diff options
| author | Ralf Jung <post@ralfj.de> | 2025-07-14 06:06:20 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-14 06:06:20 +0000 |
| commit | 794dc328b46520f145091771db6531bf1d5b5c4e (patch) | |
| tree | 57b04ecd511abfddf715b5605fc0e091a7792d16 | |
| parent | 91a52cac82ead1d8ed75fa5bd22df228a250bb17 (diff) | |
| parent | 8812d741eb54c58ee1b9bf6bd69e60f08bba941a (diff) | |
| download | rust-794dc328b46520f145091771db6531bf1d5b5c4e.tar.gz rust-794dc328b46520f145091771db6531bf1d5b5c4e.zip | |
Merge pull request #4467 from rust-lang/rustup-2025-07-14
Automatic Rustup
526 files changed, 6167 insertions, 3998 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 674b6ccf34f..e92afc14c20 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,6 +152,9 @@ jobs: - name: show the current environment run: src/ci/scripts/dump-environment.sh + - name: install rust + run: src/ci/scripts/install-rust.sh + - name: install awscli run: src/ci/scripts/install-awscli.sh diff --git a/Cargo.lock b/Cargo.lock index 549818eecb0..c767c90f1ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4358,6 +4358,7 @@ dependencies = [ "rustc_ast_lowering", "rustc_ast_pretty", "rustc_attr_data_structures", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_expand", @@ -5250,9 +5251,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.35.2" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3ffa3e4ff2b324a57f7aeb3c349656c7b127c3c189520251a648102a92496e" +checksum = "aab138f5c1bb35231de19049060a87977ad23e04f2303e953bc5c2947ac7dec4" dependencies = [ "libc", "objc2-core-foundation", diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index f4caa3ef769..99414d6264e 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -27,6 +27,7 @@ features = ['unprefixed_malloc_on_supported_platforms'] [features] # tidy-alphabetical-start +check_only = ['rustc_driver_impl/check_only'] jemalloc = ['dep:tikv-jemalloc-sys'] llvm = ['rustc_driver_impl/llvm'] max_level_info = ['rustc_driver_impl/max_level_info'] diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 42d25b512f5..9bfcd232221 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -47,6 +47,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_middle::span_bug; use rustc_middle::ty::{Asyncness, ResolverAstLowering}; +use rustc_span::symbol::kw; use rustc_span::{Ident, Span, Symbol}; use {rustc_ast as ast, rustc_hir as hir}; @@ -61,21 +62,6 @@ pub(crate) struct DelegationResults<'hir> { } impl<'hir> LoweringContext<'_, 'hir> { - /// Defines whether the delegatee is an associated function whose first parameter is `self`. - pub(crate) fn delegatee_is_method( - &self, - item_id: NodeId, - path_id: NodeId, - span: Span, - is_in_trait_impl: bool, - ) -> bool { - let sig_id = self.get_delegation_sig_id(item_id, path_id, span, is_in_trait_impl); - let Ok(sig_id) = sig_id else { - return false; - }; - self.is_method(sig_id, span) - } - fn is_method(&self, def_id: DefId, span: Span) -> bool { match self.tcx.def_kind(def_id) { DefKind::Fn => false, @@ -101,10 +87,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl); match sig_id { Ok(sig_id) => { + let is_method = self.is_method(sig_id, span); let (param_count, c_variadic) = self.param_count(sig_id); let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span); let sig = self.lower_delegation_sig(sig_id, decl, span); - let body_id = self.lower_delegation_body(delegation, param_count, span); + let body_id = self.lower_delegation_body(delegation, is_method, param_count, span); let ident = self.lower_ident(delegation.ident); let generics = self.lower_delegation_generics(span); DelegationResults { body_id, sig, ident, generics } @@ -234,10 +221,21 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::FnSig { decl, header, span } } - fn generate_param(&mut self, idx: usize, span: Span) -> (hir::Param<'hir>, NodeId) { + fn generate_param( + &mut self, + is_method: bool, + idx: usize, + span: Span, + ) -> (hir::Param<'hir>, NodeId) { let pat_node_id = self.next_node_id(); let pat_id = self.lower_node_id(pat_node_id); - let ident = Ident::with_dummy_span(Symbol::intern(&format!("arg{idx}"))); + // FIXME(cjgillot) AssocItem currently relies on self parameter being exactly named `self`. + let name = if is_method && idx == 0 { + kw::SelfLower + } else { + Symbol::intern(&format!("arg{idx}")) + }; + let ident = Ident::with_dummy_span(name); let pat = self.arena.alloc(hir::Pat { hir_id: pat_id, kind: hir::PatKind::Binding(hir::BindingMode::NONE, pat_id, ident, None), @@ -248,9 +246,21 @@ impl<'hir> LoweringContext<'_, 'hir> { (hir::Param { hir_id: self.next_id(), pat, ty_span: span, span }, pat_node_id) } - fn generate_arg(&mut self, idx: usize, param_id: HirId, span: Span) -> hir::Expr<'hir> { + fn generate_arg( + &mut self, + is_method: bool, + idx: usize, + param_id: HirId, + span: Span, + ) -> hir::Expr<'hir> { + // FIXME(cjgillot) AssocItem currently relies on self parameter being exactly named `self`. + let name = if is_method && idx == 0 { + kw::SelfLower + } else { + Symbol::intern(&format!("arg{idx}")) + }; let segments = self.arena.alloc_from_iter(iter::once(hir::PathSegment { - ident: Ident::with_dummy_span(Symbol::intern(&format!("arg{idx}"))), + ident: Ident::with_dummy_span(name), hir_id: self.next_id(), res: Res::Local(param_id), args: None, @@ -264,6 +274,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_delegation_body( &mut self, delegation: &Delegation, + is_method: bool, param_count: usize, span: Span, ) -> BodyId { @@ -274,7 +285,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut args: Vec<hir::Expr<'_>> = Vec::with_capacity(param_count); for idx in 0..param_count { - let (param, pat_node_id) = this.generate_param(idx, span); + let (param, pat_node_id) = this.generate_param(is_method, idx, span); parameters.push(param); let arg = if let Some(block) = block @@ -290,7 +301,7 @@ impl<'hir> LoweringContext<'_, 'hir> { this.ident_and_label_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id); this.lower_target_expr(&block) } else { - this.generate_arg(idx, param.pat.hir_id, span) + this.generate_arg(is_method, idx, param.pat.hir_id, span) }; args.push(arg); } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 8747e624a4a..15e736261d5 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -528,7 +528,7 @@ impl<'hir> LoweringContext<'_, 'hir> { then: &Block, else_opt: Option<&Expr>, ) -> hir::ExprKind<'hir> { - let lowered_cond = self.lower_cond(cond); + let lowered_cond = self.lower_expr(cond); let then_expr = self.lower_block_expr(then); if let Some(rslt) = else_opt { hir::ExprKind::If( @@ -541,44 +541,6 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - // Lowers a condition (i.e. `cond` in `if cond` or `while cond`), wrapping it in a terminating scope - // so that temporaries created in the condition don't live beyond it. - fn lower_cond(&mut self, cond: &Expr) -> &'hir hir::Expr<'hir> { - fn has_let_expr(expr: &Expr) -> bool { - match &expr.kind { - ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs), - ExprKind::Let(..) => true, - _ => false, - } - } - - // We have to take special care for `let` exprs in the condition, e.g. in - // `if let pat = val` or `if foo && let pat = val`, as we _do_ want `val` to live beyond the - // condition in this case. - // - // In order to maintain the drop behavior for the non `let` parts of the condition, - // we still wrap them in terminating scopes, e.g. `if foo && let pat = val` essentially - // gets transformed into `if { let _t = foo; _t } && let pat = val` - match &cond.kind { - ExprKind::Binary(op @ Spanned { node: ast::BinOpKind::And, .. }, lhs, rhs) - if has_let_expr(cond) => - { - let op = self.lower_binop(*op); - let lhs = self.lower_cond(lhs); - let rhs = self.lower_cond(rhs); - - self.arena.alloc(self.expr(cond.span, hir::ExprKind::Binary(op, lhs, rhs))) - } - ExprKind::Let(..) => self.lower_expr(cond), - _ => { - let cond = self.lower_expr(cond); - let reason = DesugaringKind::CondTemporary; - let span_block = self.mark_span_with_reason(reason, cond.span, None); - self.expr_drop_temps(span_block, cond) - } - } - } - // We desugar: `'label: while $cond $body` into: // // ``` @@ -602,7 +564,7 @@ impl<'hir> LoweringContext<'_, 'hir> { body: &Block, opt_label: Option<Label>, ) -> hir::ExprKind<'hir> { - let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond)); + let lowered_cond = self.with_loop_condition_scope(|t| t.lower_expr(cond)); let then = self.lower_block_expr(body); let expr_break = self.expr_break(span); let stmt_break = self.stmt_expr(span, expr_break); @@ -2091,7 +2053,8 @@ impl<'hir> LoweringContext<'_, 'hir> { /// In terms of drop order, it has the same effect as wrapping `expr` in /// `{ let _t = $expr; _t }` but should provide better compile-time performance. /// - /// The drop order can be important in e.g. `if expr { .. }`. + /// The drop order can be important, e.g. to drop temporaries from an `async fn` + /// body before its parameters. pub(super) fn expr_drop_temps( &mut self, span: Span, diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 956cb580d10..1ef64f5a352 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -381,28 +381,16 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { }) } - fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) { - // Do not visit the duplicate information in TraitItemRef. We want to - // map the actual nodes, not the duplicate ones in the *Ref. - let TraitItemRef { id, ident: _, kind: _, span: _ } = *ii; - - self.visit_nested_trait_item(id); + fn visit_trait_item_ref(&mut self, id: &'hir TraitItemId) { + self.visit_nested_trait_item(*id); } - fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) { - // Do not visit the duplicate information in ImplItemRef. We want to - // map the actual nodes, not the duplicate ones in the *Ref. - let ImplItemRef { id, ident: _, kind: _, span: _, trait_item_def_id: _ } = *ii; - - self.visit_nested_impl_item(id); + fn visit_impl_item_ref(&mut self, id: &'hir ImplItemId) { + self.visit_nested_impl_item(*id); } - fn visit_foreign_item_ref(&mut self, fi: &'hir ForeignItemRef) { - // Do not visit the duplicate information in ForeignItemRef. We want to - // map the actual nodes, not the duplicate ones in the *Ref. - let ForeignItemRef { id, ident: _, span: _ } = *fi; - - self.visit_nested_foreign_item(id); + fn visit_foreign_item_ref(&mut self, id: &'hir ForeignItemId) { + self.visit_nested_foreign_item(*id); } fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index bdcb750ba26..9d40a7386f6 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -393,11 +393,9 @@ impl<'hir> LoweringContext<'_, 'hir> { (trait_ref, lowered_ty) }); - let new_impl_items = self.arena.alloc_from_iter( - impl_items - .iter() - .map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())), - ); + let new_impl_items = self + .arena + .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item))); // `defaultness.has_value()` is never called for an `impl`, always `true` in order // to not cause an assertion failure inside the `lower_defaultness` function. @@ -706,14 +704,8 @@ impl<'hir> LoweringContext<'_, 'hir> { self.arena.alloc(item) } - fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef { - hir::ForeignItemRef { - id: hir::ForeignItemId { owner_id: self.owner_id(i.id) }, - // `unwrap` is safe because `ForeignItemKind::MacCall` is the only foreign item kind - // without an identifier and it cannot reach here. - ident: self.lower_ident(i.kind.ident().unwrap()), - span: self.lower_span(i.span), - } + fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemId { + hir::ForeignItemId { owner_id: self.owner_id(i.id) } } fn lower_variant(&mut self, item_kind: &ItemKind, v: &Variant) -> hir::Variant<'hir> { @@ -972,32 +964,8 @@ impl<'hir> LoweringContext<'_, 'hir> { self.arena.alloc(item) } - fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef { - let (ident, kind) = match &i.kind { - AssocItemKind::Const(box ConstItem { ident, .. }) => { - (*ident, hir::AssocItemKind::Const) - } - AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, hir::AssocItemKind::Type), - AssocItemKind::Fn(box Fn { ident, sig, .. }) => { - (*ident, hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }) - } - AssocItemKind::Delegation(box delegation) => ( - delegation.ident, - hir::AssocItemKind::Fn { - has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false), - }, - ), - AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { - panic!("macros should have been expanded by now") - } - }; - let id = hir::TraitItemId { owner_id: self.owner_id(i.id) }; - hir::TraitItemRef { - id, - ident: self.lower_ident(ident), - span: self.lower_span(i.span), - kind, - } + fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemId { + hir::TraitItemId { owner_id: self.owner_id(i.id) } } /// Construct `ExprKind::Err` for the given `span`. @@ -1128,41 +1096,17 @@ impl<'hir> LoweringContext<'_, 'hir> { span: self.lower_span(i.span), defaultness, has_delayed_lints: !self.delayed_lints.is_empty(), - }; - self.arena.alloc(item) - } - - fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef { - hir::ImplItemRef { - id: hir::ImplItemId { owner_id: self.owner_id(i.id) }, - // `unwrap` is safe because `AssocItemKind::{MacCall,DelegationMac}` are the only - // assoc item kinds without an identifier and they cannot reach here. - ident: self.lower_ident(i.kind.ident().unwrap()), - span: self.lower_span(i.span), - kind: match &i.kind { - AssocItemKind::Const(..) => hir::AssocItemKind::Const, - AssocItemKind::Type(..) => hir::AssocItemKind::Type, - AssocItemKind::Fn(box Fn { sig, .. }) => { - hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } - } - AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn { - has_self: self.delegatee_is_method( - i.id, - delegation.id, - i.span, - is_in_trait_impl, - ), - }, - AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { - panic!("macros should have been expanded by now") - } - }, trait_item_def_id: self .resolver .get_partial_res(i.id) .map(|r| r.expect_full_res().opt_def_id()) .unwrap_or(None), - } + }; + self.arena.alloc(item) + } + + fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemId { + hir::ImplItemId { owner_id: self.owner_id(i.id) } } fn lower_defaultness( diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index aff98c63bcb..def0cb74d29 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -120,7 +120,7 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comment> pos += shebang_len; } - for token in rustc_lexer::tokenize(&text[pos..]) { + for token in rustc_lexer::tokenize(&text[pos..], rustc_lexer::FrontmatterAllowed::Yes) { let token_text = &text[pos..pos + token.len as usize]; match token.kind { rustc_lexer::TokenKind::Whitespace => { @@ -171,6 +171,14 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comment> }) } } + rustc_lexer::TokenKind::Frontmatter { .. } => { + code_to_the_left = false; + comments.push(Comment { + style: CommentStyle::Isolated, + lines: vec![token_text.to_string()], + pos: start_bpos + BytePos(pos as u32), + }); + } _ => { code_to_the_left = true; } diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index b656db32528..f61efcf2388 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -198,6 +198,9 @@ pub enum AttributeKind { /// Represents `#[rustc_allow_const_fn_unstable]`. AllowConstFnUnstable(ThinVec<Symbol>, Span), + /// Represents `#[rustc_allow_incoherent_impl]`. + AllowIncoherentImpl(Span), + /// Represents `#[allow_internal_unstable]`. AllowInternalUnstable(ThinVec<(Symbol, Span)>, Span), @@ -211,6 +214,12 @@ pub enum AttributeKind { span: Span, }, + /// Represents `#[rustc_coherence_is_core]`. + CoherenceIsCore, + + /// Represents `#[rustc_coinductive]`. + Coinductive(Span), + /// Represents `#[cold]`. Cold(Span), @@ -234,9 +243,18 @@ pub enum AttributeKind { /// Represents `#[rustc_const_stable_indirect]`. ConstStabilityIndirect, + /// Represents `#[const_trait]`. + ConstTrait(Span), + + ///Represents `#[rustc_deny_explicit_impl]`. + DenyExplicitImpl(Span), + /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute). Deprecation { deprecation: Deprecation, span: Span }, + /// Represents `#[rustc_do_not_implement_via_object]`. + DoNotImplementViaObject(Span), + /// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol }, @@ -260,6 +278,9 @@ pub enum AttributeKind { /// Represents `#[ffi_pure]`. FfiPure(Span), + /// Represents `#[fundamental]`. + Fundamental, + /// Represents `#[ignore]` Ignore { span: Span, @@ -282,6 +303,9 @@ pub enum AttributeKind { /// Represents `#[rustc_macro_transparency]`. MacroTransparency(Transparency), + /// Represents `#[marker]`. + Marker(Span), + /// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html). MayDangle(Span), @@ -307,6 +331,9 @@ pub enum AttributeKind { /// Represents `#[optimize(size|speed)]` Optimize(OptimizeAttr, Span), + /// Represents `#[rustc_paren_sugar]`. + ParenSugar(Span), + /// Represents `#[rustc_pass_by_value]` (used by the `rustc_pass_by_value` lint). PassByValue(Span), @@ -331,6 +358,9 @@ pub enum AttributeKind { /// Represents `#[rustc_skip_during_method_dispatch]`. SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span }, + /// Represents `#[rustc_specialization_trait]`. + SpecializationTrait(Span), + /// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`. Stability { stability: Stability, @@ -347,6 +377,12 @@ pub enum AttributeKind { /// Represents `#[track_caller]` TrackCaller(Span), + /// Represents `#[type_const]`. + TypeConst(Span), + + /// Represents `#[rustc_unsafe_specialization_marker]`. + UnsafeSpecializationMarker(Span), + /// Represents `#[used]` Used { used_by: UsedBy, span: Span }, // tidy-alphabetical-end diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 5414c7b103b..ad587523e03 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -15,27 +15,35 @@ impl AttributeKind { // tidy-alphabetical-start Align { .. } => No, AllowConstFnUnstable(..) => No, + AllowIncoherentImpl(..) => No, AllowInternalUnstable(..) => Yes, AsPtr(..) => Yes, BodyStability { .. } => No, + CoherenceIsCore => No, + Coinductive(..) => No, Cold(..) => No, Confusables { .. } => Yes, ConstContinue(..) => No, ConstStability { .. } => Yes, ConstStabilityIndirect => No, + ConstTrait(..) => No, + DenyExplicitImpl(..) => No, Deprecation { .. } => Yes, + DoNotImplementViaObject(..) => No, DocComment { .. } => Yes, Dummy => No, ExportName { .. } => Yes, ExportStable => No, FfiConst(..) => No, FfiPure(..) => No, + Fundamental { .. } => Yes, Ignore { .. } => No, Inline(..) => No, LinkName { .. } => Yes, LinkSection { .. } => No, LoopMatch(..) => No, MacroTransparency(..) => Yes, + Marker(..) => No, MayDangle(..) => No, MustUse { .. } => Yes, Naked(..) => No, @@ -43,6 +51,7 @@ impl AttributeKind { NoMangle(..) => No, NonExhaustive(..) => Yes, Optimize(..) => No, + ParenSugar(..) => No, PassByValue(..) => Yes, Path(..) => No, PubTransparent(..) => Yes, @@ -51,10 +60,13 @@ impl AttributeKind { RustcLayoutScalarValidRangeStart(..) => Yes, RustcObjectLifetimeDefault => No, SkipDuringMethodDispatch { .. } => No, + SpecializationTrait(..) => No, Stability { .. } => Yes, StdInternalSymbol(..) => No, TargetFeature(..) => No, TrackCaller(..) => Yes, + TypeConst(..) => Yes, + UnsafeSpecializationMarker(..) => No, Used { .. } => No, // tidy-alphabetical-end } diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index c29dbf4d1e9..ee8a33ae9c4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -2,14 +2,15 @@ use core::mem; use rustc_attr_data_structures::AttributeKind; use rustc_feature::{AttributeTemplate, template}; -use rustc_span::{Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; -use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::attributes::{ + AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser, +}; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; pub(crate) struct SkipDuringMethodDispatchParser; - impl<S: Stage> SingleAttributeParser<S> for SkipDuringMethodDispatchParser { const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; @@ -52,3 +53,95 @@ impl<S: Stage> SingleAttributeParser<S> for SkipDuringMethodDispatchParser { Some(AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: cx.attr_span }) } } + +pub(crate) struct ParenSugarParser; +impl<S: Stage> NoArgsAttributeParser<S> for ParenSugarParser { + const PATH: &[Symbol] = &[sym::rustc_paren_sugar]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::ParenSugar; +} + +pub(crate) struct TypeConstParser; +impl<S: Stage> NoArgsAttributeParser<S> for TypeConstParser { + const PATH: &[Symbol] = &[sym::type_const]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst; +} + +// Markers + +pub(crate) struct MarkerParser; +impl<S: Stage> NoArgsAttributeParser<S> for MarkerParser { + const PATH: &[Symbol] = &[sym::marker]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::Marker; +} + +pub(crate) struct DenyExplicitImplParser; +impl<S: Stage> NoArgsAttributeParser<S> for DenyExplicitImplParser { + const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::DenyExplicitImpl; +} + +pub(crate) struct DoNotImplementViaObjectParser; +impl<S: Stage> NoArgsAttributeParser<S> for DoNotImplementViaObjectParser { + const PATH: &[Symbol] = &[sym::rustc_do_not_implement_via_object]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::DoNotImplementViaObject; +} + +// Const traits + +pub(crate) struct ConstTraitParser; +impl<S: Stage> NoArgsAttributeParser<S> for ConstTraitParser { + const PATH: &[Symbol] = &[sym::const_trait]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstTrait; +} + +// Specialization + +pub(crate) struct SpecializationTraitParser; +impl<S: Stage> NoArgsAttributeParser<S> for SpecializationTraitParser { + const PATH: &[Symbol] = &[sym::rustc_specialization_trait]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::SpecializationTrait; +} + +pub(crate) struct UnsafeSpecializationMarkerParser; +impl<S: Stage> NoArgsAttributeParser<S> for UnsafeSpecializationMarkerParser { + const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::UnsafeSpecializationMarker; +} + +// Coherence + +pub(crate) struct CoinductiveParser; +impl<S: Stage> NoArgsAttributeParser<S> for CoinductiveParser { + const PATH: &[Symbol] = &[sym::rustc_coinductive]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::Coinductive; +} + +pub(crate) struct AllowIncoherentImplParser; +impl<S: Stage> NoArgsAttributeParser<S> for AllowIncoherentImplParser { + const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::AllowIncoherentImpl; +} + +pub(crate) struct CoherenceIsCoreParser; +impl<S: Stage> NoArgsAttributeParser<S> for CoherenceIsCoreParser { + const PATH: &[Symbol] = &[sym::rustc_coherence_is_core]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CoherenceIsCore; +} + +pub(crate) struct FundamentalParser; +impl<S: Stage> NoArgsAttributeParser<S> for FundamentalParser { + const PATH: &[Symbol] = &[sym::fundamental]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index dbe1a5b2ad0..ad48eb1498e 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -43,7 +43,12 @@ use crate::attributes::stability::{ BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser, }; use crate::attributes::test_attrs::IgnoreParser; -use crate::attributes::traits::SkipDuringMethodDispatchParser; +use crate::attributes::traits::{ + AllowIncoherentImplParser, CoherenceIsCoreParser, CoinductiveParser, ConstTraitParser, + DenyExplicitImplParser, DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, + ParenSugarParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, + UnsafeSpecializationMarkerParser, +}; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; use crate::parser::{ArgParser, MetaItemParser, PathParser}; @@ -146,22 +151,34 @@ attribute_parsers!( Single<RustcObjectLifetimeDefaultParser>, Single<SkipDuringMethodDispatchParser>, Single<TransparencyParser>, + Single<WithoutArgs<AllowIncoherentImplParser>>, Single<WithoutArgs<AsPtrParser>>, + Single<WithoutArgs<CoherenceIsCoreParser>>, + Single<WithoutArgs<CoinductiveParser>>, Single<WithoutArgs<ColdParser>>, Single<WithoutArgs<ConstContinueParser>>, Single<WithoutArgs<ConstStabilityIndirectParser>>, + Single<WithoutArgs<ConstTraitParser>>, + Single<WithoutArgs<DenyExplicitImplParser>>, + Single<WithoutArgs<DoNotImplementViaObjectParser>>, Single<WithoutArgs<ExportStableParser>>, Single<WithoutArgs<FfiConstParser>>, Single<WithoutArgs<FfiPureParser>>, + Single<WithoutArgs<FundamentalParser>>, Single<WithoutArgs<LoopMatchParser>>, + Single<WithoutArgs<MarkerParser>>, Single<WithoutArgs<MayDangleParser>>, Single<WithoutArgs<NoImplicitPreludeParser>>, Single<WithoutArgs<NoMangleParser>>, Single<WithoutArgs<NonExhaustiveParser>>, + Single<WithoutArgs<ParenSugarParser>>, Single<WithoutArgs<PassByValueParser>>, Single<WithoutArgs<PubTransparentParser>>, + Single<WithoutArgs<SpecializationTraitParser>>, Single<WithoutArgs<StdInternalSymbolParser>>, Single<WithoutArgs<TrackCallerParser>>, + Single<WithoutArgs<TypeConstParser>>, + Single<WithoutArgs<UnsafeSpecializationMarkerParser>>, // tidy-alphabetical-end ]; ); @@ -718,6 +735,11 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attributes } + /// Returns whether there is a parser for an attribute with this name + pub fn is_parsed_attribute(path: &[Symbol]) -> bool { + Late::parsers().0.contains_key(path) + } + fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs { match args { ast::AttrArgs::Empty => AttrArgs::Empty, diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 7c69baba62e..a06540f8325 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -681,46 +681,30 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return (false, false, None); } let my_def = self.body.source.def_id(); - let my_hir = self.infcx.tcx.local_def_id_to_hir_id(my_def.as_local().unwrap()); let Some(td) = self.infcx.tcx.impl_of_method(my_def).and_then(|x| self.infcx.tcx.trait_id_of_impl(x)) else { return (false, false, None); }; + + let implemented_trait_item = self.infcx.tcx.associated_item(my_def).trait_item_def_id; + ( true, td.is_local(), - td.as_local().and_then(|tld| match self.infcx.tcx.hir_node_by_def_id(tld) { - Node::Item(hir::Item { - kind: hir::ItemKind::Trait(_, _, _, _, _, items), .. - }) => { - let mut f_in_trait_opt = None; - for hir::TraitItemRef { id: fi, kind: k, .. } in *items { - let hi = fi.hir_id(); - if !matches!(k, hir::AssocItemKind::Fn { .. }) { - continue; - } - if self.infcx.tcx.hir_name(hi) != self.infcx.tcx.hir_name(my_hir) { - continue; - } - f_in_trait_opt = Some(hi); - break; - } - f_in_trait_opt.and_then(|f_in_trait| { - if let Node::TraitItem(ti) = self.infcx.tcx.hir_node(f_in_trait) - && let hir::TraitItemKind::Fn(sig, _) = ti.kind - && let Some(ty) = sig.decl.inputs.get(local.index() - 1) - && let hir::TyKind::Ref(_, mut_ty) = ty.kind - && let hir::Mutability::Not = mut_ty.mutbl - && sig.decl.implicit_self.has_implicit_self() - { - Some(ty.span) - } else { - None - } - }) + implemented_trait_item.and_then(|f_in_trait| { + let f_in_trait = f_in_trait.as_local()?; + if let Node::TraitItem(ti) = self.infcx.tcx.hir_node_by_def_id(f_in_trait) + && let hir::TraitItemKind::Fn(sig, _) = ti.kind + && let Some(ty) = sig.decl.inputs.get(local.index() - 1) + && let hir::TyKind::Ref(_, mut_ty) = ty.kind + && let hir::Mutability::Not = mut_ty.mutbl + && sig.decl.implicit_self.has_implicit_self() + { + Some(ty.span) + } else { + None } - _ => None, }), ) } diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 3594c7ec210..183927edb02 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -81,6 +81,12 @@ builtin_macros_cfg_accessible_literal_path = `cfg_accessible` path cannot be a l builtin_macros_cfg_accessible_multiple_paths = multiple `cfg_accessible` paths are specified builtin_macros_cfg_accessible_unspecified_path = `cfg_accessible` path is not specified +builtin_macros_cfg_select_no_matches = none of the rules in this `cfg_select` evaluated to true + +builtin_macros_cfg_select_unreachable = unreachable rule + .label = always matches + .label2 = this rules is never reached + builtin_macros_coerce_pointee_requires_maybe_sized = `derive(CoercePointee)` requires `{$name}` to be marked `?Sized` builtin_macros_coerce_pointee_requires_one_field = `CoercePointee` can only be derived on `struct`s with at least one field diff --git a/compiler/rustc_builtin_macros/src/cfg_select.rs b/compiler/rustc_builtin_macros/src/cfg_select.rs new file mode 100644 index 00000000000..2dc387d5866 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/cfg_select.rs @@ -0,0 +1,63 @@ +use rustc_ast::tokenstream::TokenStream; +use rustc_attr_parsing as attr; +use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; +use rustc_parse::parser::cfg_select::{CfgSelectBranches, CfgSelectRule, parse_cfg_select}; +use rustc_span::{Ident, Span, sym}; + +use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable}; + +/// Selects the first arm whose rule evaluates to true. +fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> { + for (cfg, tt, arm_span) in branches.reachable { + if attr::cfg_matches( + &cfg, + &ecx.sess, + ecx.current_expansion.lint_node_id, + Some(ecx.ecfg.features), + ) { + return Some((tt, arm_span)); + } + } + + branches.wildcard.map(|(_, tt, span)| (tt, span)) +} + +pub(super) fn expand_cfg_select<'cx>( + ecx: &'cx mut ExtCtxt<'_>, + sp: Span, + tts: TokenStream, +) -> MacroExpanderResult<'cx> { + ExpandResult::Ready(match parse_cfg_select(&mut ecx.new_parser_from_tts(tts)) { + Ok(branches) => { + if let Some((underscore, _, _)) = branches.wildcard { + // Warn for every unreachable rule. We store the fully parsed branch for rustfmt. + for (rule, _, _) in &branches.unreachable { + let span = match rule { + CfgSelectRule::Wildcard(underscore) => underscore.span, + CfgSelectRule::Cfg(cfg) => cfg.span(), + }; + let err = CfgSelectUnreachable { span, wildcard_span: underscore.span }; + ecx.dcx().emit_warn(err); + } + } + + if let Some((tts, arm_span)) = select_arm(ecx, branches) { + return ExpandResult::from_tts( + ecx, + tts, + sp, + arm_span, + Ident::with_dummy_span(sym::cfg_select), + ); + } else { + // Emit a compiler error when none of the rules matched. + let guar = ecx.dcx().emit_err(CfgSelectNoMatches { span: sp }); + DummyResult::any(sp, guar) + } + } + Err(err) => { + let guar = err.emit(); + DummyResult::any(sp, guar) + } + }) +} diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index a5ee7349fc6..6bcf4d3e0a2 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -954,3 +954,21 @@ pub(crate) struct AsmExpectedOther { pub(crate) span: Span, pub(crate) is_inline_asm: bool, } + +#[derive(Diagnostic)] +#[diag(builtin_macros_cfg_select_no_matches)] +pub(crate) struct CfgSelectNoMatches { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_cfg_select_unreachable)] +pub(crate) struct CfgSelectUnreachable { + #[primary_span] + #[label(builtin_macros_label2)] + pub span: Span, + + #[label] + pub wildcard_span: Span, +} diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 6bf590df5c9..7bc448a9acb 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -33,6 +33,7 @@ mod autodiff; mod cfg; mod cfg_accessible; mod cfg_eval; +mod cfg_select; mod compile_error; mod concat; mod concat_bytes; @@ -79,6 +80,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { asm: asm::expand_asm, assert: assert::expand_assert, cfg: cfg::expand_cfg, + cfg_select: cfg_select::expand_cfg_select, column: source_util::expand_column, compile_error: compile_error::expand_compile_error, concat: concat::expand_concat, diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index b1785af444a..28d1ec7d895 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -926,10 +926,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { .get_address(self.location) } - fn dynamic_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { - unimplemented!(); - } - fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> { let block = self.llbb(); let function = block.get_function(); diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 88efc8ac96b..5ab22f8fc4d 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -43,3 +43,6 @@ serde_json = "1" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end + +[features] +check_only = ["rustc_llvm/check_only"] diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 9ddadcf16aa..a643a91141e 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -384,15 +384,19 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { ) { let asm_arch = self.tcx.sess.asm_arch.unwrap(); - // Default to Intel syntax on x86 - let intel_syntax = matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64) - && !options.contains(InlineAsmOptions::ATT_SYNTAX); - // Build the template string let mut template_str = String::new(); - if intel_syntax { - template_str.push_str(".intel_syntax\n"); + + // On X86 platforms there are two assembly syntaxes. Rust uses intel by default, + // but AT&T can be specified explicitly. + if matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64) { + if options.contains(InlineAsmOptions::ATT_SYNTAX) { + template_str.push_str(".att_syntax\n") + } else { + template_str.push_str(".intel_syntax\n") + } } + for piece in template { match *piece { InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s), @@ -431,7 +435,11 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { } } } - if intel_syntax { + + // Just to play it safe, if intel was used, reset the assembly syntax to att. + if matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64) + && !options.contains(InlineAsmOptions::ATT_SYNTAX) + { template_str.push_str("\n.att_syntax\n"); } diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 9c62244f3c9..74418adc43c 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -680,7 +680,7 @@ pub(crate) fn run_pass_manager( if attributes::has_string_attr(function, enzyme_marker) { // Sanity check: Ensure 'noinline' is present before replacing it. assert!( - !attributes::has_attr(function, Function, llvm::AttributeKind::NoInline), + attributes::has_attr(function, Function, llvm::AttributeKind::NoInline), "Expected __enzyme function to have 'noinline' before adding 'alwaysinline'" ); diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index bde6a9cf4bc..506286fc255 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -1182,7 +1182,7 @@ fn create_msvc_imps( .filter_map(|val| { // Exclude some symbols that we know are not Rust symbols. let name = llvm::get_value_name(val); - if ignored(name) { None } else { Some((val, name)) } + if ignored(&name) { None } else { Some((val, name)) } }) .map(move |(val, name)| { let mut imp_name = prefix.as_bytes().to_vec(); diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index d0aa7320b4b..9c3b866aa3c 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -538,16 +538,6 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn dynamic_alloca(&mut self, size: &'ll Value, align: Align) -> &'ll Value { - unsafe { - let alloca = - llvm::LLVMBuildArrayAlloca(self.llbuilder, self.cx().type_i8(), size, UNNAMED); - llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); - // Cast to default addrspace if necessary - llvm::LLVMBuildPointerCast(self.llbuilder, alloca, self.cx().type_ptr(), UNNAMED) - } - } - fn load(&mut self, ty: &'ll Type, ptr: &'ll Value, align: Align) -> &'ll Value { unsafe { let load = llvm::LLVMBuildLoad2(self.llbuilder, ty, ptr, UNNAMED); diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index b07d9a5cfca..5afb9a60d42 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -306,7 +306,7 @@ fn generate_enzyme_call<'ll>( // add outer_fn name to ad_name to make it unique, in case users apply autodiff to multiple // functions. Unwrap will only panic, if LLVM gave us an invalid string. let name = llvm::get_value_name(outer_fn); - let outer_fn_name = std::str::from_utf8(name).unwrap(); + let outer_fn_name = std::str::from_utf8(&name).unwrap(); ad_name.push_str(outer_fn_name); // Let us assume the user wrote the following function square: diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 21524fd2eb8..5deddb3ed98 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -429,7 +429,7 @@ impl<'ll> CodegenCx<'ll, '_> { // specific rules on what can be cast. So instead of adding a new way to // generate static initializers that match the static's type, we picked // the easier option and retroactively change the type of the static item itself. - let name = llvm::get_value_name(g).to_vec(); + let name = llvm::get_value_name(g); llvm::set_value_name(g, b""); let linkage = llvm::get_linkage(g); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 91ada856d59..5c34ab2e304 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1492,12 +1492,6 @@ unsafe extern "C" { Ty: &'a Type, Name: *const c_char, ) -> &'a Value; - pub(crate) fn LLVMBuildArrayAlloca<'a>( - B: &Builder<'a>, - Ty: &'a Type, - Val: &'a Value, - Name: *const c_char, - ) -> &'a Value; pub(crate) fn LLVMBuildLoad2<'a>( B: &Builder<'a>, Ty: &'a Type, @@ -1980,12 +1974,12 @@ unsafe extern "C" { pub(crate) fn LLVMRustBuildMinNum<'a>( B: &Builder<'a>, LHS: &'a Value, - LHS: &'a Value, + RHS: &'a Value, ) -> &'a Value; pub(crate) fn LLVMRustBuildMaxNum<'a>( B: &Builder<'a>, LHS: &'a Value, - LHS: &'a Value, + RHS: &'a Value, ) -> &'a Value; // Atomic Operations diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 661174a80df..3fc83fca352 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -211,7 +211,7 @@ pub(crate) fn SetFunctionCallConv(fn_: &Value, cc: CallConv) { // function. // For more details on COMDAT sections see e.g., https://www.airs.com/blog/archives/52 pub(crate) fn SetUniqueComdat(llmod: &Module, val: &Value) { - let name_buf = get_value_name(val).to_vec(); + let name_buf = get_value_name(val); let name = CString::from_vec_with_nul(name_buf).or_else(|buf| CString::new(buf.into_bytes())).unwrap(); set_comdat(llmod, val, &name); @@ -319,12 +319,14 @@ pub(crate) fn get_param(llfn: &Value, index: c_uint) -> &Value { } } -/// Safe wrapper for `LLVMGetValueName2` into a byte slice -pub(crate) fn get_value_name(value: &Value) -> &[u8] { +/// Safe wrapper for `LLVMGetValueName2` +/// Needs to allocate the value, because `set_value_name` will invalidate +/// the pointer. +pub(crate) fn get_value_name(value: &Value) -> Vec<u8> { unsafe { let mut len = 0; let data = LLVMGetValueName2(value, &mut len); - std::slice::from_raw_parts(data.cast(), len) + std::slice::from_raw_parts(data.cast(), len).to_vec() } } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 1896f63bd2d..e0a3ad55be0 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -800,9 +800,7 @@ impl<'a> Linker for GccLinker<'a> { return; } - let is_windows = self.sess.target.is_like_windows; - let path = tmpdir.join(if is_windows { "list.def" } else { "list" }); - + let path = tmpdir.join(if self.sess.target.is_like_windows { "list.def" } else { "list" }); debug!("EXPORTED SYMBOLS:"); if self.sess.target.is_like_darwin { @@ -817,7 +815,8 @@ impl<'a> Linker for GccLinker<'a> { if let Err(error) = res { self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error }); } - } else if is_windows { + self.link_arg("-exported_symbols_list").link_arg(path); + } else if self.sess.target.is_like_windows { let res: io::Result<()> = try { let mut f = File::create_buffered(&path)?; @@ -835,6 +834,21 @@ impl<'a> Linker for GccLinker<'a> { if let Err(error) = res { self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error }); } + self.link_arg(path); + } else if crate_type == CrateType::Executable && !self.sess.target.is_like_solaris { + let res: io::Result<()> = try { + let mut f = File::create_buffered(&path)?; + writeln!(f, "{{")?; + for (sym, _) in symbols { + debug!(sym); + writeln!(f, " {sym};")?; + } + writeln!(f, "}};")?; + }; + if let Err(error) = res { + self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error }); + } + self.link_arg("--dynamic-list").link_arg(path); } else { // Write an LD version script let res: io::Result<()> = try { @@ -852,18 +866,13 @@ impl<'a> Linker for GccLinker<'a> { if let Err(error) = res { self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error }); } - } - - if self.sess.target.is_like_darwin { - self.link_arg("-exported_symbols_list").link_arg(path); - } else if self.sess.target.is_like_solaris { - self.link_arg("-M").link_arg(path); - } else if is_windows { - self.link_arg(path); - } else { - let mut arg = OsString::from("--version-script="); - arg.push(path); - self.link_arg(arg).link_arg("--no-undefined-version"); + if self.sess.target.is_like_solaris { + self.link_arg("-M").link_arg(path); + } else { + let mut arg = OsString::from("--version-script="); + arg.push(path); + self.link_arg(arg).link_arg("--no-undefined-version"); + } } } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 10b44a1faf0..fa69820d5d2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -140,8 +140,13 @@ enum LocalRef<'tcx, V> { Place(PlaceRef<'tcx, V>), /// `UnsizedPlace(p)`: `p` itself is a thin pointer (indirect place). /// `*p` is the wide pointer that references the actual unsized place. - /// Every time it is initialized, we have to reallocate the place - /// and update the wide pointer. That's the reason why it is indirect. + /// + /// MIR only supports unsized args, not dynamically-sized locals, so + /// new unsized temps don't exist and we must reuse the referred-to place. + /// + /// FIXME: Since the removal of unsized locals in <https://github.com/rust-lang/rust/pull/142911>, + /// can we maybe use `Place` here? Or refactor it in another way? There are quite a few + /// `UnsizedPlace => bug` branches now. UnsizedPlace(PlaceRef<'tcx, V>), /// The backend [`OperandValue`] has already been generated. Operand(OperandRef<'tcx, V>), @@ -498,7 +503,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( LocalRef::Place(PlaceRef::new_sized(llarg, arg.layout)) } } - // Unsized indirect qrguments + // Unsized indirect arguments PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { // As the storage for the indirect argument lives during // the whole function call, we just copy the wide pointer. diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index bc83e41b278..b0d191528a8 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -16,9 +16,9 @@ use tracing::{debug, instrument}; use super::place::{PlaceRef, PlaceValue}; use super::rvalue::transmute_scalar; use super::{FunctionCx, LocalRef}; +use crate::MemFlags; use crate::common::IntPredicate; use crate::traits::*; -use crate::{MemFlags, size_of_val}; /// The representation of a Rust value. The enum variant is in fact /// uniquely determined by the value's type, but is kept as a @@ -861,44 +861,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> { } } } - - pub fn store_unsized<Bx: BuilderMethods<'a, 'tcx, Value = V>>( - self, - bx: &mut Bx, - indirect_dest: PlaceRef<'tcx, V>, - ) { - debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest); - // `indirect_dest` must have `*mut T` type. We extract `T` out of it. - let unsized_ty = indirect_dest - .layout - .ty - .builtin_deref(true) - .unwrap_or_else(|| bug!("indirect_dest has non-pointer type: {:?}", indirect_dest)); - - let OperandValue::Ref(PlaceValue { llval: llptr, llextra: Some(llextra), .. }) = self - else { - bug!("store_unsized called with a sized value (or with an extern type)") - }; - - // Allocate an appropriate region on the stack, and copy the value into it. Since alloca - // doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the - // pointer manually. - let (size, align) = size_of_val::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); - let one = bx.const_usize(1); - let align_minus_1 = bx.sub(align, one); - let size_extra = bx.add(size, align_minus_1); - let min_align = Align::ONE; - let alloca = bx.dynamic_alloca(size_extra, min_align); - let address = bx.ptrtoint(alloca, bx.type_isize()); - let neg_address = bx.neg(address); - let offset = bx.and(neg_address, align_minus_1); - let dst = bx.inbounds_ptradd(alloca, offset); - bx.memcpy(dst, min_align, llptr, min_align, size, MemFlags::empty()); - - // Store the allocated region and the extra to the indirect place. - let indirect_operand = OperandValue::Pair(dst, llextra); - indirect_operand.store(bx, indirect_dest); - } } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index cbbb0196890..e90463aacc8 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -207,9 +207,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { { // These cases are all UB to actually hit, so don't emit code for them. // (The size mismatches are reachable via `transmute_unchecked`.) - // We can't use unreachable because that's a terminator, and we - // need something that can be in the middle of a basic block. - bx.assume(bx.cx().const_bool(false)) + bx.unreachable_nonterminator(); } else { // Since in this path we have a place anyway, we can store or copy to it, // making sure we use the destination place's alignment even if the @@ -236,14 +234,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { || operand.layout.is_uninhabited() || cast.is_uninhabited() { - if !operand.layout.is_uninhabited() { - // Since this is known statically and the input could have existed - // without already having hit UB, might as well trap for it. - bx.abort(); - } + bx.unreachable_nonterminator(); - // Because this transmute is UB, return something easy to generate, - // since it's fine that later uses of the value are probably UB. + // We still need to return a value of the appropriate type, but + // it's already UB so do the easiest thing available. return OperandValue::poison(bx, cast); } @@ -327,27 +321,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some(imm) } - pub(crate) fn codegen_rvalue_unsized( - &mut self, - bx: &mut Bx, - indirect_dest: PlaceRef<'tcx, Bx::Value>, - rvalue: &mir::Rvalue<'tcx>, - ) { - debug!( - "codegen_rvalue_unsized(indirect_dest.llval={:?}, rvalue={:?})", - indirect_dest.val.llval, rvalue - ); - - match *rvalue { - mir::Rvalue::Use(ref operand) => { - let cg_operand = self.codegen_operand(bx, operand); - cg_operand.val.store_unsized(bx, indirect_dest); - } - - _ => bug!("unsized assignment other than `Rvalue::Use`"), - } - } - pub(crate) fn codegen_rvalue_operand( &mut self, bx: &mut Bx, diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index cd55a838a75..f164e0f9123 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -15,7 +15,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match self.locals[index] { LocalRef::Place(cg_dest) => self.codegen_rvalue(bx, cg_dest, rvalue), LocalRef::UnsizedPlace(cg_indirect_dest) => { - self.codegen_rvalue_unsized(bx, cg_indirect_dest, rvalue) + let ty = cg_indirect_dest.layout.ty; + span_bug!( + statement.source_info.span, + "cannot reallocate from `UnsizedPlace({ty})` \ + into `{rvalue:?}`; dynamic alloca is not supported", + ); } LocalRef::PendingOperand => { let operand = self.codegen_rvalue_operand(bx, rvalue); diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 9d367748c2a..979456a6ba7 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -136,6 +136,16 @@ pub trait BuilderMethods<'a, 'tcx>: ) -> Self::Value; fn unreachable(&mut self); + /// Like [`Self::unreachable`], but for use in the middle of a basic block. + fn unreachable_nonterminator(&mut self) { + // This is the preferred LLVM incantation for this per + // https://llvm.org/docs/Frontend/PerformanceTips.html#other-things-to-consider + // Other backends may override if they have a better way. + let const_true = self.cx().const_bool(true); + let poison_ptr = self.const_poison(self.cx().type_ptr()); + self.store(const_true, poison_ptr, Align::ONE); + } + fn add(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fadd(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fadd_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; @@ -224,7 +234,6 @@ pub trait BuilderMethods<'a, 'tcx>: fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value; fn alloca(&mut self, size: Size, align: Align) -> Self::Value; - fn dynamic_alloca(&mut self, size: Self::Value, align: Align) -> Self::Value; fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value; fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value; @@ -555,12 +564,33 @@ pub trait BuilderMethods<'a, 'tcx>: /// Called for `StorageDead` fn lifetime_end(&mut self, ptr: Self::Value, size: Size); + /// "Finally codegen the call" + /// + /// ## Arguments + /// + /// The `fn_attrs`, `fn_abi`, and `instance` arguments are Options because they are advisory. + /// They relate to optional codegen enhancements like LLVM CFI, and do not affect ABI per se. + /// Any ABI-related transformations should be handled by different, earlier stages of codegen. + /// For instance, in the caller of `BuilderMethods::call`. + /// + /// This means that a codegen backend which disregards `fn_attrs`, `fn_abi`, and `instance` + /// should still do correct codegen, and code should not be miscompiled if they are omitted. + /// It is not a miscompilation in this sense if it fails to run under CFI, other sanitizers, or + /// in the context of other compiler-enhanced security features. + /// + /// The typical case that they are None is during the codegen of intrinsics and lang-items, + /// as those are "fake functions" with only a trivial ABI if any, et cetera. + /// + /// ## Return + /// + /// Must return the value the function will return so it can be written to the destination, + /// assuming the function does not explicitly pass the destination as a pointer in `args`. fn call( &mut self, llty: Self::Type, fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, - llfn: Self::Value, + fn_val: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, instance: Option<Instance<'tcx>>, diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index 7d0c6be4c65..c5ecf43046c 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -6,16 +6,22 @@ use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { + /// Higher-level interface to emitting calls to intrinsics + /// /// Remember to add all intrinsics here, in `compiler/rustc_hir_analysis/src/check/mod.rs`, /// and in `library/core/src/intrinsics.rs`; if you need access to any LLVM intrinsics, /// add them to `compiler/rustc_codegen_llvm/src/context.rs`. /// Returns `Err` if another instance should be called instead. This is used to invoke /// intrinsic default bodies in case an intrinsic is not implemented by the backend. + /// + /// NOTE: allowed to call [`BuilderMethods::call`] + /// + /// [`BuilderMethods::call`]: super::builder::BuilderMethods::call fn codegen_intrinsic_call( &mut self, instance: ty::Instance<'tcx>, args: &[OperandRef<'tcx, Self::Value>], - result: PlaceRef<'tcx, Self::Value>, + result_dest: PlaceRef<'tcx, Self::Value>, span: Span, ) -> Result<(), ty::Instance<'tcx>>; diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index bb301600135..6414821e21d 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -1498,7 +1498,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { dest_alloc .write_uninit(&tcx, dest_range) .map_err(|e| e.to_interp_error(dest_alloc_id))?; - // We can forget about the provenance, this is all not initialized anyway. + // `write_uninit` also resets the provenance, so we are done. return interp_ok(()); } diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 1971d06aad6..ce26aa449d9 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -72,6 +72,7 @@ ctrlc = "3.4.4" [features] # tidy-alphabetical-start +check_only = ['rustc_interface/check_only'] llvm = ['rustc_interface/llvm'] max_level_info = ['rustc_log/max_level_info'] rustc_randomized_layouts = [ diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 5746c28a2ab..a128f8d31a1 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1165,7 +1165,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self.push_suggestion(CodeSuggestion { substitutions, msg: self.subdiagnostic_message_to_diagnostic_message(msg), - style: SuggestionStyle::ShowCode, + style: SuggestionStyle::ShowAlways, applicability, }); self diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 510f37f37e2..95400ac2ca3 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2446,17 +2446,22 @@ impl HumanEmitter { | DisplaySuggestion::Underline => row_num - 1, DisplaySuggestion::None => row_num, }; - self.draw_col_separator_end(&mut buffer, row, max_line_num_len + 1); + if other_suggestions > 0 { + self.draw_col_separator_no_space(&mut buffer, row, max_line_num_len + 1); + } else { + self.draw_col_separator_end(&mut buffer, row, max_line_num_len + 1); + } row_num = row + 1; } } if other_suggestions > 0 { + self.draw_note_separator(&mut buffer, row_num, max_line_num_len + 1, false); let msg = format!( "and {} other candidate{}", other_suggestions, pluralize!(other_suggestions) ); - buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle); + buffer.append(row_num, &msg, Style::NoStyle); } emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index d6d89808839..757a7e1c8e7 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -34,6 +34,7 @@ use thin_vec::ThinVec; use crate::base::ast::MetaItemInner; use crate::errors; use crate::expand::{self, AstFragment, Invocation}; +use crate::mbe::macro_rules::ParserAnyMacro; use crate::module::DirOwnership; use crate::stats::MacroStat; @@ -262,6 +263,25 @@ impl<T, U> ExpandResult<T, U> { } } +impl<'cx> MacroExpanderResult<'cx> { + /// Creates a [`MacroExpanderResult::Ready`] from a [`TokenStream`]. + /// + /// The `TokenStream` is forwarded without any expansion. + pub fn from_tts( + cx: &'cx mut ExtCtxt<'_>, + tts: TokenStream, + site_span: Span, + arm_span: Span, + macro_ident: Ident, + ) -> Self { + // Emit the SEMICOLON_IN_EXPRESSIONS_FROM_MACROS deprecation lint. + let is_local = true; + + let parser = ParserAnyMacro::from_tts(cx, tts, site_span, arm_span, is_local, macro_ident); + ExpandResult::Ready(Box::new(parser)) + } +} + pub trait MultiItemModifier { /// `meta_item` is the attribute, and `item` is the item being modified. fn expand( diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 89547088f50..2d792355b27 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -96,6 +96,30 @@ impl<'a> ParserAnyMacro<'a> { ensure_complete_parse(parser, &path, kind.name(), site_span); fragment } + + #[instrument(skip(cx, tts))] + pub(crate) fn from_tts<'cx>( + cx: &'cx mut ExtCtxt<'a>, + tts: TokenStream, + site_span: Span, + arm_span: Span, + is_local: bool, + macro_ident: Ident, + ) -> Self { + Self { + parser: Parser::new(&cx.sess.psess, tts, None), + + // Pass along the original expansion site and the name of the macro + // so we can print a useful error message if the parse of the expanded + // macro leaves unparsed tokens. + site_span, + macro_ident, + lint_node_id: cx.current_expansion.lint_node_id, + is_trailing_mac: cx.current_expansion.is_trailing_mac, + arm_span, + is_local, + } + } } pub(super) struct MacroRule { @@ -207,9 +231,6 @@ fn expand_macro<'cx>( rules: &[MacroRule], ) -> Box<dyn MacResult + 'cx> { let psess = &cx.sess.psess; - // Macros defined in the current crate have a real node id, - // whereas macros from an external crate have a dummy id. - let is_local = node_id != DUMMY_NODE_ID; if cx.trace_macros() { let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(&arg)); @@ -220,7 +241,7 @@ fn expand_macro<'cx>( let try_success_result = try_match_macro(psess, name, &arg, rules, &mut NoopTracker); match try_success_result { - Ok((i, rule, named_matches)) => { + Ok((rule_index, rule, named_matches)) => { let mbe::TokenTree::Delimited(rhs_span, _, ref rhs) = rule.rhs else { cx.dcx().span_bug(sp, "malformed macro rhs"); }; @@ -241,27 +262,13 @@ fn expand_macro<'cx>( trace_macros_note(&mut cx.expansions, sp, msg); } - let p = Parser::new(psess, tts, None); - + let is_local = is_defined_in_current_crate(node_id); if is_local { - cx.resolver.record_macro_rule_usage(node_id, i); + cx.resolver.record_macro_rule_usage(node_id, rule_index); } - // Let the context choose how to interpret the result. - // Weird, but useful for X-macros. - Box::new(ParserAnyMacro { - parser: p, - - // Pass along the original expansion site and the name of the macro - // so we can print a useful error message if the parse of the expanded - // macro leaves unparsed tokens. - site_span: sp, - macro_ident: name, - lint_node_id: cx.current_expansion.lint_node_id, - is_trailing_mac: cx.current_expansion.is_trailing_mac, - arm_span, - is_local, - }) + // Let the context choose how to interpret the result. Weird, but useful for X-macros. + Box::new(ParserAnyMacro::from_tts(cx, tts, sp, arm_span, is_local, name)) } Err(CanRetry::No(guar)) => { debug!("Will not retry matching as an error was emitted already"); @@ -373,9 +380,9 @@ pub fn compile_declarative_macro( node_id: NodeId, edition: Edition, ) -> (SyntaxExtension, usize) { - let is_local = node_id != DUMMY_NODE_ID; let mk_syn_ext = |expander| { let kind = SyntaxExtensionKind::LegacyBang(expander); + let is_local = is_defined_in_current_crate(node_id); SyntaxExtension::new(sess, kind, span, Vec::new(), edition, ident.name, attrs, is_local) }; let dummy_syn_ext = |guar| (mk_syn_ext(Arc::new(DummyExpander(guar))), 0); @@ -439,7 +446,7 @@ pub fn compile_declarative_macro( } // Return the number of rules for unused rule linting, if this is a local macro. - let nrules = if is_local { rules.len() } else { 0 }; + let nrules = if is_defined_in_current_crate(node_id) { rules.len() } else { 0 }; let expander = Arc::new(MacroRulesMacroExpander { name: ident, span, node_id, transparency, rules }); @@ -1034,9 +1041,7 @@ fn check_matcher_core<'tt>( // definition of this macro_rules, not while (re)parsing // the macro when compiling another crate that is using the // macro. (See #86567.) - // Macros defined in the current crate have a real node id, - // whereas macros from an external crate have a dummy id. - if node_id != DUMMY_NODE_ID + if is_defined_in_current_crate(node_id) && matches!(kind, NonterminalKind::Pat(PatParam { inferred: true })) && matches!( next_token, @@ -1296,6 +1301,12 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { } } +fn is_defined_in_current_crate(node_id: NodeId) -> bool { + // Macros defined in the current crate have a real node id, + // whereas macros from an external crate have a dummy id. + node_id != DUMMY_NODE_ID +} + pub(super) fn parser_from_cx( psess: &ParseSess, mut tts: TokenStream, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 0f6f81d7964..80e07af8a46 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3172,6 +3172,8 @@ pub struct ImplItem<'hir> { pub span: Span, pub vis_span: Span, pub has_delayed_lints: bool, + /// When we are in a trait impl, link to the trait-item's id. + pub trait_item_def_id: Option<DefId>, } impl<'hir> ImplItem<'hir> { @@ -4136,7 +4138,7 @@ impl<'hir> Item<'hir> { expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m); - expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]), + expect_foreign_mod, (ExternAbi, &'hir [ForeignItemId]), ItemKind::ForeignMod { abi, items }, (*abi, items); expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm; @@ -4160,7 +4162,7 @@ impl<'hir> Item<'hir> { Ident, &'hir Generics<'hir>, GenericBounds<'hir>, - &'hir [TraitItemRef] + &'hir [TraitItemId] ), ItemKind::Trait(is_auto, safety, ident, generics, bounds, items), (*is_auto, *safety, *ident, generics, bounds, items); @@ -4313,7 +4315,7 @@ pub enum ItemKind<'hir> { /// A module. Mod(Ident, &'hir Mod<'hir>), /// An external module, e.g. `extern { .. }`. - ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] }, + ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemId] }, /// Module-level inline assembly (from `global_asm!`). GlobalAsm { asm: &'hir InlineAsm<'hir>, @@ -4333,7 +4335,7 @@ pub enum ItemKind<'hir> { /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`. Union(Ident, &'hir Generics<'hir>, VariantData<'hir>), /// A trait definition. - Trait(IsAuto, Safety, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]), + Trait(IsAuto, Safety, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemId]), /// A trait alias. TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>), @@ -4360,7 +4362,7 @@ pub struct Impl<'hir> { pub of_trait: Option<TraitRef<'hir>>, pub self_ty: &'hir Ty<'hir>, - pub items: &'hir [ImplItemRef], + pub items: &'hir [ImplItemId], } impl ItemKind<'_> { @@ -4403,43 +4405,6 @@ impl ItemKind<'_> { } } -/// A reference from an trait to one of its associated items. This -/// contains the item's id, naturally, but also the item's name and -/// some other high-level details (like whether it is an associated -/// type or method, and whether it is public). This allows other -/// passes to find the impl they want without loading the ID (which -/// means fewer edges in the incremental compilation graph). -#[derive(Debug, Clone, Copy, HashStable_Generic)] -pub struct TraitItemRef { - pub id: TraitItemId, - pub ident: Ident, - pub kind: AssocItemKind, - pub span: Span, -} - -/// A reference from an impl to one of its associated items. This -/// contains the item's ID, naturally, but also the item's name and -/// some other high-level details (like whether it is an associated -/// type or method, and whether it is public). This allows other -/// passes to find the impl they want without loading the ID (which -/// means fewer edges in the incremental compilation graph). -#[derive(Debug, Clone, Copy, HashStable_Generic)] -pub struct ImplItemRef { - pub id: ImplItemId, - pub ident: Ident, - pub kind: AssocItemKind, - pub span: Span, - /// When we are in a trait impl, link to the trait-item's id. - pub trait_item_def_id: Option<DefId>, -} - -#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)] -pub enum AssocItemKind { - Const, - Fn { has_self: bool }, - Type, -} - // The bodies for items are stored "out of line", in a separate // hashmap in the `Crate`. Here we just record the hir-id of the item // so it can fetched later. @@ -4456,19 +4421,6 @@ impl ForeignItemId { } } -/// A reference from a foreign block to one of its items. This -/// contains the item's ID, naturally, but also the item's name and -/// some other high-level details (like whether it is an associated -/// type or method, and whether it is public). This allows other -/// passes to find the impl they want without loading the ID (which -/// means fewer edges in the incremental compilation graph). -#[derive(Debug, Clone, Copy, HashStable_Generic)] -pub struct ForeignItemRef { - pub id: ForeignItemId, - pub ident: Ident, - pub span: Span, -} - #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ForeignItem<'hir> { pub ident: Ident, @@ -4969,7 +4921,7 @@ mod size_asserts { static_assert_size!(GenericBound<'_>, 64); static_assert_size!(Generics<'_>, 56); static_assert_size!(Impl<'_>, 80); - static_assert_size!(ImplItem<'_>, 88); + static_assert_size!(ImplItem<'_>, 96); static_assert_size!(ImplItemKind<'_>, 40); static_assert_size!(Item<'_>, 88); static_assert_size!(ItemKind<'_>, 64); diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 1bb8f7ad894..3edb94c28da 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -435,17 +435,17 @@ pub trait Visitor<'v>: Sized { fn visit_trait_item(&mut self, ti: &'v TraitItem<'v>) -> Self::Result { walk_trait_item(self, ti) } - fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) -> Self::Result { - walk_trait_item_ref(self, ii) + fn visit_trait_item_ref(&mut self, ii: &'v TraitItemId) -> Self::Result { + walk_trait_item_ref(self, *ii) } fn visit_impl_item(&mut self, ii: &'v ImplItem<'v>) -> Self::Result { walk_impl_item(self, ii) } - fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef) -> Self::Result { - walk_foreign_item_ref(self, ii) + fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemId) -> Self::Result { + walk_foreign_item_ref(self, *ii) } - fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) -> Self::Result { - walk_impl_item_ref(self, ii) + fn visit_impl_item_ref(&mut self, ii: &'v ImplItemId) -> Self::Result { + walk_impl_item_ref(self, *ii) } fn visit_trait_ref(&mut self, t: &'v TraitRef<'v>) -> Self::Result { walk_trait_ref(self, t) @@ -499,9 +499,6 @@ pub trait Visitor<'v>: Sized { fn visit_attribute(&mut self, _attr: &'v Attribute) -> Self::Result { Self::Result::output() } - fn visit_associated_item_kind(&mut self, kind: &'v AssocItemKind) -> Self::Result { - walk_associated_item_kind(self, kind) - } fn visit_defaultness(&mut self, defaultness: &'v Defaultness) -> Self::Result { walk_defaultness(self, defaultness) } @@ -1248,14 +1245,8 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>( V::Result::output() } -pub fn walk_trait_item_ref<'v, V: Visitor<'v>>( - visitor: &mut V, - trait_item_ref: &'v TraitItemRef, -) -> V::Result { - let TraitItemRef { id, ident, ref kind, span: _ } = *trait_item_ref; - try_visit!(visitor.visit_nested_trait_item(id)); - try_visit!(visitor.visit_ident(ident)); - visitor.visit_associated_item_kind(kind) +pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, id: TraitItemId) -> V::Result { + visitor.visit_nested_trait_item(id) } pub fn walk_impl_item<'v, V: Visitor<'v>>( @@ -1271,6 +1262,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>( span: _, vis_span: _, has_delayed_lints: _, + trait_item_def_id: _, } = *impl_item; try_visit!(visitor.visit_ident(ident)); @@ -1293,23 +1285,12 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>( } } -pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>( - visitor: &mut V, - foreign_item_ref: &'v ForeignItemRef, -) -> V::Result { - let ForeignItemRef { id, ident, span: _ } = *foreign_item_ref; - try_visit!(visitor.visit_nested_foreign_item(id)); - visitor.visit_ident(ident) +pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, id: ForeignItemId) -> V::Result { + visitor.visit_nested_foreign_item(id) } -pub fn walk_impl_item_ref<'v, V: Visitor<'v>>( - visitor: &mut V, - impl_item_ref: &'v ImplItemRef, -) -> V::Result { - let ImplItemRef { id, ident, ref kind, span: _, trait_item_def_id: _ } = *impl_item_ref; - try_visit!(visitor.visit_nested_impl_item(id)); - try_visit!(visitor.visit_ident(ident)); - visitor.visit_associated_item_kind(kind) +pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, id: ImplItemId) -> V::Result { + visitor.visit_nested_impl_item(id) } pub fn walk_trait_ref<'v, V: Visitor<'v>>( @@ -1483,13 +1464,6 @@ pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>( V::Result::output() } -pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) -> V::Result { - // No visitable content here: this fn exists so you can call it if - // the right thing to do, should content be added in the future, - // would be to walk it. - V::Result::output() -} - pub fn walk_defaultness<'v, V: Visitor<'v>>(_: &mut V, _: &'v Defaultness) -> V::Result { // No visitable content here: this fn exists so you can call it if // the right thing to do, should content be added in the future, diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f4bbf03f0c2..70fbb8a543e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -930,8 +930,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), check_abi(tcx, it.hir_id(), it.span, abi); - for item in items { - let def_id = item.id.owner_id.def_id; + for &item in items { + let def_id = item.owner_id.def_id; let generics = tcx.generics_of(def_id); let own_counts = generics.own_counts(); @@ -943,13 +943,14 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), (0, _) => ("const", "consts", None), _ => ("type or const", "types or consts", None), }; + let span = tcx.def_span(def_id); struct_span_code_err!( tcx.dcx(), - item.span, + span, E0044, "foreign items may not have {kinds} parameters", ) - .with_span_label(item.span, format!("can't have {kinds} parameters")) + .with_span_label(span, format!("can't have {kinds} parameters")) .with_help( // FIXME: once we start storing spans for type arguments, turn this // into a suggestion. @@ -963,22 +964,23 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), .emit(); } - let item = tcx.hir_foreign_item(item.id); - tcx.ensure_ok().generics_of(item.owner_id); - tcx.ensure_ok().type_of(item.owner_id); - tcx.ensure_ok().predicates_of(item.owner_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); if tcx.is_conditionally_const(def_id) { tcx.ensure_ok().explicit_implied_const_bounds(def_id); tcx.ensure_ok().const_conditions(def_id); } - match item.kind { - hir::ForeignItemKind::Fn(sig, ..) => { - tcx.ensure_ok().codegen_fn_attrs(item.owner_id); - tcx.ensure_ok().fn_sig(item.owner_id); + match tcx.def_kind(def_id) { + DefKind::Fn => { + tcx.ensure_ok().codegen_fn_attrs(def_id); + tcx.ensure_ok().fn_sig(def_id); + let item = tcx.hir_foreign_item(item); + let hir::ForeignItemKind::Fn(sig, ..) = item.kind else { bug!() }; require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span); } - hir::ForeignItemKind::Static(..) => { - tcx.ensure_ok().codegen_fn_attrs(item.owner_id); + DefKind::Static { .. } => { + tcx.ensure_ok().codegen_fn_attrs(def_id); } _ => (), } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index e3532ade32f..dcab6ef1c5a 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -59,7 +59,7 @@ fn equate_intrinsic_type<'tcx>( /// Returns the unsafety of the given intrinsic. fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Safety { - let is_in_list = match tcx.item_name(intrinsic_id.into()) { + let is_in_list = match tcx.item_name(intrinsic_id) { // When adding a new intrinsic to this list, // it's usually worth updating that intrinsic's documentation // to note that it's safe to call, since @@ -144,7 +144,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi tcx.def_span(intrinsic_id), DiagMessage::from(format!( "intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `{}`", - tcx.item_name(intrinsic_id.into()) + tcx.item_name(intrinsic_id) ) )).emit(); } diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 288105dfba7..95f6fba6487 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -167,15 +167,31 @@ fn resolve_block<'tcx>( visitor.cx = prev_cx; } -fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir::Arm<'tcx>) { - fn has_let_expr(expr: &Expr<'_>) -> bool { - match &expr.kind { - hir::ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs), - hir::ExprKind::Let(..) => true, - _ => false, - } - } +/// Resolve a condition from an `if` expression or match guard so that it is a terminating scope +/// if it doesn't contain `let` expressions. +fn resolve_cond<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, cond: &'tcx hir::Expr<'tcx>) { + let terminate = match cond.kind { + // Temporaries for `let` expressions must live into the success branch. + hir::ExprKind::Let(_) => false, + // Logical operator chains are handled in `resolve_expr`. Since logical operator chains in + // conditions are lowered to control-flow rather than boolean temporaries, there's no + // temporary to drop for logical operators themselves. `resolve_expr` will also recursively + // wrap any operands in terminating scopes, other than `let` expressions (which we shouldn't + // terminate) and other logical operators (which don't need a terminating scope, since their + // operands will be terminated). Any temporaries that would need to be dropped will be + // dropped before we leave this operator's scope; terminating them here would be redundant. + hir::ExprKind::Binary( + source_map::Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. }, + _, + _, + ) => false, + // Otherwise, conditions should always drop their temporaries. + _ => true, + }; + resolve_expr(visitor, cond, terminate); +} +fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir::Arm<'tcx>) { let prev_cx = visitor.cx; visitor.enter_node_scope_with_dtor(arm.hir_id.local_id, true); @@ -183,7 +199,7 @@ fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir: resolve_pat(visitor, arm.pat); if let Some(guard) = arm.guard { - resolve_expr(visitor, guard, !has_let_expr(guard)); + resolve_cond(visitor, guard); } resolve_expr(visitor, arm.body, false); @@ -340,7 +356,7 @@ fn resolve_expr<'tcx>( }; visitor.enter_scope(Scope { local_id: then.hir_id.local_id, data }); visitor.cx.var_parent = visitor.cx.parent; - visitor.visit_expr(cond); + resolve_cond(visitor, cond); resolve_expr(visitor, then, true); visitor.cx = expr_cx; resolve_expr(visitor, otherwise, true); @@ -355,7 +371,7 @@ fn resolve_expr<'tcx>( }; visitor.enter_scope(Scope { local_id: then.hir_id.local_id, data }); visitor.cx.var_parent = visitor.cx.parent; - visitor.visit_expr(cond); + resolve_cond(visitor, cond); resolve_expr(visitor, then, true); visitor.cx = expr_cx; } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 428d627ad6f..607028f4d9a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -326,7 +326,9 @@ pub(crate) fn check_trait_item<'tcx>( let mut res = Ok(()); if matches!(tcx.def_kind(def_id), DefKind::AssocFn) { - for &assoc_ty_def_id in tcx.associated_types_for_impl_traits_in_associated_fn(def_id) { + for &assoc_ty_def_id in + tcx.associated_types_for_impl_traits_in_associated_fn(def_id.to_def_id()) + { res = res.and(check_associated_item(tcx, assoc_ty_def_id.expect_local())); } } diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index bd25b4a3260..80bf13dc4b7 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -7,6 +7,7 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -85,7 +86,10 @@ impl<'tcx> InherentCollect<'tcx> { } for &impl_item in items { - if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { + if !find_attr!( + self.tcx.get_all_attrs(impl_item), + AttributeKind::AllowIncoherentImpl(_) + ) { let impl_span = self.tcx.def_span(impl_def_id); return Err(self.tcx.dcx().emit_err(errors::InherentTyOutsideRelevant { span: impl_span, @@ -116,7 +120,10 @@ impl<'tcx> InherentCollect<'tcx> { if !self.tcx.hir_rustc_coherence_is_core() { if self.tcx.features().rustc_attrs() { for &impl_item in items { - if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { + if !find_attr!( + self.tcx.get_all_attrs(impl_item), + AttributeKind::AllowIncoherentImpl(_) + ) { let span = self.tcx.def_span(impl_def_id); return Err(self.tcx.dcx().emit_err(errors::InherentTyOutsidePrimitive { span, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index a185291887d..28a8758178f 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -844,47 +844,47 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { let item = tcx.hir_expect_item(def_id); - let (is_alias, is_auto, safety, items) = match item.kind { - hir::ItemKind::Trait(is_auto, safety, .., items) => { - (false, is_auto == hir::IsAuto::Yes, safety, items) - } - hir::ItemKind::TraitAlias(..) => (true, false, hir::Safety::Safe, &[][..]), + let (is_alias, is_auto, safety) = match item.kind { + hir::ItemKind::Trait(is_auto, safety, ..) => (false, is_auto == hir::IsAuto::Yes, safety), + hir::ItemKind::TraitAlias(..) => (true, false, hir::Safety::Safe), _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"), }; + let attrs = tcx.get_all_attrs(def_id); // Only regular traits can be const. - let constness = if !is_alias && tcx.has_attr(def_id, sym::const_trait) { + let constness = if !is_alias && find_attr!(attrs, AttributeKind::ConstTrait(_)) { hir::Constness::Const } else { hir::Constness::NotConst }; - let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar); + let paren_sugar = find_attr!(attrs, AttributeKind::ParenSugar(_)); if paren_sugar && !tcx.features().unboxed_closures() { tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span }); } // Only regular traits can be marker. - let is_marker = !is_alias && tcx.has_attr(def_id, sym::marker); + let is_marker = !is_alias && find_attr!(attrs, AttributeKind::Marker(_)); - let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive); - let is_fundamental = tcx.has_attr(def_id, sym::fundamental); + let rustc_coinductive = find_attr!(attrs, AttributeKind::Coinductive(_)); + let is_fundamental = find_attr!(attrs, AttributeKind::Fundamental); let [skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch] = find_attr!( - tcx.get_all_attrs(def_id), - AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span:_ } => [*array, *boxed_slice] + attrs, + AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: _ } => [*array, *boxed_slice] ) .unwrap_or([false; 2]); - let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) { + let specialization_kind = if find_attr!(attrs, AttributeKind::UnsafeSpecializationMarker(_)) { ty::trait_def::TraitSpecializationKind::Marker - } else if tcx.has_attr(def_id, sym::rustc_specialization_trait) { + } else if find_attr!(attrs, AttributeKind::SpecializationTrait(_)) { ty::trait_def::TraitSpecializationKind::AlwaysApplicable } else { ty::trait_def::TraitSpecializationKind::None }; - let must_implement_one_of = tcx - .get_attr(def_id, sym::rustc_must_implement_one_of) + let must_implement_one_of = attrs + .iter() + .find(|attr| attr.has_name(sym::rustc_must_implement_one_of)) // Check that there are at least 2 arguments of `#[rustc_must_implement_one_of]` // and that they are all identifiers .and_then(|attr| match attr.meta_item_list() { @@ -909,13 +909,16 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { // functions in the trait with default implementations .and_then(|(list, attr_span)| { let errors = list.iter().filter_map(|ident| { - let item = items.iter().find(|item| item.ident == *ident); + let item = tcx + .associated_items(def_id) + .filter_by_name_unhygienic(ident.name) + .find(|item| item.ident(tcx) == *ident); match item { - Some(item) if matches!(item.kind, hir::AssocItemKind::Fn { .. }) => { - if !tcx.defaultness(item.id.owner_id).has_value() { + Some(item) if matches!(item.kind, ty::AssocKind::Fn { .. }) => { + if !item.defaultness(tcx).has_value() { tcx.dcx().emit_err(errors::FunctionNotHaveDefaultImplementation { - span: item.span, + span: tcx.def_span(item.def_id), note_span: attr_span, }); @@ -926,7 +929,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { } Some(item) => { tcx.dcx().emit_err(errors::MustImplementNotFunction { - span: item.span, + span: tcx.def_span(item.def_id), span_note: errors::MustImplementNotFunctionSpanNote { span: attr_span }, note: errors::MustImplementNotFunctionNote {}, }); @@ -958,8 +961,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { no_dups.then_some(list) }); - let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl); - let implement_via_object = !tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object); + let deny_explicit_impl = find_attr!(attrs, AttributeKind::DenyExplicitImpl(_)); + let implement_via_object = !find_attr!(attrs, AttributeKind::DoNotImplementViaObject(_)); ty::TraitDef { def_id: def_id.to_def_id(), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 20d165897e2..a5bd7c1a34a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2602,7 +2602,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // do a linear search to map this to the synthetic associated type that // it will be lowered to. let def_id = if let Some(parent_def_id) = in_trait { - *tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id) + *tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id.to_def_id()) .iter() .find(|rpitit| match tcx.opt_rpitit_info(**rpitit) { Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 3a525021f6f..2c13c9ef438 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -654,8 +654,8 @@ impl<'a> State<'a> { let (cb, ib) = self.head("extern"); self.word_nbsp(abi.to_string()); self.bopen(ib); - for item in items { - self.ann.nested(self, Nested::ForeignItem(item.id)); + for &foreign_item in items { + self.ann.nested(self, Nested::ForeignItem(foreign_item)); } self.bclose(item.span, cb); } @@ -730,8 +730,8 @@ impl<'a> State<'a> { self.space(); self.bopen(ib); - for impl_item in items { - self.ann.nested(self, Nested::ImplItem(impl_item.id)); + for &impl_item in items { + self.ann.nested(self, Nested::ImplItem(impl_item)); } self.bclose(item.span, cb); } @@ -746,8 +746,8 @@ impl<'a> State<'a> { self.print_where_clause(generics); self.word(" "); self.bopen(ib); - for trait_item in trait_items { - self.ann.nested(self, Nested::TraitItem(trait_item.id)); + for &trait_item in trait_items { + self.ann.nested(self, Nested::TraitItem(trait_item)); } self.bclose(item.span, cb); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 58751f232d0..af1fc045ac8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -51,12 +51,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; match span.desugaring_kind() { - // If span arose from a desugaring of `if` or `while`, then it is the condition - // itself, which diverges, that we are about to lint on. This gives suboptimal - // diagnostics. Instead, stop here so that the `if`- or `while`-expression's - // block is linted instead. - Some(DesugaringKind::CondTemporary) => return, - // Don't lint if the result of an async block or async function is `!`. // This does not affect the unreachable lints *within* the body. Some(DesugaringKind::Async) => return, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index eeb8d33ef65..eb8d671c939 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -241,6 +241,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arg_expr.span, ObligationCauseCode::WellFormed(None), ); + + self.check_place_expr_if_unsized(fn_input_ty, arg_expr); } // First, let's unify the formal method signature with the expectation eagerly. @@ -543,6 +545,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// If `unsized_fn_params` is active, check that unsized values are place expressions. Since + /// the removal of `unsized_locals` in <https://github.com/rust-lang/rust/pull/142911> we can't + /// store them in MIR locals as temporaries. + /// + /// If `unsized_fn_params` is inactive, this will be checked in borrowck instead. + fn check_place_expr_if_unsized(&self, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + if self.tcx.features().unsized_fn_params() && !expr.is_syntactic_place_expr() { + self.require_type_is_sized( + ty, + expr.span, + ObligationCauseCode::UnsizedNonPlaceExpr(expr.span), + ); + } + } + fn report_arg_errors( &self, compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>, @@ -1873,7 +1890,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); } hir::StmtKind::Semi(expr) => { - self.check_expr(expr); + let ty = self.check_expr(expr); + self.check_place_expr_if_unsized(ty, expr); } } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index ea8c2c6ce23..9e324286fa1 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -428,11 +428,9 @@ fn report_unexpected_variant_res( } hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(..), hir_id, .. }) => { suggestion.push((expr.span.shrink_to_lo(), "(".to_string())); - if let hir::Node::Expr(drop_temps) = tcx.parent_hir_node(*hir_id) - && let hir::ExprKind::DropTemps(_) = drop_temps.kind - && let hir::Node::Expr(parent) = tcx.parent_hir_node(drop_temps.hir_id) + if let hir::Node::Expr(parent) = tcx.parent_hir_node(*hir_id) && let hir::ExprKind::If(condition, block, None) = parent.kind - && condition.hir_id == drop_temps.hir_id + && condition.hir_id == *hir_id && let hir::ExprKind::Block(block, _) = block.kind && block.stmts.is_empty() && let Some(expr) = block.expr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 43475521a0f..bf4611e1e34 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -24,7 +24,6 @@ use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; -use rustc_span::hygiene::DesugaringKind; use rustc_span::source_map::Spanned; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym}; use rustc_trait_selection::infer::InferCtxtExt; @@ -902,16 +901,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // then that's equivalent to there existing a LUB. let cause = self.pattern_cause(ti, span); if let Err(err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) { - err.emit_unless( - ti.span - .filter(|&s| { - // In the case of `if`- and `while`-expressions we've already checked - // that `scrutinee: bool`. We know that the pattern is `true`, - // so an error here would be a duplicate and from the wrong POV. - s.is_desugaring(DesugaringKind::CondTemporary) - }) - .is_some(), - ); + err.emit(); } pat_ty diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index a72a7958787..473ac5e0cea 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -56,5 +56,6 @@ rustc_abi = { path = "../rustc_abi" } [features] # tidy-alphabetical-start +check_only = ['rustc_codegen_llvm?/check_only'] llvm = ['dep:rustc_codegen_llvm'] # tidy-alphabetical-end diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index e30dbe80248..e80196ed567 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -273,14 +273,15 @@ pub fn strip_shebang(input: &str) -> Option<usize> { if let Some(input_tail) = input.strip_prefix("#!") { // Ok, this is a shebang but if the next non-whitespace token is `[`, // then it may be valid Rust code, so consider it Rust code. - let next_non_whitespace_token = tokenize(input_tail).map(|tok| tok.kind).find(|tok| { - !matches!( - tok, - TokenKind::Whitespace - | TokenKind::LineComment { doc_style: None } - | TokenKind::BlockComment { doc_style: None, .. } - ) - }); + let next_non_whitespace_token = + tokenize(input_tail, FrontmatterAllowed::No).map(|tok| tok.kind).find(|tok| { + !matches!( + tok, + TokenKind::Whitespace + | TokenKind::LineComment { doc_style: None } + | TokenKind::BlockComment { doc_style: None, .. } + ) + }); if next_non_whitespace_token != Some(TokenKind::OpenBracket) { // No other choice than to consider this a shebang. return Some(2 + input_tail.lines().next().unwrap_or_default().len()); @@ -303,8 +304,16 @@ pub fn validate_raw_str(input: &str, prefix_len: u32) -> Result<(), RawStrError> } /// Creates an iterator that produces tokens from the input string. -pub fn tokenize(input: &str) -> impl Iterator<Item = Token> { - let mut cursor = Cursor::new(input, FrontmatterAllowed::No); +/// +/// When parsing a full Rust document, +/// first [`strip_shebang`] and then allow frontmatters with [`FrontmatterAllowed::Yes`]. +/// +/// When tokenizing a slice of a document, be sure to disallow frontmatters with [`FrontmatterAllowed::No`] +pub fn tokenize( + input: &str, + frontmatter_allowed: FrontmatterAllowed, +) -> impl Iterator<Item = Token> { + let mut cursor = Cursor::new(input, frontmatter_allowed); std::iter::from_fn(move || { let token = cursor.advance_token(); if token.kind != TokenKind::Eof { Some(token) } else { None } diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index fc8d9b9d57b..a7357ba38c8 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -124,8 +124,9 @@ fn test_valid_shebang() { assert_eq!(strip_shebang(input), None); } -fn check_lexing(src: &str, expect: Expect) { - let actual: String = tokenize(src).map(|token| format!("{:?}\n", token)).collect(); +fn check_lexing(src: &str, frontmatter_allowed: FrontmatterAllowed, expect: Expect) { + let actual: String = + tokenize(src, frontmatter_allowed).map(|token| format!("{:?}\n", token)).collect(); expect.assert_eq(&actual) } @@ -133,6 +134,7 @@ fn check_lexing(src: &str, expect: Expect) { fn smoke_test() { check_lexing( "/* my source file */ fn main() { println!(\"zebra\"); }\n", + FrontmatterAllowed::No, expect![[r#" Token { kind: BlockComment { doc_style: None, terminated: true }, len: 20 } Token { kind: Whitespace, len: 1 } @@ -171,6 +173,7 @@ fn comment_flavors() { /** outer doc block */ /*! inner doc block */ ", + FrontmatterAllowed::No, expect![[r#" Token { kind: Whitespace, len: 1 } Token { kind: LineComment { doc_style: None }, len: 7 } @@ -199,6 +202,7 @@ fn comment_flavors() { fn nested_block_comments() { check_lexing( "/* /* */ */'a'", + FrontmatterAllowed::No, expect![[r#" Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 } Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } @@ -210,6 +214,7 @@ fn nested_block_comments() { fn characters() { check_lexing( "'a' ' ' '\\n'", + FrontmatterAllowed::No, expect![[r#" Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } Token { kind: Whitespace, len: 1 } @@ -224,6 +229,7 @@ fn characters() { fn lifetime() { check_lexing( "'abc", + FrontmatterAllowed::No, expect![[r#" Token { kind: Lifetime { starts_with_number: false }, len: 4 } "#]], @@ -234,6 +240,7 @@ fn lifetime() { fn raw_string() { check_lexing( "r###\"\"#a\\b\x00c\"\"###", + FrontmatterAllowed::No, expect![[r#" Token { kind: Literal { kind: RawStr { n_hashes: Some(3) }, suffix_start: 17 }, len: 17 } "#]], @@ -257,6 +264,7 @@ b"a" r###"raw"###suffix br###"raw"###suffix "####, + FrontmatterAllowed::No, expect![[r#" Token { kind: Whitespace, len: 1 } Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } @@ -286,3 +294,78 @@ br###"raw"###suffix "#]], ) } + +#[test] +fn frontmatter_allowed() { + check_lexing( + r#" +---cargo +[dependencies] +clap = "4" +--- + +fn main() {} +"#, + FrontmatterAllowed::Yes, + expect![[r#" + Token { kind: Whitespace, len: 1 } + Token { kind: Frontmatter { has_invalid_preceding_whitespace: false, invalid_infostring: false }, len: 38 } + Token { kind: Whitespace, len: 2 } + Token { kind: Ident, len: 2 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 4 } + Token { kind: OpenParen, len: 1 } + Token { kind: CloseParen, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: OpenBrace, len: 1 } + Token { kind: CloseBrace, len: 1 } + Token { kind: Whitespace, len: 1 } + "#]], + ) +} + +#[test] +fn frontmatter_disallowed() { + check_lexing( + r#" +---cargo +[dependencies] +clap = "4" +--- + +fn main() {} +"#, + FrontmatterAllowed::No, + expect![[r#" + Token { kind: Whitespace, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Ident, len: 5 } + Token { kind: Whitespace, len: 1 } + Token { kind: OpenBracket, len: 1 } + Token { kind: Ident, len: 12 } + Token { kind: CloseBracket, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 4 } + Token { kind: Whitespace, len: 1 } + Token { kind: Eq, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 3 }, len: 3 } + Token { kind: Whitespace, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Whitespace, len: 2 } + Token { kind: Ident, len: 2 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 4 } + Token { kind: OpenParen, len: 1 } + Token { kind: CloseParen, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: OpenBrace, len: 1 } + Token { kind: CloseBrace, len: 1 } + Token { kind: Whitespace, len: 1 } + "#]], + ) +} diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 172f3372483..255ff56f62b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -28,7 +28,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_hir::intravisit::FnKind as HirFnKind; -use rustc_hir::{Body, FnDecl, GenericParamKind, PatKind, PredicateOrigin}; +use rustc_hir::{Body, FnDecl, PatKind, PredicateOrigin}; use rustc_middle::bug; use rustc_middle::lint::LevelAndSource; use rustc_middle::ty::layout::LayoutOf; @@ -952,36 +952,34 @@ declare_lint! { declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GENERIC_ITEMS]); +impl InvalidNoMangleItems { + fn check_no_mangle_on_generic_fn( + &self, + cx: &LateContext<'_>, + attr_span: Span, + def_id: LocalDefId, + ) { + let generics = cx.tcx.generics_of(def_id); + if generics.requires_monomorphization(cx.tcx) { + cx.emit_span_lint( + NO_MANGLE_GENERIC_ITEMS, + cx.tcx.def_span(def_id), + BuiltinNoMangleGeneric { suggestion: attr_span }, + ); + } + } +} + impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { let attrs = cx.tcx.hir_attrs(it.hir_id()); - let check_no_mangle_on_generic_fn = |attr_span: Span, - impl_generics: Option<&hir::Generics<'_>>, - generics: &hir::Generics<'_>, - span| { - for param in - generics.params.iter().chain(impl_generics.map(|g| g.params).into_iter().flatten()) - { - match param.kind { - GenericParamKind::Lifetime { .. } => {} - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { - cx.emit_span_lint( - NO_MANGLE_GENERIC_ITEMS, - span, - BuiltinNoMangleGeneric { suggestion: attr_span }, - ); - break; - } - } - } - }; match it.kind { - hir::ItemKind::Fn { generics, .. } => { + hir::ItemKind::Fn { .. } => { if let Some(attr_span) = find_attr!(attrs, AttributeKind::ExportName {span, ..} => *span) .or_else(|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span)) { - check_no_mangle_on_generic_fn(attr_span, None, generics, it.span); + self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id); } } hir::ItemKind::Const(..) => { @@ -1006,24 +1004,19 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { ); } } - hir::ItemKind::Impl(hir::Impl { generics, items, .. }) => { - for it in *items { - if let hir::AssocItemKind::Fn { .. } = it.kind { - let attrs = cx.tcx.hir_attrs(it.id.hir_id()); - if let Some(attr_span) = - find_attr!(attrs, AttributeKind::ExportName {span, ..} => *span) - .or_else( - || find_attr!(attrs, AttributeKind::NoMangle(span) => *span), - ) - { - check_no_mangle_on_generic_fn( - attr_span, - Some(generics), - cx.tcx.hir_get_generics(it.id.owner_id.def_id).unwrap(), - it.span, - ); - } - } + _ => {} + } + } + + fn check_impl_item(&mut self, cx: &LateContext<'_>, it: &hir::ImplItem<'_>) { + let attrs = cx.tcx.hir_attrs(it.hir_id()); + match it.kind { + hir::ImplItemKind::Fn { .. } => { + if let Some(attr_span) = + find_attr!(attrs, AttributeKind::ExportName {span, ..} => *span) + .or_else(|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span)) + { + self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id); } } _ => {} diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 5989ef9519c..dd16117db1c 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -1,7 +1,7 @@ use rustc_hir::{self as hir, LangItem}; use rustc_middle::ty; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::sym; +use rustc_span::{Ident, sym}; use rustc_trait_selection::traits::supertraits; use crate::lints::{SupertraitAsDerefTarget, SupertraitAsDerefTargetLabel}; @@ -79,11 +79,15 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait { // erase regions in self type for better diagnostic presentation let (self_ty, target_principal, supertrait_principal) = tcx.erase_regions((self_ty, target_principal, supertrait_principal)); - let label2 = impl_ - .items - .iter() - .find_map(|i| (i.ident.name == sym::Target).then_some(i.span)) - .map(|label| SupertraitAsDerefTargetLabel { label }); + let label2 = tcx + .associated_items(item.owner_id) + .find_by_ident_and_kind( + tcx, + Ident::with_dummy_span(sym::Target), + ty::AssocTag::Type, + item.owner_id.to_def_id(), + ) + .map(|label| SupertraitAsDerefTargetLabel { label: tcx.def_span(label.def_id) }); let span = tcx.def_span(item.owner_id.def_id); cx.emit_span_lint( DEREF_INTO_DYN_SUPERTRAIT, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 48982bda0a0..419124d5144 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -339,6 +339,14 @@ fn register_builtins(store: &mut LintStore) { add_lint_group!("deprecated_safe", DEPRECATED_SAFE_2024); + add_lint_group!( + "unknown_or_malformed_diagnostic_attributes", + MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, + MISPLACED_DIAGNOSTIC_ATTRIBUTES, + UNKNOWN_DIAGNOSTIC_ATTRIBUTES + ); + // Register renamed and removed lints. store.register_renamed("single_use_lifetime", "single_use_lifetimes"); store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths"); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 15f0bad226d..a08d68e2d15 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -63,7 +63,10 @@ declare_lint_pass! { LOSSY_PROVENANCE_CASTS, MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, MACRO_USE_EXTERN_CRATE, + MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, META_VARIABLE_MISUSE, + MISPLACED_DIAGNOSTIC_ATTRIBUTES, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN, MUST_NOT_SUSPEND, @@ -112,8 +115,8 @@ declare_lint_pass! { UNFULFILLED_LINT_EXPECTATIONS, UNINHABITED_STATIC, UNKNOWN_CRATE_TYPES, + UNKNOWN_DIAGNOSTIC_ATTRIBUTES, UNKNOWN_LINTS, - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNNAMEABLE_TEST_ITEMS, UNNAMEABLE_TYPES, UNREACHABLE_CODE, @@ -4284,32 +4287,106 @@ declare_lint! { } declare_lint! { - /// The `unknown_or_malformed_diagnostic_attributes` lint detects unrecognized or otherwise malformed - /// diagnostic attributes. + /// The `malformed_diagnostic_attributes` lint detects malformed diagnostic attributes. /// /// ### Example /// /// ```rust - /// #![feature(diagnostic_namespace)] - /// #[diagnostic::does_not_exist] - /// struct Foo; + /// #[diagnostic::do_not_recommend(message = "message")] + /// trait Trait {} /// ``` /// /// {{produces}} /// + /// ### Explanation + /// + /// It is usually a mistake to use options or syntax that is not supported. Check the spelling, + /// and check the diagnostic attribute listing for the correct name and syntax. Also consider if + /// you are using an old version of the compiler; perhaps the option or syntax is only available + /// in a newer version. See the [reference] for a list of diagnostic attributes and the syntax + /// of each. + /// + /// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace + pub MALFORMED_DIAGNOSTIC_ATTRIBUTES, + Warn, + "detects malformed diagnostic attributes", +} + +declare_lint! { + /// The `misplaced_diagnostic_attributes` lint detects wrongly placed diagnostic attributes. + /// + /// ### Example + /// + /// ```rust + /// #[diagnostic::do_not_recommend] + /// struct NotUserFacing; + /// ``` + /// + /// {{produces}} /// /// ### Explanation /// - /// It is usually a mistake to specify a diagnostic attribute that does not exist. Check - /// the spelling, and check the diagnostic attribute listing for the correct name. Also - /// consider if you are using an old version of the compiler, and the attribute - /// is only available in a newer version. - pub UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + /// It is usually a mistake to specify a diagnostic attribute on an item it is not meant for. + /// For example, `#[diagnostic::do_not_recommend]` can only be placed on trait implementations, + /// and does nothing if placed elsewhere. See the [reference] for a list of diagnostic + /// attributes and their correct positions. + /// + /// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace + pub MISPLACED_DIAGNOSTIC_ATTRIBUTES, Warn, - "unrecognized or malformed diagnostic attribute", + "detects diagnostic attributes that are placed on the wrong item", } declare_lint! { + /// The `unknown_diagnostic_attributes` lint detects unknown diagnostic attributes. + /// + /// ### Example + /// + /// ```rust + /// #[diagnostic::does_not_exist] + /// struct Thing; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// It is usually a mistake to specify a diagnostic attribute that does not exist. Check the + /// spelling, and check the diagnostic attribute listing for the correct name. Also consider if + /// you are using an old version of the compiler and the attribute is only available in a newer + /// version. See the [reference] for the list of diagnostic attributes. + /// + /// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace + pub UNKNOWN_DIAGNOSTIC_ATTRIBUTES, + Warn, + "detects unknown diagnostic attributes", +} + +declare_lint! { + /// The `malformed_diagnostic_format_literals` lint detects malformed diagnostic format + /// literals. + /// + /// ### Example + /// + /// ```rust + /// #[diagnostic::on_unimplemented(message = "{Self}} does not implement `Trait`")] + /// trait Trait {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The `#[diagnostic::on_unimplemented]` attribute accepts string literal values that are + /// similar to `format!`'s string literal. See the [reference] for details on what is permitted + /// in this string literal. + /// + /// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace + pub MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, + Warn, + "detects diagnostic attribute with malformed diagnostic format literals", +} +declare_lint! { /// The `ambiguous_glob_imports` lint detects glob imports that should report ambiguity /// errors, but previously didn't do that due to rustc bugs. /// diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 061562b2ec5..39de4783238 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -14,3 +14,7 @@ libc = "0.2.73" # pinned `cc` in `rustc_codegen_ssa` if you update `cc` here. cc = "=1.2.16" # tidy-alphabetical-end + +[features] +# Used by ./x.py check --compile-time-deps to skip building C++ code +check_only = [] diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 9a6549379d3..069b684ad09 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -106,6 +106,10 @@ fn output(cmd: &mut Command) -> String { } fn main() { + if cfg!(feature = "check_only") { + return; + } + for component in REQUIRED_COMPONENTS.iter().chain(OPTIONAL_COMPONENTS.iter()) { println!("cargo:rustc-check-cfg=cfg(llvm_component,values(\"{component}\"))"); } diff --git a/compiler/rustc_metadata/src/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs index 24689ea61d0..8a6b2027083 100644 --- a/compiler/rustc_metadata/src/foreign_modules.rs +++ b/compiler/rustc_metadata/src/foreign_modules.rs @@ -19,7 +19,7 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> FxIndexMap<Def let item = tcx.hir_item(id); if let hir::ItemKind::ForeignMod { abi, items } = item.kind { - let foreign_items = items.iter().map(|it| it.id.owner_id.to_def_id()).collect(); + let foreign_items = items.iter().map(|it| it.owner_id.to_def_id()).collect(); modules.insert(def_id, ForeignModule { def_id, abi, foreign_items }); } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 6943d4198df..19954459cb5 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -326,7 +326,7 @@ provide! { tcx, def_id, other, cdata, .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys"))) } - associated_types_for_impl_traits_in_associated_fn => { table_defaulted_array } + associated_types_for_impl_traits_in_trait_or_impl => { table } visibility => { cdata.get_visibility(def_id.index) } adt_def => { cdata.get_adt_def(def_id.index, tcx) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b0ec605a85f..b50453cb0df 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1382,17 +1382,6 @@ fn should_encode_const(def_kind: DefKind) -> bool { } } -fn should_encode_fn_impl_trait_in_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { - if let Some(assoc_item) = tcx.opt_associated_item(def_id) - && assoc_item.container == ty::AssocItemContainer::Trait - && assoc_item.is_fn() - { - true - } else { - false - } -} - impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_attrs(&mut self, def_id: LocalDefId) { let tcx = self.tcx; @@ -1617,9 +1606,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { { record!(self.tables.trait_impl_trait_tys[def_id] <- table); } - if should_encode_fn_impl_trait_in_trait(tcx, def_id) { - let table = tcx.associated_types_for_impl_traits_in_associated_fn(def_id); - record_defaulted_array!(self.tables.associated_types_for_impl_traits_in_associated_fn[def_id] <- table); + if let DefKind::Impl { .. } | DefKind::Trait = def_kind { + let table = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id); + record!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[def_id] <- table); } } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index a962a787a42..8347626080e 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -403,7 +403,6 @@ define_tables! { explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, explicit_implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>, inherent_impls: Table<DefIndex, LazyArray<DefIndex>>, - associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>, opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>, // Reexported names are not associated with individual `DefId`s, // e.g. a glob import can introduce a lot of names, all with the same `DefId`. @@ -482,6 +481,7 @@ define_tables! { assumed_wf_types_for_rpitit: Table<DefIndex, LazyArray<(Ty<'static>, Span)>>, opaque_ty_origin: Table<DefIndex, LazyValue<hir::OpaqueTyOrigin<DefId>>>, anon_const_kind: Table<DefIndex, LazyValue<ty::AnonConstKind>>, + associated_types_for_impl_traits_in_trait_or_impl: Table<DefIndex, LazyValue<DefIdMap<Vec<DefId>>>>, } #[derive(TyEncodable, TyDecodable)] diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 291707878a3..84710e5e636 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -4,6 +4,7 @@ use rustc_abi::ExternAbi; use rustc_ast::visit::{VisitorResult, walk_list}; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::svh::Svh; @@ -15,7 +16,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::*; use rustc_hir_pretty as pprust_hir; use rustc_span::def_id::StableCrateId; -use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym, with_metavar_spans}; +use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, with_metavar_spans}; use crate::hir::{ModuleItems, nested_filter}; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; @@ -369,7 +370,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn hir_rustc_coherence_is_core(self) -> bool { - self.hir_krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core)) + find_attr!(self.hir_krate_attrs(), AttributeKind::CoherenceIsCore) } pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) { diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index d0dbf64dc59..0d2e23609ce 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -1,6 +1,5 @@ use std::sync::OnceLock; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph; use rustc_data_structures::graph::dominators::{Dominators, dominators}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -10,7 +9,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use smallvec::SmallVec; use crate::mir::traversal::Postorder; -use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK, Terminator, TerminatorKind}; +use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK}; #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] pub struct BasicBlocks<'tcx> { @@ -21,15 +20,6 @@ pub struct BasicBlocks<'tcx> { // Typically 95%+ of basic blocks have 4 or fewer predecessors. type Predecessors = IndexVec<BasicBlock, SmallVec<[BasicBlock; 4]>>; -/// Each `(target, switch)` entry in the map contains a list of switch values -/// that lead to a `target` block from a `switch` block. -/// -/// Note: this type is currently never instantiated, because it's only used for -/// `BasicBlocks::switch_sources`, which is only called by backwards analyses -/// that do `SwitchInt` handling, and we don't have any of those, not even in -/// tests. See #95120 and #94576. -type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[SwitchTargetValue; 1]>>; - #[derive(Debug, Clone, Copy)] pub enum SwitchTargetValue { // A normal switch value. @@ -41,7 +31,6 @@ pub enum SwitchTargetValue { #[derive(Clone, Default, Debug)] struct Cache { predecessors: OnceLock<Predecessors>, - switch_sources: OnceLock<SwitchSources>, reverse_postorder: OnceLock<Vec<BasicBlock>>, dominators: OnceLock<Dominators<BasicBlock>>, } @@ -86,33 +75,6 @@ impl<'tcx> BasicBlocks<'tcx> { }) } - /// Returns info about switch values that lead from one block to another - /// block. See `SwitchSources`. - #[inline] - pub fn switch_sources(&self) -> &SwitchSources { - self.cache.switch_sources.get_or_init(|| { - let mut switch_sources: SwitchSources = FxHashMap::default(); - for (bb, data) in self.basic_blocks.iter_enumerated() { - if let Some(Terminator { - kind: TerminatorKind::SwitchInt { targets, .. }, .. - }) = &data.terminator - { - for (value, target) in targets.iter() { - switch_sources - .entry((target, bb)) - .or_default() - .push(SwitchTargetValue::Normal(value)); - } - switch_sources - .entry((targets.otherwise(), bb)) - .or_default() - .push(SwitchTargetValue::Otherwise); - } - } - switch_sources - }) - } - /// Returns mutable reference to basic blocks. Invalidates CFG cache. #[inline] pub fn as_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> { diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index f039849d1bb..133111ff15d 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -101,6 +101,8 @@ pub struct Allocation<Prov: Provenance = CtfeProvenance, Extra = (), Bytes = Box /// at the given offset. provenance: ProvenanceMap<Prov>, /// Denotes which part of this allocation is initialized. + /// + /// Invariant: the uninitialized parts have no provenance. init_mask: InitMask, /// The alignment of the allocation to detect unaligned reads. /// (`Align` guarantees that this is a power of two.) @@ -796,24 +798,19 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes> Ok(()) } - /// Initialize all previously uninitialized bytes in the entire allocation, and set - /// provenance of everything to `Wildcard`. Before calling this, make sure all - /// provenance in this allocation is exposed! - pub fn prepare_for_native_access(&mut self) { - let full_range = AllocRange { start: Size::ZERO, size: Size::from_bytes(self.len()) }; - // Overwrite uninitialized bytes with 0, to ensure we don't leak whatever their value happens to be. - for chunk in self.init_mask.range_as_init_chunks(full_range) { - if !chunk.is_init() { - let uninit_bytes = &mut self.bytes - [chunk.range().start.bytes_usize()..chunk.range().end.bytes_usize()]; - uninit_bytes.fill(0); - } - } - // Mark everything as initialized now. - self.mark_init(full_range, true); - - // Set provenance of all bytes to wildcard. - self.provenance.write_wildcards(self.len()); + /// Mark all bytes in the given range as initialised and reset the provenance + /// to wildcards. This entirely breaks the normal mechanisms for tracking + /// initialisation and is only provided for Miri operating in native-lib + /// mode. UB will be missed if the underlying bytes were not actually written to. + /// + /// If `range` is `None`, defaults to performing this on the whole allocation. + pub fn process_native_write(&mut self, cx: &impl HasDataLayout, range: Option<AllocRange>) { + let range = range.unwrap_or_else(|| AllocRange { + start: Size::ZERO, + size: Size::from_bytes(self.len()), + }); + self.mark_init(range, true); + self.provenance.write_wildcards(cx, range); } /// Remove all provenance in the given memory range. diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index 9c6e1664386..119d4be64e6 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -212,21 +212,37 @@ impl<Prov: Provenance> ProvenanceMap<Prov> { Ok(()) } - /// Overwrites all provenance in the allocation with wildcard provenance. + /// Overwrites all provenance in the given range with wildcard provenance. + /// Pointers partially overwritten will have their provenances preserved + /// bytewise on their remaining bytes. /// /// Provided for usage in Miri and panics otherwise. - pub fn write_wildcards(&mut self, alloc_size: usize) { + pub fn write_wildcards(&mut self, cx: &impl HasDataLayout, range: AllocRange) { assert!( Prov::OFFSET_IS_ADDR, "writing wildcard provenance is not supported when `OFFSET_IS_ADDR` is false" ); let wildcard = Prov::WILDCARD.unwrap(); - // Remove all pointer provenances, then write wildcards into the whole byte range. - self.ptrs.clear(); - let last = Size::from_bytes(alloc_size); let bytes = self.bytes.get_or_insert_with(Box::default); - for offset in Size::ZERO..last { + + // Remove pointer provenances that overlap with the range, then readd the edge ones bytewise. + let ptr_range = Self::adjusted_range_ptrs(range, cx); + let ptrs = self.ptrs.range(ptr_range.clone()); + if let Some((offset, prov)) = ptrs.first() { + for byte_ofs in *offset..range.start { + bytes.insert(byte_ofs, *prov); + } + } + if let Some((offset, prov)) = ptrs.last() { + for byte_ofs in range.end()..*offset + cx.data_layout().pointer_size() { + bytes.insert(byte_ofs, *prov); + } + } + self.ptrs.remove_range(ptr_range); + + // Overwrite bytewise provenance. + for offset in range.start..range.end() { bytes.insert(offset, wildcard); } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 9af5683ff75..842d118449a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1079,15 +1079,11 @@ rustc_queries! { desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) } } - /// Given `fn_def_id` of a trait or of an impl that implements a given trait: - /// if `fn_def_id` is the def id of a function defined inside a trait, then it creates and returns - /// the associated items that correspond to each impl trait in return position for that trait. - /// if `fn_def_id` is the def id of a function defined inside an impl that implements a trait, then it - /// creates and returns the associated items that correspond to each impl trait in return position - /// of the implemented trait. - query associated_types_for_impl_traits_in_associated_fn(fn_def_id: DefId) -> &'tcx [DefId] { - desc { |tcx| "creating associated items for opaque types returned by `{}`", tcx.def_path_str(fn_def_id) } - cache_on_disk_if { fn_def_id.is_local() } + /// Given the `item_def_id` of a trait or impl, return a mapping from associated fn def id + /// to its associated type items that correspond to the RPITITs in its signature. + query associated_types_for_impl_traits_in_trait_or_impl(item_def_id: DefId) -> &'tcx DefIdMap<Vec<DefId>> { + arena_cache + desc { |tcx| "synthesizing RPITIT items for the opaque types for methods in `{}`", tcx.def_path_str(item_def_id) } separate_provide_extern } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 1a5a9765ce7..5bdde3a514e 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -412,6 +412,10 @@ pub enum ObligationCauseCode<'tcx> { /// Obligations emitted during the normalization of a free type alias. TypeAlias(ObligationCauseCodeHandle<'tcx>, Span, DefId), + + /// Only reachable if the `unsized_fn_params` feature is used. Unsized function arguments must + /// be place expressions because we can't store them in MIR locals as temporaries. + UnsizedNonPlaceExpr(Span), } /// Whether a value can be extracted into a const. diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 44165b06f1c..275458fc85f 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -17,7 +17,6 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_query_system::ich::StableHashingContext; use rustc_session::DataTypeKind; -use rustc_span::sym; use rustc_type_ir::solve::AdtDestructorKind; use tracing::{debug, info, trace}; @@ -296,7 +295,7 @@ impl AdtDefData { flags |= AdtFlags::HAS_CTOR; } - if tcx.has_attr(did, sym::fundamental) { + if find_attr!(tcx.get_all_attrs(did), AttributeKind::Fundamental) { flags |= AdtFlags::IS_FUNDAMENTAL; } if tcx.is_lang_item(did, LangItem::PhantomData) { diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 78b2e265b48..1d15e4de7b6 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -1,9 +1,10 @@ +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_macros::{Decodable, Encodable, HashStable}; -use rustc_span::{Ident, Symbol, sym}; +use rustc_span::{Ident, Symbol}; use super::{TyCtxt, Visibility}; use crate::ty; @@ -160,7 +161,7 @@ impl AssocItem { // Inherent impl but this attr is only applied to trait assoc items. (AssocItemContainer::Impl, None) => return true, }; - tcx.has_attr(def_id, sym::type_const) + find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) } } @@ -257,6 +258,16 @@ impl AssocItems { } /// Returns the associated item with the given identifier and `AssocKind`, if one exists. + /// The identifier is ignoring hygiene. This is meant to be used for lints and diagnostics. + pub fn filter_by_name_unhygienic_and_kind( + &self, + name: Symbol, + assoc_tag: AssocTag, + ) -> impl '_ + Iterator<Item = &ty::AssocItem> { + self.filter_by_name_unhygienic(name).filter(move |item| item.as_tag() == assoc_tag) + } + + /// Returns the associated item with the given identifier and `AssocKind`, if one exists. /// The identifier is matched hygienically. pub fn find_by_ident_and_kind( &self, @@ -284,3 +295,22 @@ impl AssocItems { .find(|item| tcx.hygienic_eq(ident, item.ident(tcx), parent_def_id)) } } + +impl<'tcx> TyCtxt<'tcx> { + /// Given an `fn_def_id` of a trait or a trait implementation: + /// + /// if `fn_def_id` is a function defined inside a trait, then it synthesizes + /// a new def id corresponding to a new associated type for each return- + /// position `impl Trait` in the signature. + /// + /// if `fn_def_id` is a function inside of an impl, then for each synthetic + /// associated type generated for the corresponding trait function described + /// above, synthesize a corresponding associated type in the impl. + pub fn associated_types_for_impl_traits_in_associated_fn( + self, + fn_def_id: DefId, + ) -> &'tcx [DefId] { + let parent_def_id = self.parent(fn_def_id); + &self.associated_types_for_impl_traits_in_trait_or_impl(parent_def_id)[&fn_def_id] + } +} diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 21b7500e46f..d5767ca3786 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -991,18 +991,16 @@ fn needs_fn_once_adapter_shim( Ok(false) } (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => { - // The closure fn `llfn` is a `fn(&self, ...)`. We want a - // `fn(&mut self, ...)`. In fact, at codegen time, these are - // basically the same thing, so we can just return llfn. + // The closure fn is a `fn(&self, ...)`, but we want a `fn(&mut self, ...)`. + // At codegen time, these are basically the same, so we can just return the closure. Ok(false) } (ty::ClosureKind::Fn | ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { - // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut - // self, ...)`. We want a `fn(self, ...)`. We can produce - // this by doing something like: + // The closure fn is a `fn(&self, ...)` or `fn(&mut self, ...)`, but + // we want a `fn(self, ...)`. We can produce this by doing something like: // - // fn call_once(self, ...) { call_mut(&self, ...) } - // fn call_once(mut self, ...) { call_mut(&mut self, ...) } + // fn call_once(self, ...) { Fn::call(&self, ...) } + // fn call_once(mut self, ...) { FnMut::call_mut(&mut self, ...) } // // These are both the same at codegen time. Ok(true) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b780b1c5776..9df44bbc15e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1590,7 +1590,8 @@ impl<'tcx> TyCtxt<'tcx> { } /// Look up the name of a definition across crates. This does not look at HIR. - pub fn opt_item_name(self, def_id: DefId) -> Option<Symbol> { + pub fn opt_item_name(self, def_id: impl IntoQueryParam<DefId>) -> Option<Symbol> { + let def_id = def_id.into_query_param(); if let Some(cnum) = def_id.as_crate_root() { Some(self.crate_name(cnum)) } else { @@ -1610,7 +1611,8 @@ impl<'tcx> TyCtxt<'tcx> { /// [`opt_item_name`] instead. /// /// [`opt_item_name`]: Self::opt_item_name - pub fn item_name(self, id: DefId) -> Symbol { + pub fn item_name(self, id: impl IntoQueryParam<DefId>) -> Symbol { + let id = id.into_query_param(); self.opt_item_name(id).unwrap_or_else(|| { bug!("item_name: no name for {:?}", self.def_path(id)); }) @@ -1619,7 +1621,8 @@ impl<'tcx> TyCtxt<'tcx> { /// Look up the name and span of a definition. /// /// See [`item_name`][Self::item_name] for more information. - pub fn opt_item_ident(self, def_id: DefId) -> Option<Ident> { + pub fn opt_item_ident(self, def_id: impl IntoQueryParam<DefId>) -> Option<Ident> { + let def_id = def_id.into_query_param(); let def = self.opt_item_name(def_id)?; let span = self .def_ident_span(def_id) @@ -1630,7 +1633,8 @@ impl<'tcx> TyCtxt<'tcx> { /// Look up the name and span of a definition. /// /// See [`item_name`][Self::item_name] for more information. - pub fn item_ident(self, def_id: DefId) -> Ident { + pub fn item_ident(self, def_id: impl IntoQueryParam<DefId>) -> Ident { + let def_id = def_id.into_query_param(); self.opt_item_ident(def_id).unwrap_or_else(|| { bug!("item_ident: no name for {:?}", self.def_path(def_id)); }) @@ -1782,21 +1786,18 @@ impl<'tcx> TyCtxt<'tcx> { did: impl Into<DefId>, attr: Symbol, ) -> impl Iterator<Item = &'tcx hir::Attribute> { - self.get_all_attrs(did).filter(move |a: &&hir::Attribute| a.has_name(attr)) + self.get_all_attrs(did).iter().filter(move |a: &&hir::Attribute| a.has_name(attr)) } /// Gets all attributes. /// /// To see if an item has a specific attribute, you should use [`rustc_attr_data_structures::find_attr!`] so you can use matching. - pub fn get_all_attrs( - self, - did: impl Into<DefId>, - ) -> impl Iterator<Item = &'tcx hir::Attribute> { + pub fn get_all_attrs(self, did: impl Into<DefId>) -> &'tcx [hir::Attribute] { let did: DefId = did.into(); if let Some(did) = did.as_local() { - self.hir_attrs(self.local_def_id_to_hir_id(did)).iter() + self.hir_attrs(self.local_def_id_to_hir_id(did)) } else { - self.attrs_for_def(did).iter() + self.attrs_for_def(did) } } diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 3858778bfc8..3d601fc0533 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -23,6 +23,10 @@ impl<A: ParameterizedOverTcx, B: ParameterizedOverTcx> ParameterizedOverTcx for type Value<'tcx> = (A::Value<'tcx>, B::Value<'tcx>); } +impl<T: ParameterizedOverTcx> ParameterizedOverTcx for Vec<T> { + type Value<'tcx> = Vec<T::Value<'tcx>>; +} + impl<I: Idx + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for IndexVec<I, T> { type Value<'tcx> = IndexVec<I, T::Value<'tcx>>; } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 69b8be3d9cb..174892c6f4d 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1052,9 +1052,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for FreeAliasTypeExpander<'tcx> { } self.depth += 1; - ensure_sufficient_stack(|| { + let ty = ensure_sufficient_stack(|| { self.tcx.type_of(alias.def_id).instantiate(self.tcx, alias.args).fold_with(self) - }) + }); + self.depth -= 1; + ty } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { @@ -1681,7 +1683,7 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Intrinsi _ => true, }; Some(ty::IntrinsicDef { - name: tcx.item_name(def_id.into()), + name: tcx.item_name(def_id), must_be_overridden, const_stable: tcx.has_attr(def_id, sym::rustc_intrinsic_const_stable_indirect), }) diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index a49bfc1b8f4..7f47754f6bc 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1084,7 +1084,7 @@ fn find_fallback_pattern_typo<'tcx>( && infcx.can_eq(param_env, ty, cx.tcx.type_of(item.owner_id).instantiate_identity()) { // Look for local consts. - let item_name = cx.tcx.item_name(item.owner_id.into()); + let item_name = cx.tcx.item_name(item.owner_id); let vis = cx.tcx.visibility(item.owner_id); if vis.is_accessible_from(parent, cx.tcx) { accessible.push(item_name); diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index cb647476db8..79c0db7d728 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -1,5 +1,6 @@ use std::ops::RangeInclusive; +use rustc_middle::bug; use rustc_middle::mir::{ self, BasicBlock, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges, }; @@ -112,15 +113,11 @@ impl Direction for Backward { propagate(pred, &tmp); } - mir::TerminatorKind::SwitchInt { ref targets, ref discr } => { - if let Some(mut data) = analysis.get_switch_int_data(block, discr) { - let mut tmp = analysis.bottom_value(body); - for &value in &body.basic_blocks.switch_sources()[&(block, pred)] { - tmp.clone_from(exit_state); - analysis - .apply_switch_int_edge_effect(&mut data, &mut tmp, value, targets); - propagate(pred, &tmp); - } + mir::TerminatorKind::SwitchInt { ref discr, .. } => { + if let Some(_data) = analysis.get_switch_int_data(pred, discr) { + bug!( + "SwitchInt edge effects are unsupported in backward dataflow analyses" + ); } else { propagate(pred, exit_state) } diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index d3b4b99e932..cd9a7f4a39d 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -293,10 +293,6 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_, 'tcx> { fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) { let mut direct_uses = std::mem::take(&mut ssa.direct_uses); let mut copies = IndexVec::from_fn_n(|l| l, body.local_decls.len()); - // We must not unify two locals that are borrowed. But this is fine if one is borrowed and - // the other is not. This bitset is keyed by *class head* and contains whether any member of - // the class is borrowed. - let mut borrowed_classes = ssa.borrowed_locals().clone(); for (local, rvalue, _) in ssa.assignments(body) { let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) @@ -322,8 +318,12 @@ fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) { // visited before `local`, and we just have to copy the representing local. let head = copies[rhs]; - // Do not unify borrowed locals. - if borrowed_classes.contains(local) || borrowed_classes.contains(head) { + // When propagating from `head` to `local` we need to ensure that changes to the address + // are not observable, so at most one the locals involved can be borrowed. Additionally, we + // need to ensure that the definition of `head` dominates all uses of `local`. When `local` + // is borrowed, there might exist an indirect use of `local` that isn't dominated by the + // definition, so we have to reject copy propagation. + if ssa.borrowed_locals().contains(local) { continue; } @@ -339,21 +339,14 @@ fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) { *h = RETURN_PLACE; } } - if borrowed_classes.contains(head) { - borrowed_classes.insert(RETURN_PLACE); - } } else { copies[local] = head; - if borrowed_classes.contains(local) { - borrowed_classes.insert(head); - } } direct_uses[rhs] -= 1; } debug!(?copies); debug!(?direct_uses); - debug!(?borrowed_classes); // Invariant: `copies` must point to the head of an equivalence class. #[cfg(debug_assertions)] @@ -362,13 +355,6 @@ fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) { } debug_assert_eq!(copies[RETURN_PLACE], RETURN_PLACE); - // Invariant: `borrowed_classes` must be true if any member of the class is borrowed. - #[cfg(debug_assertions)] - for &head in copies.iter() { - let any_borrowed = ssa.borrowed_locals.iter().any(|l| copies[l] == head); - assert_eq!(borrowed_classes.contains(head), any_borrowed); - } - ssa.direct_uses = direct_uses; ssa.copy_classes = copies; } diff --git a/compiler/rustc_parse/src/parser/cfg_select.rs b/compiler/rustc_parse/src/parser/cfg_select.rs new file mode 100644 index 00000000000..24a05afff4a --- /dev/null +++ b/compiler/rustc_parse/src/parser/cfg_select.rs @@ -0,0 +1,73 @@ +use rustc_ast::token::Token; +use rustc_ast::tokenstream::{TokenStream, TokenTree}; +use rustc_ast::{MetaItemInner, token}; +use rustc_errors::PResult; +use rustc_span::Span; + +use crate::exp; +use crate::parser::Parser; + +pub enum CfgSelectRule { + Cfg(MetaItemInner), + Wildcard(Token), +} + +#[derive(Default)] +pub struct CfgSelectBranches { + /// All the conditional branches. + pub reachable: Vec<(MetaItemInner, TokenStream, Span)>, + /// The first wildcard `_ => { ... }` branch. + pub wildcard: Option<(Token, TokenStream, Span)>, + /// All branches after the first wildcard, including further wildcards. + /// These branches are kept for formatting. + pub unreachable: Vec<(CfgSelectRule, TokenStream, Span)>, +} + +/// Parses a `TokenTree` that must be of the form `{ /* ... */ }`, and returns a `TokenStream` where +/// the surrounding braces are stripped. +fn parse_token_tree<'a>(p: &mut Parser<'a>) -> PResult<'a, TokenStream> { + // Generate an error if the `=>` is not followed by `{`. + if p.token != token::OpenBrace { + p.expect(exp!(OpenBrace))?; + } + + // Strip the outer '{' and '}'. + match p.parse_token_tree() { + TokenTree::Token(..) => unreachable!("because of the expect above"), + TokenTree::Delimited(.., tts) => Ok(tts), + } +} + +pub fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches> { + let mut branches = CfgSelectBranches::default(); + + while p.token != token::Eof { + if p.eat_keyword(exp!(Underscore)) { + let underscore = p.prev_token; + p.expect(exp!(FatArrow))?; + + let tts = parse_token_tree(p)?; + let span = underscore.span.to(p.token.span); + + match branches.wildcard { + None => branches.wildcard = Some((underscore, tts, span)), + Some(_) => { + branches.unreachable.push((CfgSelectRule::Wildcard(underscore), tts, span)) + } + } + } else { + let meta_item = p.parse_meta_item_inner()?; + p.expect(exp!(FatArrow))?; + + let tts = parse_token_tree(p)?; + let span = meta_item.span().to(p.token.span); + + match branches.wildcard { + None => branches.reachable.push((meta_item, tts, span)), + Some(_) => branches.unreachable.push((CfgSelectRule::Cfg(meta_item), tts, span)), + } + } + } + + Ok(branches) +} diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 2787be46f33..90491e53249 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1,4 +1,3 @@ -pub mod asm; pub mod attr; mod attr_wrapper; mod diagnostics; @@ -12,6 +11,11 @@ mod stmt; pub mod token_type; mod ty; +// Parsers for non-functionlike builtin macros are defined in rustc_parse so they can be used by +// both rustc_builtin_macros and rustfmt. +pub mod asm; +pub mod cfg_select; + use std::assert_matches::debug_assert_matches; use std::{fmt, mem, slice}; diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 11424ec3724..bb5c1e0e653 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -283,6 +283,18 @@ pub fn check_builtin_meta_item( | sym::rustc_confusables | sym::rustc_skip_during_method_dispatch | sym::rustc_pass_by_value + | sym::rustc_deny_explicit_impl + | sym::rustc_do_not_implement_via_object + | sym::rustc_coinductive + | sym::const_trait + | sym::rustc_specialization_trait + | sym::rustc_unsafe_specialization_marker + | sym::rustc_allow_incoherent_impl + | sym::rustc_coherence_is_core + | sym::marker + | sym::fundamental + | sym::rustc_paren_sugar + | sym::type_const | sym::repr | sym::align | sym::deprecated diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index b9167489076..503fc98da76 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -10,6 +10,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_ast_lowering = { path = "../rustc_ast_lowering" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr_data_structures = { path = "../rustc_attr_data_structures" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index b139ed6a66c..0ac42f03eb2 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -79,7 +79,7 @@ fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut for meta_item in meta_items { match meta_item.name() { Some(sym::debug) => { - let fn_name = tcx.item_name(item_def_id.into()); + let fn_name = tcx.item_name(item_def_id); tcx.dcx().emit_err(AbiOf { span: tcx.def_span(item_def_id), fn_name, @@ -135,7 +135,7 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut item_def_id, ); - let fn_name = tcx.item_name(item_def_id.into()); + let fn_name = tcx.item_name(item_def_id); tcx.dcx().emit_err(AbiOf { span, fn_name, fn_abi: format!("{:#?}", abi) }); } Some(sym::assert_eq) => { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0aa6a2b41cf..e7af615a715 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -7,10 +7,12 @@ use std::cell::Cell; use std::collections::hash_map::Entry; +use std::slice; use rustc_abi::{Align, ExternAbi, Size}; use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, ast}; use rustc_attr_data_structures::{AttributeKind, InlineAttr, ReprAttr, find_attr}; +use rustc_attr_parsing::{AttributeParser, Late}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey}; use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; @@ -18,8 +20,8 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ - self as hir, self, AssocItemKind, Attribute, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, - HirId, Item, ItemKind, MethodKind, Safety, Target, TraitItem, + self as hir, self, Attribute, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId, Item, + ItemKind, MethodKind, Safety, Target, TraitItem, }; use rustc_macros::LintDiagnostic; use rustc_middle::hir::nested_filter; @@ -33,7 +35,7 @@ use rustc_session::config::CrateType; use rustc_session::lint; use rustc_session::lint::builtin::{ CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS, - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES, }; use rustc_session::parse::feature_err; use rustc_span::edition::Edition; @@ -120,12 +122,35 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for attr in attrs { let mut style = None; match attr { - Attribute::Parsed(AttributeKind::SkipDuringMethodDispatch { - span: attr_span, - .. - }) => { + Attribute::Parsed( + AttributeKind::SkipDuringMethodDispatch { span: attr_span, .. } + | AttributeKind::Coinductive(attr_span) + | AttributeKind::ConstTrait(attr_span) + | AttributeKind::DenyExplicitImpl(attr_span) + | AttributeKind::DoNotImplementViaObject(attr_span), + ) => { self.check_must_be_applied_to_trait(*attr_span, span, target); } + &Attribute::Parsed( + AttributeKind::SpecializationTrait(attr_span) + | AttributeKind::UnsafeSpecializationMarker(attr_span) + | AttributeKind::ParenSugar(attr_span), + ) => { + // FIXME: more validation is needed + self.check_must_be_applied_to_trait(attr_span, span, target); + } + &Attribute::Parsed(AttributeKind::TypeConst(attr_span)) => { + self.check_type_const(hir_id, attr_span, target) + } + &Attribute::Parsed(AttributeKind::Marker(attr_span)) => { + self.check_marker(hir_id, attr_span, span, target) + } + Attribute::Parsed(AttributeKind::Fundamental | AttributeKind::CoherenceIsCore) => { + // FIXME: add validation + } + &Attribute::Parsed(AttributeKind::AllowIncoherentImpl(attr_span)) => { + self.check_allow_incoherent_impl(attr_span, span, target) + } Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { self.check_confusables(*first_span, target); } @@ -259,7 +284,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::no_sanitize, ..] => { self.check_no_sanitize(attr, span, target) } - [sym::marker, ..] => self.check_marker(hir_id, attr, span, target), [sym::thread_local, ..] => self.check_thread_local(attr, span, target), [sym::doc, ..] => self.check_doc_attrs( attr, @@ -297,16 +321,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::rustc_dirty, ..] | [sym::rustc_if_this_changed, ..] | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), - [sym::rustc_coinductive, ..] - | [sym::rustc_must_implement_one_of, ..] - | [sym::rustc_deny_explicit_impl, ..] - | [sym::rustc_do_not_implement_via_object, ..] - | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), + [sym::rustc_must_implement_one_of, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), - [sym::rustc_allow_incoherent_impl, ..] => { - self.check_allow_incoherent_impl(attr, span, target) - } [sym::rustc_has_incoherent_inherent_impls, ..] => { self.check_has_incoherent_inherent_impls(attr, span, target) } @@ -339,9 +356,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::coroutine, ..] => { self.check_coroutine(attr, target); } - [sym::type_const, ..] => { - self.check_type_const(hir_id,attr, target); - } [sym::linkage, ..] => self.check_linkage(attr, span, target), [ // ok @@ -366,18 +380,24 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::prelude_import | sym::panic_handler | sym::allow_internal_unsafe - | sym::fundamental | sym::lang | sym::needs_allocator | sym::default_lib_allocator | sym::custom_mir, .. ] => {} - [name, ..] => { + [name, rest@..] => { match BUILTIN_ATTRIBUTE_MAP.get(name) { // checked below Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {} Some(_) => { + if rest.len() > 0 && AttributeParser::<Late>::is_parsed_attribute(slice::from_ref(name)) { + // Check if we tried to use a builtin attribute as an attribute namespace, like `#[must_use::skip]`. + // This check is here to solve https://github.com/rust-lang/rust/issues/137590 + // An error is already produced for this case elsewhere + continue + } + // FIXME: differentiate between unstable and internal attributes just // like we do with features instead of just accepting `rustc_` // attributes by name. That should allow trimming the above list, too. @@ -449,7 +469,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ); } - /// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl. + /// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl and that it has no + /// arguments. fn check_do_not_recommend( &self, attr_span: Span, @@ -466,7 +487,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ) { self.tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MISPLACED_DIAGNOSTIC_ATTRIBUTES, hir_id, attr_span, errors::IncorrectDoNotRecommendLocation, @@ -474,7 +495,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } if !attr.is_word() { self.tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_ATTRIBUTES, hir_id, attr_span, errors::DoNotRecommendDoesNotExpectArgs, @@ -486,7 +507,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_diagnostic_on_unimplemented(&self, attr_span: Span, hir_id: HirId, target: Target) { if !matches!(target, Target::Trait) { self.tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MISPLACED_DIAGNOSTIC_ATTRIBUTES, hir_id, attr_span, DiagnosticOnUnimplementedOnlyForTraits, @@ -830,7 +851,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Checks if the `#[marker]` attribute on an `item` is valid. - fn check_marker(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { + fn check_marker(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) { match target { Target::Trait => {} // FIXME(#80564): We permit struct fields, match arms and macro defs to have an @@ -838,13 +859,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // erroneously allowed it and some crates used it accidentally, to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { - self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "marker"); + self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "marker"); } _ => { - self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait { - attr_span: attr.span(), - defn_span: span, - }); + self.dcx() + .emit_err(errors::AttrShouldBeAppliedToTrait { attr_span, defn_span: span }); } } } @@ -1132,7 +1151,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if generics.params.len() != 0 => {} ItemKind::Trait(_, _, _, generics, _, items) if generics.params.len() != 0 - || items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {} + || items.iter().any(|item| { + matches!(self.tcx.def_kind(item.owner_id), DefKind::AssocTy) + }) => {} ItemKind::TyAlias(_, generics, _) if generics.params.len() != 0 => {} _ => { self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() }); @@ -1489,11 +1510,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_allow_incoherent_impl(&self, attr: &Attribute, span: Span, target: Target) { + fn check_allow_incoherent_impl(&self, attr_span: Span, span: Span, target: Target) { match target { Target::Method(MethodKind::Inherent) => {} _ => { - self.dcx().emit_err(errors::AllowIncoherentImpl { attr_span: attr.span(), span }); + self.dcx().emit_err(errors::AllowIncoherentImpl { attr_span, span }); } } } @@ -2514,7 +2535,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_type_const(&self, hir_id: HirId, attr: &Attribute, target: Target) { + fn check_type_const(&self, hir_id: HirId, attr_span: Span, target: Target) { let tcx = self.tcx; if target == Target::AssocConst && let parent = tcx.parent(hir_id.expect_owner().to_def_id()) @@ -2524,7 +2545,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } else { self.dcx() .struct_span_err( - attr.span(), + attr_span, "`#[type_const]` must only be applied to trait associated constants", ) .emit(); diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index cdfd1a2b07e..d987041fe0e 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -18,7 +18,7 @@ use rustc_hir::{self as hir, ImplItem, ImplItemKind, Node, PatKind, QPath, TyKin use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::privacy::Level; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, AssocTag, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::DEAD_CODE; use rustc_session::lint::{self, LintExpectationId}; @@ -115,7 +115,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { fn handle_res(&mut self, res: Res) { match res { - Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias, def_id) => { + Res::Def( + DefKind::Const | DefKind::AssocConst | DefKind::AssocTy | DefKind::TyAlias, + def_id, + ) => { self.check_def_id(def_id); } _ if self.in_pat => {} @@ -415,8 +418,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { hir::ItemKind::Trait(.., trait_item_refs) => { // mark assoc ty live if the trait is live for trait_item in trait_item_refs { - if matches!(trait_item.kind, hir::AssocItemKind::Type) { - self.check_def_id(trait_item.id.owner_id.to_def_id()); + if matches!(self.tcx.def_kind(trait_item.owner_id), DefKind::AssocTy) { + self.check_def_id(trait_item.owner_id.to_def_id()); } } intravisit::walk_item(self, item) @@ -482,7 +485,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { ) -> bool { let trait_def_id = match self.tcx.def_kind(local_def_id) { // assoc impl items of traits are live if the corresponding trait items are live - DefKind::AssocFn => self + DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => self .tcx .associated_item(local_def_id) .trait_item_def_id @@ -647,6 +650,31 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { self.in_pat = in_pat; } + + fn visit_trait_ref(&mut self, t: &'tcx hir::TraitRef<'tcx>) { + if let Some(trait_def_id) = t.path.res.opt_def_id() + && let Some(segment) = t.path.segments.last() + && let Some(args) = segment.args + { + for constraint in args.constraints { + if let Some(local_def_id) = self + .tcx + .associated_items(trait_def_id) + .find_by_ident_and_kind( + self.tcx, + constraint.ident, + AssocTag::Const, + trait_def_id, + ) + .and_then(|item| item.def_id.as_local()) + { + self.worklist.push((local_def_id, ComesFromAllowExpect::No)); + } + } + } + + intravisit::walk_trait_ref(self, t); + } } fn has_allow_dead_code_or_lang_attr( @@ -744,18 +772,12 @@ fn check_item<'tcx>( { worklist.push((local_def_id, comes_from_allow)); } else if of_trait { - // FIXME: This condition can be removed - // if we support dead check for assoc consts and tys. - if !matches!(tcx.def_kind(local_def_id), DefKind::AssocFn) { - worklist.push((local_def_id, ComesFromAllowExpect::No)); - } else { - // We only care about associated items of traits, - // because they cannot be visited directly, - // so we later mark them as live if their corresponding traits - // or trait items and self types are both live, - // but inherent associated items can be visited and marked directly. - unsolved_items.push((id, local_def_id)); - } + // We only care about associated items of traits, + // because they cannot be visited directly, + // so we later mark them as live if their corresponding traits + // or trait items and self types are both live, + // but inherent associated items can be visited and marked directly. + unsolved_items.push((id, local_def_id)); } } } @@ -791,15 +813,14 @@ fn check_trait_item( worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>, id: hir::TraitItemId, ) { - use hir::TraitItemKind::{Const, Fn}; - if matches!(tcx.def_kind(id.owner_id), DefKind::AssocConst | DefKind::AssocFn) { - let trait_item = tcx.hir_trait_item(id); - if matches!(trait_item.kind, Const(_, Some(_)) | Fn(..)) - && let Some(comes_from_allow) = - has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id) - { - worklist.push((trait_item.owner_id.def_id, comes_from_allow)); - } + use hir::TraitItemKind::{Const, Fn, Type}; + + let trait_item = tcx.hir_trait_item(id); + if matches!(trait_item.kind, Const(_, Some(_)) | Type(_, Some(_)) | Fn(..)) + && let Some(comes_from_allow) = + has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id) + { + worklist.push((trait_item.owner_id.def_id, comes_from_allow)); } } @@ -1163,6 +1184,7 @@ impl<'tcx> DeadVisitor<'tcx> { } match self.tcx.def_kind(def_id) { DefKind::AssocConst + | DefKind::AssocTy | DefKind::AssocFn | DefKind::Fn | DefKind::Static { .. } diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index e38c7b2cbf1..6ee325dce03 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -467,9 +467,9 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_trait_item(self, ti) } - fn visit_trait_item_ref(&mut self, ti: &'v hir::TraitItemRef) { - self.record("TraitItemRef", Some(ti.id.hir_id()), ti); - hir_visit::walk_trait_item_ref(self, ti) + fn visit_trait_item_ref(&mut self, ti: &'v hir::TraitItemId) { + self.record("TraitItemId", Some(ti.hir_id()), ti); + hir_visit::walk_trait_item_ref(self, *ti) } fn visit_impl_item(&mut self, ii: &'v hir::ImplItem<'v>) { @@ -480,14 +480,14 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_impl_item(self, ii) } - fn visit_foreign_item_ref(&mut self, fi: &'v hir::ForeignItemRef) { - self.record("ForeignItemRef", Some(fi.id.hir_id()), fi); - hir_visit::walk_foreign_item_ref(self, fi) + fn visit_foreign_item_ref(&mut self, fi: &'v hir::ForeignItemId) { + self.record("ForeignItemId", Some(fi.hir_id()), fi); + hir_visit::walk_foreign_item_ref(self, *fi) } - fn visit_impl_item_ref(&mut self, ii: &'v hir::ImplItemRef) { - self.record("ImplItemRef", Some(ii.id.hir_id()), ii); - hir_visit::walk_impl_item_ref(self, ii) + fn visit_impl_item_ref(&mut self, ii: &'v hir::ImplItemId) { + self.record("ImplItemId", Some(ii.hir_id()), ii); + hir_visit::walk_impl_item_ref(self, *ii) } fn visit_param_bound(&mut self, b: &'v hir::GenericBound<'v>) { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index a30655d32a7..adda94fda8f 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -880,11 +880,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { } for impl_item_ref in *items { - let impl_item = self.tcx.associated_item(impl_item_ref.id.owner_id); + let impl_item = self.tcx.associated_item(impl_item_ref.owner_id); if let Some(def_id) = impl_item.trait_item_def_id { // Pass `None` to skip deprecation warnings. - self.tcx.check_stability(def_id, None, impl_item_ref.span, None); + self.tcx.check_stability( + def_id, + None, + self.tcx.def_span(impl_item_ref.owner_id), + None, + ); } } } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 963f4c77d80..ab2433234aa 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -26,7 +26,7 @@ use rustc_errors::{MultiSpan, listify}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, InferKind, Visitor}; -use rustc_hir::{AmbigArg, AssocItemKind, ForeignItemKind, ItemId, ItemKind, PatKind}; +use rustc_hir::{AmbigArg, ForeignItemKind, ItemId, ItemKind, PatKind}; use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level}; use rustc_middle::query::Providers; use rustc_middle::ty::print::PrintTraitRefExt as _; @@ -672,14 +672,14 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { self.reach(item.owner_id.def_id, item_ev).generics().predicates(); for trait_item_ref in trait_item_refs { - self.update(trait_item_ref.id.owner_id.def_id, item_ev, Level::Reachable); + self.update(trait_item_ref.owner_id.def_id, item_ev, Level::Reachable); let tcx = self.tcx; - let mut reach = self.reach(trait_item_ref.id.owner_id.def_id, item_ev); + let mut reach = self.reach(trait_item_ref.owner_id.def_id, item_ev); reach.generics().predicates(); - if trait_item_ref.kind == AssocItemKind::Type - && !tcx.defaultness(trait_item_ref.id.owner_id).has_value() + if let DefKind::AssocTy = tcx.def_kind(trait_item_ref.owner_id) + && !tcx.defaultness(trait_item_ref.owner_id).has_value() { // No type to visit. } else { @@ -715,7 +715,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty().trait_ref(); for impl_item_ref in impl_.items { - let def_id = impl_item_ref.id.owner_id.def_id; + let def_id = impl_item_ref.owner_id.def_id; let max_vis = impl_.of_trait.is_none().then(|| self.tcx.local_visibility(def_id)); self.update_eff_vis(def_id, item_ev, max_vis, Level::Direct); @@ -755,8 +755,8 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } hir::ItemKind::ForeignMod { items, .. } => { for foreign_item in items { - if let Some(foreign_item_ev) = self.get(foreign_item.id.owner_id.def_id) { - self.reach(foreign_item.id.owner_id.def_id, foreign_item_ev) + if let Some(foreign_item_ev) = self.get(foreign_item.owner_id.def_id) { + self.reach(foreign_item.owner_id.def_id, foreign_item_ev) .generics() .predicates() .ty(); @@ -1576,16 +1576,15 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { fn check_assoc_item( &self, - def_id: LocalDefId, - assoc_item_kind: AssocItemKind, + item: &ty::AssocItem, vis: ty::Visibility, effective_vis: Option<EffectiveVisibility>, ) { - let mut check = self.check(def_id, vis, effective_vis); + let mut check = self.check(item.def_id.expect_local(), vis, effective_vis); - let (check_ty, is_assoc_ty) = match assoc_item_kind { - AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false), - AssocItemKind::Type => (self.tcx.defaultness(def_id).has_value(), true), + let (check_ty, is_assoc_ty) = match item.kind { + ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => (true, false), + ty::AssocKind::Type { .. } => (item.defaultness(self.tcx).has_value(), true), }; check.in_assoc_ty = is_assoc_ty; @@ -1619,30 +1618,20 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { self.check(def_id, item_visibility, effective_vis).generics().bounds(); } DefKind::Trait => { - let item = tcx.hir_item(id); - if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind { - self.check_unnameable(item.owner_id.def_id, effective_vis); + self.check_unnameable(def_id, effective_vis); - self.check(item.owner_id.def_id, item_visibility, effective_vis) - .generics() - .predicates(); + self.check(def_id, item_visibility, effective_vis).generics().predicates(); - for trait_item_ref in trait_item_refs { - self.check_assoc_item( - trait_item_ref.id.owner_id.def_id, - trait_item_ref.kind, + for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() { + self.check_assoc_item(assoc_item, item_visibility, effective_vis); + + if assoc_item.is_type() { + self.check( + assoc_item.def_id.expect_local(), item_visibility, effective_vis, - ); - - if let AssocItemKind::Type = trait_item_ref.kind { - self.check( - trait_item_ref.id.owner_id.def_id, - item_visibility, - effective_vis, - ) - .bounds(); - } + ) + .bounds(); } } } @@ -1669,8 +1658,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { DefKind::ForeignMod => { let item = tcx.hir_item(id); if let hir::ItemKind::ForeignMod { items, .. } = item.kind { - for foreign_item in items { - let foreign_item = tcx.hir_foreign_item(foreign_item.id); + for &foreign_item in items { + let foreign_item = tcx.hir_foreign_item(foreign_item); let ev = self.get(foreign_item.owner_id.def_id); let vis = tcx.local_visibility(foreign_item.owner_id.def_id); @@ -1714,69 +1703,52 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { // Subitems of inherent impls have their own publicity. // A trait impl is public when both its type and its trait are public // Subitems of trait impls have inherited publicity. - DefKind::Impl { .. } => { - let item = tcx.hir_item(id); - if let hir::ItemKind::Impl(impl_) = item.kind { - let impl_vis = ty::Visibility::of_impl::<false>( - item.owner_id.def_id, - tcx, - &Default::default(), - ); + DefKind::Impl { of_trait } => { + let impl_vis = ty::Visibility::of_impl::<false>(def_id, tcx, &Default::default()); - // We are using the non-shallow version here, unlike when building the - // effective visisibilities table to avoid large number of false positives. - // For example in - // - // impl From<Priv> for Pub { - // fn from(_: Priv) -> Pub {...} - // } - // - // lints shouldn't be emitted even if `from` effective visibility - // is larger than `Priv` nominal visibility and if `Priv` can leak - // in some scenarios due to type inference. - let impl_ev = EffectiveVisibility::of_impl::<false>( - item.owner_id.def_id, - tcx, - self.effective_visibilities, - ); + // We are using the non-shallow version here, unlike when building the + // effective visisibilities table to avoid large number of false positives. + // For example in + // + // impl From<Priv> for Pub { + // fn from(_: Priv) -> Pub {...} + // } + // + // lints shouldn't be emitted even if `from` effective visibility + // is larger than `Priv` nominal visibility and if `Priv` can leak + // in some scenarios due to type inference. + let impl_ev = + EffectiveVisibility::of_impl::<false>(def_id, tcx, self.effective_visibilities); + + let mut check = self.check(def_id, impl_vis, Some(impl_ev)); + + // Generics and predicates of trait impls are intentionally not checked + // for private components (#90586). + if !of_trait { + check.generics().predicates(); + } - let mut check = self.check(item.owner_id.def_id, impl_vis, Some(impl_ev)); - // Generics and predicates of trait impls are intentionally not checked - // for private components (#90586). - if impl_.of_trait.is_none() { - check.generics().predicates(); - } - // Skip checking private components in associated types, due to lack of full - // normalization they produce very ridiculous false positives. - // FIXME: Remove this when full normalization is implemented. - check.skip_assoc_tys = true; - check.ty().trait_ref(); - - for impl_item_ref in impl_.items { - let impl_item_vis = if impl_.of_trait.is_none() { - min( - tcx.local_visibility(impl_item_ref.id.owner_id.def_id), - impl_vis, - tcx, - ) - } else { - impl_vis - }; + // Skip checking private components in associated types, due to lack of full + // normalization they produce very ridiculous false positives. + // FIXME: Remove this when full normalization is implemented. + check.skip_assoc_tys = true; + check.ty().trait_ref(); - let impl_item_ev = if impl_.of_trait.is_none() { - self.get(impl_item_ref.id.owner_id.def_id) - .map(|ev| ev.min(impl_ev, self.tcx)) - } else { - Some(impl_ev) - }; - - self.check_assoc_item( - impl_item_ref.id.owner_id.def_id, - impl_item_ref.kind, - impl_item_vis, - impl_item_ev, - ); - } + for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() { + let impl_item_vis = if !of_trait { + min(tcx.local_visibility(assoc_item.def_id.expect_local()), impl_vis, tcx) + } else { + impl_vis + }; + + let impl_item_ev = if !of_trait { + self.get(assoc_item.def_id.expect_local()) + .map(|ev| ev.min(impl_ev, self.tcx)) + } else { + Some(impl_ev) + }; + + self.check_assoc_item(assoc_item, impl_item_vis, impl_item_ev); } } _ => {} diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index ef122deba4e..6979d89a8e7 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -32,10 +32,9 @@ use crate::def_collector::collect_definitions; use crate::imports::{ImportData, ImportKind}; use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use crate::{ - BindingKey, Determinacy, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, - ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult, - ResolutionError, Resolver, ResolverArenas, Segment, ToNameBinding, Used, VisResolutionError, - errors, + BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot, + NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult, ResolutionError, + Resolver, ResolverArenas, Segment, ToNameBinding, Used, VisResolutionError, errors, }; type Res = def::Res<NodeId>; @@ -620,16 +619,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let kind = ImportKind::Single { source: source.ident, target: ident, - source_bindings: PerNS { - type_ns: Cell::new(Err(Determinacy::Undetermined)), - value_ns: Cell::new(Err(Determinacy::Undetermined)), - macro_ns: Cell::new(Err(Determinacy::Undetermined)), - }, - target_bindings: PerNS { - type_ns: Cell::new(None), - value_ns: Cell::new(None), - macro_ns: Cell::new(None), - }, + bindings: Default::default(), type_ns_only, nested, id, diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 2e870c47f8e..81ee02ac3c7 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -511,7 +511,7 @@ impl Resolver<'_, '_> { for (_key, resolution) in self.resolutions(*module).borrow().iter() { let resolution = resolution.borrow(); - if let Some(binding) = resolution.binding + if let Some(binding) = resolution.best_binding() && let NameBindingKind::Import { import, .. } = binding.kind && let ImportKind::Single { id, .. } = import.kind { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index c4ff5770e76..b2f16fb1dfb 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1440,7 +1440,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |(key, name_resolution)| { if key.ns == TypeNS && key.ident == ident - && let Some(binding) = name_resolution.borrow().binding + && let Some(binding) = name_resolution.borrow().best_binding() { match binding.res() { // No disambiguation needed if the identically named item we @@ -1494,7 +1494,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return None; }; for (_, resolution) in this.resolutions(m).borrow().iter() { - let Some(binding) = resolution.borrow().binding else { + let Some(binding) = resolution.borrow().best_binding() else { continue; }; let Res::Def(DefKind::Macro(MacroKind::Derive | MacroKind::Attr), def_id) = diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 68fbe48ebcb..99297de40d5 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -13,7 +13,7 @@ use rustc_span::{Ident, Span, kw, sym}; use tracing::{debug, instrument}; use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; -use crate::imports::Import; +use crate::imports::{Import, NameResolution}; use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind}; use crate::macros::{MacroRulesScope, sub_namespace_match}; use crate::{ @@ -37,7 +37,7 @@ impl From<UsePrelude> for bool { } } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone, Copy)] enum Shadowing { Restricted, Unrestricted, @@ -875,57 +875,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // binding if it exists. What we really want here is having two separate scopes in // a module - one for non-globs and one for globs, but until that's done use this // hack to avoid inconsistent resolution ICEs during import validation. - let binding = [resolution.binding, resolution.shadowed_glob] + let binding = [resolution.non_glob_binding, resolution.glob_binding] .into_iter() .find_map(|binding| if binding == ignore_binding { None } else { binding }); - if let Some(Finalize { path_span, report_private, used, root_span, .. }) = finalize { - let Some(binding) = binding else { - return Err((Determined, Weak::No)); - }; - - if !self.is_accessible_from(binding.vis, parent_scope.module) { - if report_private { - self.privacy_errors.push(PrivacyError { - ident, - binding, - dedup_span: path_span, - outermost_res: None, - parent_scope: *parent_scope, - single_nested: path_span != root_span, - }); - } else { - return Err((Determined, Weak::No)); - } - } - - // Forbid expanded shadowing to avoid time travel. - if let Some(shadowed_glob) = resolution.shadowed_glob - && shadowing == Shadowing::Restricted - && binding.expansion != LocalExpnId::ROOT - && binding.res() != shadowed_glob.res() - { - self.ambiguity_errors.push(AmbiguityError { - kind: AmbiguityKind::GlobVsExpanded, - ident, - b1: binding, - b2: shadowed_glob, - warning: false, - misc1: AmbiguityErrorMisc::None, - misc2: AmbiguityErrorMisc::None, - }); - } - - if shadowing == Shadowing::Unrestricted - && binding.expansion != LocalExpnId::ROOT - && let NameBindingKind::Import { import, .. } = binding.kind - && matches!(import.kind, ImportKind::MacroExport) - { - self.macro_expanded_macro_export_errors.insert((path_span, binding.span)); - } - - self.record_use(ident, binding, used); - return Ok(binding); + if let Some(finalize) = finalize { + return self.finalize_module_binding( + ident, + binding, + if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None }, + parent_scope, + finalize, + shadowing, + ); } let check_usable = |this: &mut Self, binding: NameBinding<'ra>| { @@ -944,75 +906,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Check if one of single imports can still define the name, // if it can then our result is not determined and can be invalidated. - for single_import in &resolution.single_imports { - if ignore_import == Some(*single_import) { - // This branch handles a cycle in single imports. - // - // For example: - // ``` - // use a::b; - // use b as a; - // ``` - // 1. Record `use a::b` as the `ignore_import` and attempt to locate `a` in the - // current module. - // 2. Encounter the import `use b as a`, which is a `single_import` for `a`, - // and try to find `b` in the current module. - // 3. Re-encounter the `use a::b` import since it's a `single_import` of `b`. - // This leads to entering this branch. - continue; - } - if !self.is_accessible_from(single_import.vis, parent_scope.module) { - continue; - } - if let Some(ignored) = ignore_binding - && let NameBindingKind::Import { import, .. } = ignored.kind - && import == *single_import - { - // Ignore not just the binding itself, but if it has a shadowed_glob, - // ignore that, too, because this loop is supposed to only process - // named imports. - continue; - } - - let Some(module) = single_import.imported_module.get() else { - return Err((Undetermined, Weak::No)); - }; - let ImportKind::Single { source, target, target_bindings, .. } = &single_import.kind - else { - unreachable!(); - }; - if source != target { - // This branch allows the binding to be defined or updated later if the target name - // can hide the source. - if target_bindings.iter().all(|binding| binding.get().is_none()) { - // None of the target bindings are available, so we can't determine - // if this binding is correct or not. - // See more details in #124840 - return Err((Undetermined, Weak::No)); - } else if target_bindings[ns].get().is_none() && binding.is_some() { - // `binding.is_some()` avoids the condition where the binding - // truly doesn't exist in this namespace and should return `Err(Determined)`. - return Err((Undetermined, Weak::No)); - } - } - - match self.resolve_ident_in_module( - module, - *source, - ns, - &single_import.parent_scope, - None, - ignore_binding, - ignore_import, - ) { - Err((Determined, _)) => continue, - Ok(binding) - if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) => - { - continue; - } - Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::No)), - } + if self.single_import_can_define_name( + &resolution, + binding, + ns, + ignore_import, + ignore_binding, + parent_scope, + ) { + return Err((Undetermined, Weak::No)); } // So we have a resolution that's from a glob import. This resolution is determined @@ -1101,6 +1003,128 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Err((Determined, Weak::No)) } + fn finalize_module_binding( + &mut self, + ident: Ident, + binding: Option<NameBinding<'ra>>, + shadowed_glob: Option<NameBinding<'ra>>, + parent_scope: &ParentScope<'ra>, + finalize: Finalize, + shadowing: Shadowing, + ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> { + let Finalize { path_span, report_private, used, root_span, .. } = finalize; + + let Some(binding) = binding else { + return Err((Determined, Weak::No)); + }; + + if !self.is_accessible_from(binding.vis, parent_scope.module) { + if report_private { + self.privacy_errors.push(PrivacyError { + ident, + binding, + dedup_span: path_span, + outermost_res: None, + parent_scope: *parent_scope, + single_nested: path_span != root_span, + }); + } else { + return Err((Determined, Weak::No)); + } + } + + // Forbid expanded shadowing to avoid time travel. + if let Some(shadowed_glob) = shadowed_glob + && shadowing == Shadowing::Restricted + && binding.expansion != LocalExpnId::ROOT + && binding.res() != shadowed_glob.res() + { + self.ambiguity_errors.push(AmbiguityError { + kind: AmbiguityKind::GlobVsExpanded, + ident, + b1: binding, + b2: shadowed_glob, + warning: false, + misc1: AmbiguityErrorMisc::None, + misc2: AmbiguityErrorMisc::None, + }); + } + + if shadowing == Shadowing::Unrestricted + && binding.expansion != LocalExpnId::ROOT + && let NameBindingKind::Import { import, .. } = binding.kind + && matches!(import.kind, ImportKind::MacroExport) + { + self.macro_expanded_macro_export_errors.insert((path_span, binding.span)); + } + + self.record_use(ident, binding, used); + return Ok(binding); + } + + // Checks if a single import can define the `Ident` corresponding to `binding`. + // This is used to check whether we can definitively accept a glob as a resolution. + fn single_import_can_define_name( + &mut self, + resolution: &NameResolution<'ra>, + binding: Option<NameBinding<'ra>>, + ns: Namespace, + ignore_import: Option<Import<'ra>>, + ignore_binding: Option<NameBinding<'ra>>, + parent_scope: &ParentScope<'ra>, + ) -> bool { + for single_import in &resolution.single_imports { + if ignore_import == Some(*single_import) { + continue; + } + if !self.is_accessible_from(single_import.vis, parent_scope.module) { + continue; + } + if let Some(ignored) = ignore_binding + && let NameBindingKind::Import { import, .. } = ignored.kind + && import == *single_import + { + continue; + } + + let Some(module) = single_import.imported_module.get() else { + return true; + }; + let ImportKind::Single { source, target, bindings, .. } = &single_import.kind else { + unreachable!(); + }; + if source != target { + if bindings.iter().all(|binding| binding.get().binding().is_none()) { + return true; + } else if bindings[ns].get().binding().is_none() && binding.is_some() { + return true; + } + } + + match self.resolve_ident_in_module( + module, + *source, + ns, + &single_import.parent_scope, + None, + ignore_binding, + ignore_import, + ) { + Err((Determined, _)) => continue, + Ok(binding) + if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) => + { + continue; + } + Ok(_) | Err((Undetermined, _)) => { + return true; + } + } + } + + false + } + /// Validate a local resolution (from ribs). #[instrument(level = "debug", skip(self, all_ribs))] fn validate_res_from_ribs( diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 2e81b54b136..40c63a3edf3 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -24,7 +24,6 @@ use rustc_span::{Ident, Span, Symbol, kw, sym}; use smallvec::SmallVec; use tracing::debug; -use crate::Determinacy::{self, *}; use crate::Namespace::*; use crate::diagnostics::{DiagMode, Suggestion, import_candidates}; use crate::errors::{ @@ -33,13 +32,30 @@ use crate::errors::{ ConsiderAddingMacroExport, ConsiderMarkingAsPub, }; use crate::{ - AmbiguityError, AmbiguityKind, BindingKey, Finalize, ImportSuggestion, Module, + AmbiguityError, AmbiguityKind, BindingKey, Determinacy, Finalize, ImportSuggestion, Module, ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError, Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string, }; type Res = def::Res<NodeId>; +/// A [`NameBinding`] in the process of being resolved. +#[derive(Clone, Copy, Default, PartialEq)] +pub(crate) enum PendingBinding<'ra> { + Ready(Option<NameBinding<'ra>>), + #[default] + Pending, +} + +impl<'ra> PendingBinding<'ra> { + pub(crate) fn binding(self) -> Option<NameBinding<'ra>> { + match self { + PendingBinding::Ready(binding) => binding, + PendingBinding::Pending => None, + } + } +} + /// Contains data for specific kinds of imports. #[derive(Clone)] pub(crate) enum ImportKind<'ra> { @@ -49,10 +65,8 @@ pub(crate) enum ImportKind<'ra> { /// `target` in `use prefix::source as target`. /// It will directly use `source` when the format is `use prefix::source`. target: Ident, - /// Bindings to which `source` refers to. - source_bindings: PerNS<Cell<Result<NameBinding<'ra>, Determinacy>>>, - /// Bindings introduced by `target`. - target_bindings: PerNS<Cell<Option<NameBinding<'ra>>>>, + /// Bindings introduced by the import. + bindings: PerNS<Cell<PendingBinding<'ra>>>, /// `true` for `...::{self [as target]}` imports, `false` otherwise. type_ns_only: bool, /// Did this import result from a nested import? ie. `use foo::{bar, baz};` @@ -96,26 +110,14 @@ impl<'ra> std::fmt::Debug for ImportKind<'ra> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use ImportKind::*; match self { - Single { - source, - target, - source_bindings, - target_bindings, - type_ns_only, - nested, - id, - } => f + Single { source, target, bindings, type_ns_only, nested, id, .. } => f .debug_struct("Single") .field("source", source) .field("target", target) // Ignore the nested bindings to avoid an infinite loop while printing. .field( - "source_bindings", - &source_bindings.clone().map(|b| b.into_inner().map(|_| format_args!(".."))), - ) - .field( - "target_bindings", - &target_bindings.clone().map(|b| b.into_inner().map(|_| format_args!(".."))), + "bindings", + &bindings.clone().map(|b| b.into_inner().binding().map(|_| format_args!(".."))), ) .field("type_ns_only", type_ns_only) .field("nested", nested) @@ -242,15 +244,16 @@ pub(crate) struct NameResolution<'ra> { /// Single imports that may define the name in the namespace. /// Imports are arena-allocated, so it's ok to use pointers as keys. pub single_imports: FxIndexSet<Import<'ra>>, - /// The least shadowable known binding for this name, or None if there are no known bindings. - pub binding: Option<NameBinding<'ra>>, - pub shadowed_glob: Option<NameBinding<'ra>>, + /// The non-glob binding for this name, if it is known to exist. + pub non_glob_binding: Option<NameBinding<'ra>>, + /// The glob binding for this name, if it is known to exist. + pub glob_binding: Option<NameBinding<'ra>>, } impl<'ra> NameResolution<'ra> { /// Returns the binding for the name if it is known or None if it not known. pub(crate) fn binding(&self) -> Option<NameBinding<'ra>> { - self.binding.and_then(|binding| { + self.best_binding().and_then(|binding| { if !binding.is_glob_import() || self.single_imports.is_empty() { Some(binding) } else { @@ -258,6 +261,10 @@ impl<'ra> NameResolution<'ra> { } }) } + + pub(crate) fn best_binding(&self) -> Option<NameBinding<'ra>> { + self.non_glob_binding.or(self.glob_binding) + } } /// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved @@ -338,69 +345,71 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.check_reserved_macro_name(key.ident, res); self.set_binding_parent_module(binding, module); self.update_resolution(module, key, warn_ambiguity, |this, resolution| { - if let Some(old_binding) = resolution.binding { + if let Some(old_binding) = resolution.best_binding() { if res == Res::Err && old_binding.res() != Res::Err { // Do not override real bindings with `Res::Err`s from error recovery. return Ok(()); } match (old_binding.is_glob_import(), binding.is_glob_import()) { (true, true) => { + let (glob_binding, old_glob_binding) = (binding, old_binding); // FIXME: remove `!binding.is_ambiguity_recursive()` after delete the warning ambiguity. if !binding.is_ambiguity_recursive() && let NameBindingKind::Import { import: old_import, .. } = - old_binding.kind - && let NameBindingKind::Import { import, .. } = binding.kind + old_glob_binding.kind + && let NameBindingKind::Import { import, .. } = glob_binding.kind && old_import == import { - // We should replace the `old_binding` with `binding` regardless - // of whether they has same resolution or not when they are - // imported from the same glob-import statement. - resolution.binding = Some(binding); - } else if res != old_binding.res() { - resolution.binding = Some(this.new_ambiguity_binding( + // When imported from the same glob-import statement, we should replace + // `old_glob_binding` with `glob_binding`, regardless of whether + // they have the same resolution or not. + resolution.glob_binding = Some(glob_binding); + } else if res != old_glob_binding.res() { + resolution.glob_binding = Some(this.new_ambiguity_binding( AmbiguityKind::GlobVsGlob, - old_binding, - binding, + old_glob_binding, + glob_binding, warn_ambiguity, )); } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { // We are glob-importing the same item but with greater visibility. - resolution.binding = Some(binding); + resolution.glob_binding = Some(glob_binding); } else if binding.is_ambiguity_recursive() { - resolution.binding = Some(this.new_warn_ambiguity_binding(binding)); + resolution.glob_binding = + Some(this.new_warn_ambiguity_binding(glob_binding)); } } (old_glob @ true, false) | (old_glob @ false, true) => { - let (glob_binding, nonglob_binding) = + let (glob_binding, non_glob_binding) = if old_glob { (old_binding, binding) } else { (binding, old_binding) }; if key.ns == MacroNS - && nonglob_binding.expansion != LocalExpnId::ROOT - && glob_binding.res() != nonglob_binding.res() + && non_glob_binding.expansion != LocalExpnId::ROOT + && glob_binding.res() != non_glob_binding.res() { - resolution.binding = Some(this.new_ambiguity_binding( + resolution.non_glob_binding = Some(this.new_ambiguity_binding( AmbiguityKind::GlobVsExpanded, - nonglob_binding, + non_glob_binding, glob_binding, false, )); } else { - resolution.binding = Some(nonglob_binding); + resolution.non_glob_binding = Some(non_glob_binding); } - if let Some(old_shadowed_glob) = resolution.shadowed_glob { - assert!(old_shadowed_glob.is_glob_import()); - if glob_binding.res() != old_shadowed_glob.res() { - resolution.shadowed_glob = Some(this.new_ambiguity_binding( + if let Some(old_glob_binding) = resolution.glob_binding { + assert!(old_glob_binding.is_glob_import()); + if glob_binding.res() != old_glob_binding.res() { + resolution.glob_binding = Some(this.new_ambiguity_binding( AmbiguityKind::GlobVsGlob, - old_shadowed_glob, + old_glob_binding, glob_binding, false, )); - } else if !old_shadowed_glob.vis.is_at_least(binding.vis, this.tcx) { - resolution.shadowed_glob = Some(glob_binding); + } else if !old_glob_binding.vis.is_at_least(binding.vis, this.tcx) { + resolution.glob_binding = Some(glob_binding); } } else { - resolution.shadowed_glob = Some(glob_binding); + resolution.glob_binding = Some(glob_binding); } } (false, false) => { @@ -408,7 +417,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } } else { - resolution.binding = Some(binding); + if binding.is_glob_import() { + resolution.glob_binding = Some(binding); + } else { + resolution.non_glob_binding = Some(binding); + } } Ok(()) @@ -491,8 +504,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics. fn import_dummy_binding(&mut self, import: Import<'ra>, is_indeterminate: bool) { - if let ImportKind::Single { target, ref target_bindings, .. } = import.kind { - if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none())) + if let ImportKind::Single { target, ref bindings, .. } = import.kind { + if !(is_indeterminate + || bindings.iter().all(|binding| binding.get().binding().is_none())) { return; // Has resolution, do not create the dummy binding } @@ -567,10 +581,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { glob_error |= import.is_glob(); - if let ImportKind::Single { source, ref source_bindings, .. } = import.kind + if let ImportKind::Single { source, ref bindings, .. } = import.kind && source.name == kw::SelfLower // Silence `unresolved import` error if E0429 is already emitted - && let Err(Determined) = source_bindings.value_ns.get() + && let PendingBinding::Ready(None) = bindings.value_ns.get() { continue; } @@ -628,7 +642,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { for (key, resolution) in self.resolutions(*module).borrow().iter() { let resolution = resolution.borrow(); - let Some(binding) = resolution.binding else { continue }; + let Some(binding) = resolution.best_binding() else { continue }; if let NameBindingKind::Import { import, .. } = binding.kind && let Some((amb_binding, _)) = binding.ambiguity @@ -648,7 +662,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ); } - if let Some(glob_binding) = resolution.shadowed_glob { + if let Some(glob_binding) = resolution.glob_binding + && resolution.non_glob_binding.is_some() + { if binding.res() != Res::Err && glob_binding.res() != Res::Err && let NameBindingKind::Import { import: glob_import, .. } = @@ -819,15 +835,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; import.imported_module.set(Some(module)); - let (source, target, source_bindings, target_bindings, type_ns_only) = match import.kind { - ImportKind::Single { - source, - target, - ref source_bindings, - ref target_bindings, - type_ns_only, - .. - } => (source, target, source_bindings, target_bindings, type_ns_only), + let (source, target, bindings, type_ns_only) = match import.kind { + ImportKind::Single { source, target, ref bindings, type_ns_only, .. } => { + (source, target, bindings, type_ns_only) + } ImportKind::Glob { .. } => { self.resolve_glob_import(import); return 0; @@ -838,21 +849,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut indeterminate_count = 0; self.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { - if let Err(Undetermined) = source_bindings[ns].get() { - let binding = this.maybe_resolve_ident_in_module( - module, - source, - ns, - &import.parent_scope, - Some(import), - ); - source_bindings[ns].set(binding); - } else { + if bindings[ns].get() != PendingBinding::Pending { return; }; - + let binding_result = this.maybe_resolve_ident_in_module( + module, + source, + ns, + &import.parent_scope, + Some(import), + ); let parent = import.parent_scope.module; - match source_bindings[ns].get() { + let binding = match binding_result { Ok(binding) => { if binding.is_assoc_item() && !this.tcx.features().import_trait_associated_functions() @@ -865,12 +873,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) .emit(); } - + // We need the `target`, `source` can be extracted. let imported_binding = this.import(binding, import); - target_bindings[ns].set(Some(imported_binding)); this.define(parent, target, ns, imported_binding); + PendingBinding::Ready(Some(imported_binding)) } - Err(Determined) => { + Err(Determinacy::Determined) => { // Don't update the resolution for underscores, because it was never added. if target.name != kw::Underscore { let key = BindingKey::new(target, ns); @@ -878,9 +886,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { resolution.single_imports.swap_remove(&import); }); } + PendingBinding::Ready(None) } - Err(Undetermined) => indeterminate_count += 1, - } + Err(Determinacy::Undetermined) => { + indeterminate_count += 1; + PendingBinding::Pending + } + }; + bindings[ns].set(binding); } }); @@ -893,7 +906,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// consolidate multiple unresolved import errors into a single diagnostic. fn finalize_import(&mut self, import: Import<'ra>) -> Option<UnresolvedImportError> { let ignore_binding = match &import.kind { - ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(), + ImportKind::Single { bindings, .. } => bindings[TypeNS].get().binding(), _ => None, }; let ambiguity_errors_len = @@ -1011,60 +1024,53 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { PathResult::Indeterminate => unreachable!(), }; - let (ident, target, source_bindings, target_bindings, type_ns_only, import_id) = - match import.kind { - ImportKind::Single { - source, - target, - ref source_bindings, - ref target_bindings, - type_ns_only, - id, - .. - } => (source, target, source_bindings, target_bindings, type_ns_only, id), - ImportKind::Glob { is_prelude, ref max_vis, id } => { - if import.module_path.len() <= 1 { - // HACK(eddyb) `lint_if_path_starts_with_module` needs at least - // 2 segments, so the `resolve_path` above won't trigger it. - let mut full_path = import.module_path.clone(); - full_path.push(Segment::from_ident(Ident::dummy())); - self.lint_if_path_starts_with_module(Some(finalize), &full_path, None); - } + let (ident, target, bindings, type_ns_only, import_id) = match import.kind { + ImportKind::Single { source, target, ref bindings, type_ns_only, id, .. } => { + (source, target, bindings, type_ns_only, id) + } + ImportKind::Glob { is_prelude, ref max_vis, id } => { + if import.module_path.len() <= 1 { + // HACK(eddyb) `lint_if_path_starts_with_module` needs at least + // 2 segments, so the `resolve_path` above won't trigger it. + let mut full_path = import.module_path.clone(); + full_path.push(Segment::from_ident(Ident::dummy())); + self.lint_if_path_starts_with_module(Some(finalize), &full_path, None); + } - if let ModuleOrUniformRoot::Module(module) = module - && module == import.parent_scope.module - { - // Importing a module into itself is not allowed. - return Some(UnresolvedImportError { + if let ModuleOrUniformRoot::Module(module) = module + && module == import.parent_scope.module + { + // Importing a module into itself is not allowed. + return Some(UnresolvedImportError { + span: import.span, + label: Some(String::from("cannot glob-import a module into itself")), + note: None, + suggestion: None, + candidates: None, + segment: None, + module: None, + }); + } + if !is_prelude + && let Some(max_vis) = max_vis.get() + && !max_vis.is_at_least(import.vis, self.tcx) + { + let def_id = self.local_def_id(id); + self.lint_buffer.buffer_lint( + UNUSED_IMPORTS, + id, + import.span, + BuiltinLintDiag::RedundantImportVisibility { + max_vis: max_vis.to_string(def_id, self.tcx), + import_vis: import.vis.to_string(def_id, self.tcx), span: import.span, - label: Some(String::from("cannot glob-import a module into itself")), - note: None, - suggestion: None, - candidates: None, - segment: None, - module: None, - }); - } - if !is_prelude - && let Some(max_vis) = max_vis.get() - && !max_vis.is_at_least(import.vis, self.tcx) - { - let def_id = self.local_def_id(id); - self.lint_buffer.buffer_lint( - UNUSED_IMPORTS, - id, - import.span, - BuiltinLintDiag::RedundantImportVisibility { - max_vis: max_vis.to_string(def_id, self.tcx), - import_vis: import.vis.to_string(def_id, self.tcx), - span: import.span, - }, - ); - } - return None; + }, + ); } - _ => unreachable!(), - }; + return None; + } + _ => unreachable!(), + }; if self.privacy_errors.len() != privacy_errors_len { // Get the Res for the last element, so that we can point to alternative ways of @@ -1095,17 +1101,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns, &import.parent_scope, Some(Finalize { report_private: false, ..finalize }), - target_bindings[ns].get(), + bindings[ns].get().binding(), Some(import), ); match binding { Ok(binding) => { // Consistency checks, analogous to `finalize_macro_resolutions`. - let initial_res = source_bindings[ns].get().map(|initial_binding| { + let initial_res = bindings[ns].get().binding().map(|binding| { + let initial_binding = binding.import_source(); all_ns_err = false; - if let Some(target_binding) = target_bindings[ns].get() - && target.name == kw::Underscore + if target.name == kw::Underscore && initial_binding.is_extern_crate() && !initial_binding.is_import() { @@ -1114,7 +1120,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } else { Used::Other }; - this.record_use(ident, target_binding, used); + this.record_use(ident, binding, used); } initial_binding.res() }); @@ -1126,7 +1132,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .span_delayed_bug(import.span, "some error happened for an import"); return; } - if let Ok(initial_res) = initial_res { + if let Some(initial_res) = initial_res { if res != initial_res { span_bug!(import.span, "inconsistent resolution for an import"); } @@ -1179,7 +1185,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return None; } // Never suggest the same name match *resolution.borrow() { - NameResolution { binding: Some(name_binding), .. } => { + ref resolution + if let Some(name_binding) = resolution.best_binding() => + { match name_binding.kind { NameBindingKind::Import { binding, .. } => { match binding.kind { @@ -1269,7 +1277,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut any_successful_reexport = false; let mut crate_private_reexport = false; self.per_ns(|this, ns| { - let Ok(binding) = source_bindings[ns].get() else { + let Some(binding) = bindings[ns].get().binding().map(|b| b.import_source()) else { return; }; @@ -1340,7 +1348,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(ident)); self.per_ns(|this, ns| { - if let Ok(binding) = source_bindings[ns].get() { + if let Some(binding) = bindings[ns].get().binding().map(|b| b.import_source()) { this.lint_if_path_starts_with_module(Some(finalize), &full_path, Some(binding)); } }); @@ -1350,7 +1358,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // this may resolve to either a value or a type, but for documentation // purposes it's good enough to just favor one over the other. self.per_ns(|this, ns| { - if let Ok(binding) = source_bindings[ns].get() { + if let Some(binding) = bindings[ns].get().binding().map(|b| b.import_source()) { this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res()); } }); @@ -1361,10 +1369,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> bool { // This function is only called for single imports. - let ImportKind::Single { - source, target, ref source_bindings, ref target_bindings, id, .. - } = import.kind - else { + let ImportKind::Single { source, target, ref bindings, id, .. } = import.kind else { unreachable!() }; @@ -1391,7 +1396,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut is_redundant = true; let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None }; self.per_ns(|this, ns| { - if is_redundant && let Ok(binding) = source_bindings[ns].get() { + let binding = bindings[ns].get().binding().map(|b| b.import_source()); + if is_redundant && let Some(binding) = binding { if binding.res() == Res::Err { return; } @@ -1402,7 +1408,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &import.parent_scope, None, false, - target_bindings[ns].get(), + bindings[ns].get().binding(), None, ) { Ok(other_binding) => { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 08629090bb1..44a567f7810 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3437,7 +3437,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }; ident.span.normalize_to_macros_2_0_and_adjust(module.expansion); let key = BindingKey::new(ident, ns); - let mut binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding); + let mut binding = + self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.best_binding()); debug!(?binding); if binding.is_none() { // We could not find the trait item in the correct namespace. @@ -3448,7 +3449,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { _ => ns, }; let key = BindingKey::new(ident, ns); - binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding); + binding = + self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.best_binding()); debug!(?binding); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 8114021510e..b669796bb02 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -880,8 +880,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn lookup_doc_alias_name(&mut self, path: &[Segment], ns: Namespace) -> Option<(DefId, Ident)> { let find_doc_alias_name = |r: &mut Resolver<'ra, '_>, m: Module<'ra>, item_name: Symbol| { for resolution in r.resolutions(m).borrow().values() { - let Some(did) = - resolution.borrow().binding.and_then(|binding| binding.res().opt_def_id()) + let Some(did) = resolution + .borrow() + .best_binding() + .and_then(|binding| binding.res().opt_def_id()) else { continue; }; @@ -1464,15 +1466,16 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { self.resolve_path(mod_path, None, None) { let resolutions = self.r.resolutions(module).borrow(); - let targets: Vec<_> = - resolutions - .iter() - .filter_map(|(key, resolution)| { - resolution.borrow().binding.map(|binding| binding.res()).and_then( - |res| if filter_fn(res) { Some((key, res)) } else { None }, - ) - }) - .collect(); + let targets: Vec<_> = resolutions + .iter() + .filter_map(|(key, resolution)| { + resolution + .borrow() + .best_binding() + .map(|binding| binding.res()) + .and_then(|res| if filter_fn(res) { Some((key, res)) } else { None }) + }) + .collect(); if let [target] = targets.as_slice() { return Some(TypoSuggestion::single_item_from_ident(target.0.ident, target.1)); } @@ -2305,7 +2308,9 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let targets = resolutions .borrow() .iter() - .filter_map(|(key, res)| res.borrow().binding.map(|binding| (key, binding.res()))) + .filter_map(|(key, res)| { + res.borrow().best_binding().map(|binding| (key, binding.res())) + }) .filter(|(_, res)| match (kind, res) { (AssocItemKind::Const(..), Res::Def(DefKind::AssocConst, _)) => true, (AssocItemKind::Fn(_), Res::Def(DefKind::AssocFn, _)) => true, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6e4c5ef1909..f8d1b6783e3 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -641,7 +641,7 @@ impl<'ra> Module<'ra> { F: FnMut(&mut R, Ident, Namespace, NameBinding<'ra>), { for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() { - if let Some(binding) = name_resolution.borrow().binding { + if let Some(binding) = name_resolution.borrow().best_binding() { f(resolver, key.ident, key.ns, binding); } } @@ -891,6 +891,13 @@ impl<'ra> NameBindingData<'ra> { } } + fn import_source(&self) -> NameBinding<'ra> { + match self.kind { + NameBindingKind::Import { binding, .. } => binding, + _ => unreachable!(), + } + } + fn is_ambiguity_recursive(&self) -> bool { self.ambiguity.is_some() || match self.kind { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 89bbe8dad98..5864b035f73 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -24,7 +24,7 @@ use rustc_middle::middle::stability; use rustc_middle::ty::{RegisteredTools, TyCtxt, Visibility}; use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::{ - LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_DIAGNOSTIC_ATTRIBUTES, UNUSED_MACRO_RULES, UNUSED_MACROS, }; use rustc_session::parse::feature_err; @@ -689,7 +689,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ); self.tcx.sess.psess.buffer_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + UNKNOWN_DIAGNOSTIC_ATTRIBUTES, attribute.span(), node_id, BuiltinLintDiag::UnknownDiagnosticAttribute { span: attribute.span(), typo_name }, diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 29be3b73ee9..c3080875da8 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1191,11 +1191,6 @@ impl AstPass { /// The kind of compiler desugaring. #[derive(Clone, Copy, PartialEq, Debug, Encodable, Decodable, HashStable_Generic)] pub enum DesugaringKind { - /// We desugar `if c { i } else { e }` to `match $ExprKind::Use(c) { true => i, _ => e }`. - /// However, we do not want to blame `c` for unreachability but rather say that `i` - /// is unreachable. This desugaring kind allows us to avoid blaming `c`. - /// This also applies to `while` loops. - CondTemporary, QuestionMark, TryBlock, YeetExpr, @@ -1230,7 +1225,6 @@ impl DesugaringKind { /// The description wording should combine well with "desugaring of {}". pub fn descr(self) -> &'static str { match self { - DesugaringKind::CondTemporary => "`if` or `while` condition", DesugaringKind::Async => "`async` block or function", DesugaringKind::Await => "`await` expression", DesugaringKind::QuestionMark => "operator `?`", @@ -1253,7 +1247,6 @@ impl DesugaringKind { /// like `from_desugaring = "QuestionMark"` pub fn matches(&self, value: &str) -> bool { match self { - DesugaringKind::CondTemporary => value == "CondTemporary", DesugaringKind::Async => value == "Async", DesugaringKind::Await => value == "Await", DesugaringKind::QuestionMark => value == "QuestionMark", diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4df91cc3429..8b12edf426c 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -624,6 +624,7 @@ symbols! { cfg_relocation_model, cfg_sanitize, cfg_sanitizer_cfi, + cfg_select, cfg_target_abi, cfg_target_compact, cfg_target_feature, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index bff5e9128cb..db35c988bf7 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -841,54 +841,32 @@ fn foo(&self) -> Self::T { String::new() } let param_env = tcx.param_env(body_owner_def_id); - match item { - hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., items), .. }) => { - // FIXME: account for `#![feature(specialization)]` - for item in &items[..] { - match item.kind { - hir::AssocItemKind::Type => { - // FIXME: account for returning some type in a trait fn impl that has - // an assoc type as a return type (#72076). - if let hir::Defaultness::Default { has_value: true } = - tcx.defaultness(item.id.owner_id) - { - let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity(); - if self.infcx.can_eq(param_env, assoc_ty, found) { - diag.span_label( - item.span, - "associated type defaults can't be assumed inside the \ - trait defining them", - ); - return true; - } - } + if let DefKind::Trait | DefKind::Impl { .. } = tcx.def_kind(parent_id) { + let assoc_items = tcx.associated_items(parent_id); + // FIXME: account for `#![feature(specialization)]` + for assoc_item in assoc_items.in_definition_order() { + if assoc_item.is_type() + // FIXME: account for returning some type in a trait fn impl that has + // an assoc type as a return type (#72076). + && let hir::Defaultness::Default { has_value: true } = assoc_item.defaultness(tcx) + && let assoc_ty = tcx.type_of(assoc_item.def_id).instantiate_identity() + && self.infcx.can_eq(param_env, assoc_ty, found) + { + let msg = match assoc_item.container { + ty::AssocItemContainer::Trait => { + "associated type defaults can't be assumed inside the \ + trait defining them" } - _ => {} - } - } - } - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { items, .. }), - .. - }) => { - for item in &items[..] { - if let hir::AssocItemKind::Type = item.kind { - let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity(); - if let hir::Defaultness::Default { has_value: true } = - tcx.defaultness(item.id.owner_id) - && self.infcx.can_eq(param_env, assoc_ty, found) - { - diag.span_label( - item.span, - "associated type is `default` and may be overridden", - ); - return true; + ty::AssocItemContainer::Impl => { + "associated type is `default` and may be overridden" } - } + }; + diag.span_label(tcx.def_span(assoc_item.def_id), msg); + return true; } } - _ => {} } + false } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index a8ba1baf6b9..712e88300ff 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -362,7 +362,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && self.tcx.trait_of_item(*item_id) == Some(*trait_id) && let None = self.tainted_by_errors() { - let (verb, noun) = match self.tcx.associated_item(item_id).kind { + let assoc_item = self.tcx.associated_item(item_id); + let (verb, noun) = match assoc_item.kind { ty::AssocKind::Const { .. } => ("refer to the", "constant"), ty::AssocKind::Fn { .. } => ("call", "function"), // This is already covered by E0223, but this following single match @@ -381,17 +382,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); err.code(E0790); - if let Some(local_def_id) = data.trait_ref.def_id.as_local() - && let hir::Node::Item(hir::Item { - kind: hir::ItemKind::Trait(_, _, trait_ident, _, _, trait_item_refs), - .. - }) = self.tcx.hir_node_by_def_id(local_def_id) - && let Some(method_ref) = trait_item_refs - .iter() - .find(|item_ref| item_ref.ident == *assoc_item_ident) - { + if item_id.is_local() { + let trait_ident = self.tcx.item_name(*trait_id); err.span_label( - method_ref.span, + self.tcx.def_span(*item_id), format!("`{trait_ident}::{assoc_item_ident}` defined here"), ); } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index a52dbedfe1e..2344bc79f21 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -11,7 +11,9 @@ use rustc_macros::LintDiagnostic; use rustc_middle::bug; use rustc_middle::ty::print::PrintTraitRefExt; use rustc_middle::ty::{self, GenericArgsRef, GenericParamDef, GenericParamDefKind, TyCtxt}; -use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES; +use rustc_session::lint::builtin::{ + MALFORMED_DIAGNOSTIC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, +}; use rustc_span::{Span, Symbol, sym}; use tracing::{debug, info}; @@ -382,7 +384,7 @@ impl IgnoredDiagnosticOption { if let (Some(new_item), Some(old_item)) = (new, old) { if let Some(item_def_id) = item_def_id.as_local() { tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), new_item, IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name }, @@ -533,7 +535,7 @@ impl<'tcx> OnUnimplementedDirective { if is_diagnostic_namespace_variant { if let Some(def_id) = item_def_id.as_local() { tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(def_id), vec![item.span()], MalformedOnUnimplementedAttrLint::new(item.span()), @@ -689,7 +691,7 @@ impl<'tcx> OnUnimplementedDirective { if let Some(item_def_id) = item_def_id.as_local() { tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), report_span, MalformedOnUnimplementedAttrLint::new(report_span), @@ -702,7 +704,7 @@ impl<'tcx> OnUnimplementedDirective { Attribute::Unparsed(p) if !matches!(p.args, AttrArgs::Empty) => { if let Some(item_def_id) = item_def_id.as_local() { tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), attr.span(), MalformedOnUnimplementedAttrLint::new(attr.span()), @@ -712,7 +714,7 @@ impl<'tcx> OnUnimplementedDirective { _ => { if let Some(item_def_id) = item_def_id.as_local() { tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), attr.span(), MissingOptionsForOnUnimplementedAttr, @@ -859,7 +861,7 @@ impl<'tcx> OnUnimplementedFormatString { if self.is_diagnostic_namespace_variant { if let Some(trait_def_id) = trait_def_id.as_local() { tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, tcx.local_def_id_to_hir_id(trait_def_id), self.span, WrappedParserError { description: e.description, label: e.label }, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs index 3e8b906fa93..1954f8a1f63 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::{GenericParamDefKind, TyCtxt}; use rustc_parse_format::{ Argument, FormatSpec, ParseError, ParseMode, Parser, Piece as RpfPiece, Position, }; -use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES; +use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_FORMAT_LITERALS; use rustc_span::def_id::DefId; use rustc_span::{InnerSpan, Span, Symbol, kw, sym}; @@ -69,7 +69,7 @@ impl FormatWarning { let this = tcx.item_ident(item_def_id); if let Some(item_def_id) = item_def_id.as_local() { tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, tcx.local_def_id_to_hir_id(item_def_id), span, UnknownFormatParameterForOnUnimplementedAttr { @@ -82,7 +82,7 @@ impl FormatWarning { FormatWarning::PositionalArgument { span, .. } => { if let Some(item_def_id) = item_def_id.as_local() { tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, tcx.local_def_id_to_hir_id(item_def_id), span, DisallowedPositionalArgument, @@ -92,7 +92,7 @@ impl FormatWarning { FormatWarning::InvalidSpecifier { span, .. } => { if let Some(item_def_id) = item_def_id.as_local() { tcx.emit_node_span_lint( - UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, tcx.local_def_id_to_hir_id(item_def_id), span, InvalidFormatSpecifier, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 3e64573aa03..bd1d29826e6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1321,7 +1321,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref); let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); - let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = + let (ref_inner_ty_satisfies_pred, ref_inner_ty_is_mut) = if let ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code() && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() { @@ -1333,117 +1333,139 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (false, false) }; - if imm_ref_self_ty_satisfies_pred - || mut_ref_self_ty_satisfies_pred - || ref_inner_ty_satisfies_pred - { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - // We don't want a borrowing suggestion on the fields in structs, - // ``` - // struct Foo { - // the_foos: Vec<Foo> - // } - // ``` - if !matches!( - span.ctxt().outer_expn_data().kind, - ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) - ) { - return false; - } - if snippet.starts_with('&') { - // This is already a literal borrow and the obligation is failing - // somewhere else in the obligation chain. Do not suggest non-sense. - return false; - } - // We have a very specific type of error, where just borrowing this argument - // might solve the problem. In cases like this, the important part is the - // original type obligation, not the last one that failed, which is arbitrary. - // Because of this, we modify the error to refer to the original obligation and - // return early in the caller. - - let msg = format!( - "the trait bound `{}` is not satisfied", - self.tcx.short_string(old_pred, err.long_ty_path()), - ); - let self_ty_str = - self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path()); - if has_custom_message { - err.note(msg); - } else { - err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)]; - } - err.span_label( - span, - format!( - "the trait `{}` is not implemented for `{self_ty_str}`", - old_pred.print_modifiers_and_trait_path() - ), - ); + let is_immut = imm_ref_self_ty_satisfies_pred + || (ref_inner_ty_satisfies_pred && !ref_inner_ty_is_mut); + let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_is_mut; + if !is_immut && !is_mut { + return false; + } + let Ok(_snippet) = self.tcx.sess.source_map().span_to_snippet(span) else { + return false; + }; + // We don't want a borrowing suggestion on the fields in structs + // ``` + // #[derive(Clone)] + // struct Foo { + // the_foos: Vec<Foo> + // } + // ``` + if !matches!( + span.ctxt().outer_expn_data().kind, + ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) + ) { + return false; + } + // We have a very specific type of error, where just borrowing this argument + // might solve the problem. In cases like this, the important part is the + // original type obligation, not the last one that failed, which is arbitrary. + // Because of this, we modify the error to refer to the original obligation and + // return early in the caller. - if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred { - err.span_suggestions( - span.shrink_to_lo(), - "consider borrowing here", - ["&".to_string(), "&mut ".to_string()], - Applicability::MaybeIncorrect, - ); - } else { - let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut; - let sugg_prefix = format!("&{}", if is_mut { "mut " } else { "" }); - let sugg_msg = format!( - "consider{} borrowing here", - if is_mut { " mutably" } else { "" } - ); + let mut label = || { + let msg = format!( + "the trait bound `{}` is not satisfied", + self.tcx.short_string(old_pred, err.long_ty_path()), + ); + let self_ty_str = + self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path()); + if has_custom_message { + err.note(msg); + } else { + err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)]; + } + err.span_label( + span, + format!( + "the trait `{}` is not implemented for `{self_ty_str}`", + old_pred.print_modifiers_and_trait_path() + ), + ); + }; - // Issue #109436, we need to add parentheses properly for method calls - // for example, `foo.into()` should be `(&foo).into()` - if let Some(_) = - self.tcx.sess.source_map().span_look_ahead(span, ".", Some(50)) - { - err.multipart_suggestion_verbose( - sugg_msg, - vec![ - (span.shrink_to_lo(), format!("({sugg_prefix}")), - (span.shrink_to_hi(), ")".to_string()), - ], - Applicability::MaybeIncorrect, - ); - return true; - } + let mut sugg_prefixes = vec![]; + if is_immut { + sugg_prefixes.push("&"); + } + if is_mut { + sugg_prefixes.push("&mut "); + } + let sugg_msg = format!( + "consider{} borrowing here", + if is_mut && !is_immut { " mutably" } else { "" }, + ); - // Issue #104961, we need to add parentheses properly for compound expressions - // for example, `x.starts_with("hi".to_string() + "you")` - // should be `x.starts_with(&("hi".to_string() + "you"))` - let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) - else { - return false; - }; - let mut expr_finder = FindExprBySpan::new(span, self.tcx); - expr_finder.visit_expr(body.value); - let Some(expr) = expr_finder.result else { - return false; - }; - let needs_parens = expr_needs_parens(expr); + // Issue #104961, we need to add parentheses properly for compound expressions + // for example, `x.starts_with("hi".to_string() + "you")` + // should be `x.starts_with(&("hi".to_string() + "you"))` + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { + return false; + }; + let mut expr_finder = FindExprBySpan::new(span, self.tcx); + expr_finder.visit_expr(body.value); - let span = if needs_parens { span } else { span.shrink_to_lo() }; - let suggestions = if !needs_parens { - vec![(span.shrink_to_lo(), sugg_prefix)] - } else { + if let Some(ty) = expr_finder.ty_result { + if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(ty.hir_id) + && let hir::ExprKind::Path(hir::QPath::TypeRelative(_, _)) = expr.kind + && ty.span == span + { + // We've encountered something like `str::from("")`, where the intended code + // was likely `<&str>::from("")`. #143393. + label(); + err.multipart_suggestions( + sugg_msg, + sugg_prefixes.into_iter().map(|sugg_prefix| { vec![ - (span.shrink_to_lo(), format!("{sugg_prefix}(")), - (span.shrink_to_hi(), ")".to_string()), + (span.shrink_to_lo(), format!("<{sugg_prefix}")), + (span.shrink_to_hi(), ">".to_string()), ] - }; - err.multipart_suggestion_verbose( - sugg_msg, - suggestions, - Applicability::MaybeIncorrect, - ); - } + }), + Applicability::MaybeIncorrect, + ); return true; } + return false; } - return false; + let Some(expr) = expr_finder.result else { + return false; + }; + if let hir::ExprKind::AddrOf(_, _, _) = expr.kind { + return false; + } + let needs_parens_post = expr_needs_parens(expr); + let needs_parens_pre = match self.tcx.parent_hir_node(expr.hir_id) { + Node::Expr(e) + if let hir::ExprKind::MethodCall(_, base, _, _) = e.kind + && base.hir_id == expr.hir_id => + { + true + } + _ => false, + }; + + label(); + let suggestions = sugg_prefixes.into_iter().map(|sugg_prefix| { + match (needs_parens_pre, needs_parens_post) { + (false, false) => vec![(span.shrink_to_lo(), sugg_prefix.to_string())], + // We have something like `foo.bar()`, where we want to bororw foo, so we need + // to suggest `(&mut foo).bar()`. + (false, true) => vec![ + (span.shrink_to_lo(), format!("{sugg_prefix}(")), + (span.shrink_to_hi(), ")".to_string()), + ], + // Issue #109436, we need to add parentheses properly for method calls + // for example, `foo.into()` should be `(&foo).into()` + (true, false) => vec![ + (span.shrink_to_lo(), format!("({sugg_prefix}")), + (span.shrink_to_hi(), ")".to_string()), + ], + (true, true) => vec![ + (span.shrink_to_lo(), format!("({sugg_prefix}(")), + (span.shrink_to_hi(), "))".to_string()), + ], + } + }); + err.multipart_suggestions(sugg_msg, suggestions, Applicability::MaybeIncorrect); + return true; }; if let ObligationCauseCode::ImplDerived(cause) = &*code { @@ -3697,6 +3719,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); suggest_remove_deref(err, &expr); } + ObligationCauseCode::UnsizedNonPlaceExpr(span) => { + err.span_note( + span, + "unsized values must be place expressions and cannot be put in temporaries", + ); + } } } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index d4e6a23f0eb..fed9f254cdf 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -288,9 +288,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( && let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id) && let Some(impl_item) = - items.iter().find(|item| item.id.owner_id.to_def_id() == impl_item_id) + items.iter().find(|item| item.owner_id.to_def_id() == impl_item_id) { - Some(tcx.hir_impl_item(impl_item.id).expect_type().span) + Some(tcx.hir_impl_item(*impl_item).expect_type().span) } else { None } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 6a9461f2b43..37cb64511c7 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -1,18 +1,20 @@ -use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::definitions::{DefPathData, DisambiguatorState}; use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::{self as hir, ItemKind}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; use rustc_middle::{bug, span_bug}; +use rustc_span::Ident; +use rustc_span::symbol::kw; pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { associated_item, associated_item_def_ids, associated_items, - associated_types_for_impl_traits_in_associated_fn, + associated_types_for_impl_traits_in_trait_or_impl, impl_item_implementor_ids, ..*providers }; @@ -22,54 +24,28 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { let item = tcx.hir_expect_item(def_id); match item.kind { hir::ItemKind::Trait(.., trait_item_refs) => { - // We collect RPITITs for each trait method's return type and create a - // corresponding associated item using associated_types_for_impl_traits_in_associated_fn + // We collect RPITITs for each trait method's return type and create a corresponding + // associated item using the associated_types_for_impl_traits_in_trait_or_impl // query. - tcx.arena.alloc_from_iter( - trait_item_refs - .iter() - .map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id()) - .chain( - trait_item_refs - .iter() - .filter(|trait_item_ref| { - matches!(trait_item_ref.kind, hir::AssocItemKind::Fn { .. }) - }) - .flat_map(|trait_item_ref| { - let trait_fn_def_id = trait_item_ref.id.owner_id.def_id.to_def_id(); - tcx.associated_types_for_impl_traits_in_associated_fn( - trait_fn_def_id, - ) - }) - .copied(), - ), - ) + let rpitit_items = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id); + tcx.arena.alloc_from_iter(trait_item_refs.iter().flat_map(|trait_item_ref| { + let item_def_id = trait_item_ref.owner_id.to_def_id(); + [item_def_id] + .into_iter() + .chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied()) + })) } hir::ItemKind::Impl(impl_) => { // We collect RPITITs for each trait method's return type, on the impl side too and // create a corresponding associated item using - // associated_types_for_impl_traits_in_associated_fn query. - tcx.arena.alloc_from_iter( - impl_ - .items - .iter() - .map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()) - .chain(impl_.of_trait.iter().flat_map(|_| { - impl_ - .items - .iter() - .filter(|impl_item_ref| { - matches!(impl_item_ref.kind, hir::AssocItemKind::Fn { .. }) - }) - .flat_map(|impl_item_ref| { - let impl_fn_def_id = impl_item_ref.id.owner_id.def_id.to_def_id(); - tcx.associated_types_for_impl_traits_in_associated_fn( - impl_fn_def_id, - ) - }) - .copied() - })), - ) + // associated_types_for_impl_traits_in_trait_or_impl query. + let rpitit_items = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id); + tcx.arena.alloc_from_iter(impl_.items.iter().flat_map(|impl_item_ref| { + let item_def_id = impl_item_ref.owner_id.to_def_id(); + [item_def_id] + .into_iter() + .chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied()) + })) } _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), } @@ -92,46 +68,33 @@ fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap<DefId> } fn associated_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AssocItem { - let id = tcx.local_def_id_to_hir_id(def_id); - let parent_def_id = tcx.hir_get_parent_item(id); - let parent_item = tcx.hir_expect_item(parent_def_id.def_id); - match parent_item.kind { - hir::ItemKind::Impl(impl_) => { - if let Some(impl_item_ref) = impl_.items.iter().find(|i| i.id.owner_id.def_id == def_id) - { - let assoc_item = associated_item_from_impl_item_ref(impl_item_ref); - debug_assert_eq!(assoc_item.def_id.expect_local(), def_id); - return assoc_item; - } - } - - hir::ItemKind::Trait(.., trait_item_refs) => { - if let Some(trait_item_ref) = - trait_item_refs.iter().find(|i| i.id.owner_id.def_id == def_id) - { - let assoc_item = associated_item_from_trait_item_ref(trait_item_ref); - debug_assert_eq!(assoc_item.def_id.expect_local(), def_id); - return assoc_item; - } - } - - _ => {} - } + let assoc_item = match tcx.hir_node_by_def_id(def_id) { + hir::Node::TraitItem(ti) => associated_item_from_trait_item(tcx, ti), + hir::Node::ImplItem(ii) => associated_item_from_impl_item(tcx, ii), + node => span_bug!(tcx.def_span(def_id), "impl item or item not found: {:?}", node,), + }; + debug_assert_eq!(assoc_item.def_id.expect_local(), def_id); + assoc_item +} - span_bug!( - parent_item.span, - "unexpected parent of trait or impl item or item not found: {:?}", - parent_item.kind - ) +fn fn_has_self_parameter(tcx: TyCtxt<'_>, owner_id: hir::OwnerId) -> bool { + matches!(tcx.fn_arg_idents(owner_id.def_id), [Some(Ident { name: kw::SelfLower, .. }), ..]) } -fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty::AssocItem { - let owner_id = trait_item_ref.id.owner_id; - let name = trait_item_ref.ident.name; - let kind = match trait_item_ref.kind { - hir::AssocItemKind::Const => ty::AssocKind::Const { name }, - hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { name, has_self }, - hir::AssocItemKind::Type => ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) }, +fn associated_item_from_trait_item( + tcx: TyCtxt<'_>, + trait_item: &hir::TraitItem<'_>, +) -> ty::AssocItem { + let owner_id = trait_item.owner_id; + let name = trait_item.ident.name; + let kind = match trait_item.kind { + hir::TraitItemKind::Const { .. } => ty::AssocKind::Const { name }, + hir::TraitItemKind::Fn { .. } => { + ty::AssocKind::Fn { name, has_self: fn_has_self_parameter(tcx, owner_id) } + } + hir::TraitItemKind::Type { .. } => { + ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) } + } }; ty::AssocItem { @@ -142,30 +105,34 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty } } -fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::AssocItem { - let def_id = impl_item_ref.id.owner_id; - let name = impl_item_ref.ident.name; - let kind = match impl_item_ref.kind { - hir::AssocItemKind::Const => ty::AssocKind::Const { name }, - hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { name, has_self }, - hir::AssocItemKind::Type => ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) }, +fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) -> ty::AssocItem { + let owner_id = impl_item.owner_id; + let name = impl_item.ident.name; + let kind = match impl_item.kind { + hir::ImplItemKind::Const { .. } => ty::AssocKind::Const { name }, + hir::ImplItemKind::Fn { .. } => { + ty::AssocKind::Fn { name, has_self: fn_has_self_parameter(tcx, owner_id) } + } + hir::ImplItemKind::Type { .. } => { + ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) } + } }; ty::AssocItem { kind, - def_id: def_id.to_def_id(), - trait_item_def_id: impl_item_ref.trait_item_def_id, + def_id: owner_id.to_def_id(), + trait_item_def_id: impl_item.trait_item_def_id, container: ty::AssocItemContainer::Impl, } } -struct RPITVisitor<'tcx> { +struct RPITVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, synthetics: Vec<LocalDefId>, data: DefPathData, - disambiguator: DisambiguatorState, + disambiguator: &'a mut DisambiguatorState, } -impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> { +impl<'tcx> Visitor<'tcx> for RPITVisitor<'_, 'tcx> { fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result { self.synthetics.push(associated_type_for_impl_trait_in_trait( self.tcx, @@ -177,100 +144,70 @@ impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> { } } -struct DisambiguatorIdxVisitor { - depth: u32, -} - -impl<'tcx> Visitor<'tcx> for DisambiguatorIdxVisitor { - fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result { - self.depth += 1; - intravisit::walk_opaque_ty(self, opaque) - } -} - -/// Given an `fn_def_id` of a trait or a trait implementation: -/// -/// if `fn_def_id` is a function defined inside a trait, then it synthesizes -/// a new def id corresponding to a new associated type for each return- -/// position `impl Trait` in the signature. -/// -/// if `fn_def_id` is a function inside of an impl, then for each synthetic -/// associated type generated for the corresponding trait function described -/// above, synthesize a corresponding associated type in the impl. -fn associated_types_for_impl_traits_in_associated_fn( - tcx: TyCtxt<'_>, - fn_def_id: LocalDefId, -) -> &'_ [DefId] { - let parent_def_id = tcx.local_parent(fn_def_id); - - match tcx.def_kind(parent_def_id) { - DefKind::Trait => { - if let Some(output) = tcx.hir_get_fn_output(fn_def_id) { - let def_path_id = |def_id: LocalDefId| tcx.item_name(def_id.to_def_id()); - let def_path_data = def_path_id(fn_def_id); - - let (.., trait_item_refs) = tcx.hir_expect_item(parent_def_id).expect_trait(); - // The purpose of `disambiguator_idx` is to ensure there are - // no duplicate `def_id` in certain cases, such as: - // ``` - // trait Foo { - // fn bar() -> impl Trait; - // fn bar() -> impl Trait; - // // ~~~~~~~~~~ It will generate the same ID if we don’t disambiguate it. - // } - // ``` - let disambiguator_idx = trait_item_refs - .iter() - .take_while(|item| item.id.owner_id.def_id != fn_def_id) - .filter(|item| { - matches!(item.kind, hir::AssocItemKind::Fn { .. }) - && def_path_id(item.id.owner_id.def_id) == def_path_data - }) - .last() - .map(|item| { - let output = tcx.hir_get_fn_output(item.id.owner_id.def_id).unwrap(); - let mut visitor = DisambiguatorIdxVisitor { depth: 0 }; - visitor.visit_fn_ret_ty(output); - tcx.def_key(item.id.owner_id.def_id).disambiguated_data.disambiguator - + visitor.depth - }) - .unwrap_or_default(); - - let data = DefPathData::AnonAssocTy(def_path_data); - let mut visitor = RPITVisitor { - tcx, - synthetics: vec![], - data, - disambiguator: DisambiguatorState::with(parent_def_id, data, disambiguator_idx), +fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> DefIdMap<Vec<DefId>> { + let item = tcx.hir_expect_item(def_id); + let disambiguator = &mut DisambiguatorState::new(); + match item.kind { + ItemKind::Trait(.., trait_item_refs) => trait_item_refs + .iter() + .filter_map(move |item| { + if !matches!(tcx.def_kind(item.owner_id), DefKind::AssocFn) { + return None; + } + let fn_def_id = item.owner_id.def_id; + let Some(output) = tcx.hir_get_fn_output(fn_def_id) else { + return Some((fn_def_id.to_def_id(), vec![])); }; + let def_name = tcx.item_name(fn_def_id.to_def_id()); + let data = DefPathData::AnonAssocTy(def_name); + let mut visitor = RPITVisitor { tcx, synthetics: vec![], data, disambiguator }; visitor.visit_fn_ret_ty(output); - tcx.arena.alloc_from_iter( - visitor.synthetics.into_iter().map(|def_id| def_id.to_def_id()), - ) - } else { - &[] - } - } - - DefKind::Impl { .. } => { - let Some(trait_fn_def_id) = tcx.associated_item(fn_def_id).trait_item_def_id else { - return &[]; + let defs = visitor + .synthetics + .into_iter() + .map(|def_id| def_id.to_def_id()) + .collect::<Vec<_>>(); + Some((fn_def_id.to_def_id(), defs)) + }) + .collect(), + ItemKind::Impl(impl_) => { + let Some(trait_ref) = impl_.of_trait else { + return Default::default(); + }; + let Some(trait_def_id) = trait_ref.trait_def_id() else { + return Default::default(); }; - tcx.arena.alloc_from_iter( - tcx.associated_types_for_impl_traits_in_associated_fn(trait_fn_def_id).iter().map( - move |&trait_assoc_def_id| { - associated_type_for_impl_trait_in_impl(tcx, trait_assoc_def_id, fn_def_id) + let in_trait_def = tcx.associated_types_for_impl_traits_in_trait_or_impl(trait_def_id); + impl_ + .items + .iter() + .filter_map(|item| { + if !matches!(tcx.def_kind(item.owner_id), DefKind::AssocFn) { + return None; + } + let did = item.owner_id.def_id.to_def_id(); + let item = tcx.hir_impl_item(*item); + let Some(trait_item_def_id) = item.trait_item_def_id else { + return Some((did, vec![])); + }; + let iter = in_trait_def[&trait_item_def_id].iter().map(|&id| { + associated_type_for_impl_trait_in_impl(tcx, id, item, disambiguator) .to_def_id() - }, - ), + }); + Some((did, iter.collect())) + }) + .collect() + } + _ => { + bug!( + "associated_types_for_impl_traits_in_trait_or_impl: {:?} should be Trait or Impl but is {:?}", + def_id, + tcx.def_kind(def_id) ) } - - def_kind => bug!( - "associated_types_for_impl_traits_in_associated_fn: {:?} should be Trait or Impl but is {:?}", - parent_def_id, - def_kind - ), } } @@ -337,19 +274,20 @@ fn associated_type_for_impl_trait_in_trait( /// Given an `trait_assoc_def_id` corresponding to an associated item synthesized /// from an `impl Trait` in an associated function from a trait, and an -/// `impl_fn_def_id` that represents an implementation of the associated function +/// `impl_fn` that represents an implementation of the associated function /// that the `impl Trait` comes from, synthesize an associated type for that `impl Trait` /// that inherits properties that we infer from the method and the associated type. fn associated_type_for_impl_trait_in_impl( tcx: TyCtxt<'_>, trait_assoc_def_id: DefId, - impl_fn_def_id: LocalDefId, + impl_fn: &hir::ImplItem<'_>, + disambiguator: &mut DisambiguatorState, ) -> LocalDefId { - let impl_local_def_id = tcx.local_parent(impl_fn_def_id); + let impl_local_def_id = tcx.local_parent(impl_fn.owner_id.def_id); - let decl = tcx.hir_node_by_def_id(impl_fn_def_id).fn_decl().expect("expected decl"); - let span = match decl.output { - hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn_def_id), + let hir::ImplItemKind::Fn(fn_sig, _) = impl_fn.kind else { bug!("expected decl") }; + let span = match fn_sig.decl.output { + hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn.owner_id), hir::FnRetTy::Return(ty) => ty.span, }; @@ -366,7 +304,7 @@ fn associated_type_for_impl_trait_in_impl( None, DefKind::AssocTy, Some(data), - &mut DisambiguatorState::with(impl_local_def_id, data, disambiguated_data.disambiguator), + disambiguator, ); let local_def_id = impl_assoc_ty.def_id(); @@ -380,7 +318,7 @@ fn associated_type_for_impl_trait_in_impl( impl_assoc_ty.associated_item(ty::AssocItem { kind: ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(ImplTraitInTraitData::Impl { - fn_def_id: impl_fn_def_id.to_def_id(), + fn_def_id: impl_fn.owner_id.to_def_id(), }), }, def_id, @@ -389,10 +327,10 @@ fn associated_type_for_impl_trait_in_impl( }); // Copy visility of the containing function. - impl_assoc_ty.visibility(tcx.visibility(impl_fn_def_id)); + impl_assoc_ty.visibility(tcx.visibility(impl_fn.owner_id)); // Copy defaultness of the containing function. - impl_assoc_ty.defaultness(tcx.defaultness(impl_fn_def_id)); + impl_assoc_ty.defaultness(tcx.defaultness(impl_fn.owner_id)); // Copy generics_of the trait's associated item but the impl as the parent. // FIXME: This may be detrimental to diagnostics, as we resolve the early-bound vars diff --git a/library/compiler-builtins/compiler-builtins/Cargo.toml b/library/compiler-builtins/compiler-builtins/Cargo.toml index c5446cd76e3..3ccb05f73fb 100644 --- a/library/compiler-builtins/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/compiler-builtins/Cargo.toml @@ -19,6 +19,8 @@ links = "compiler-rt" bench = false doctest = false test = false +# make sure this crate isn't included in public standard library docs +doc = false [dependencies] core = { path = "../../core", optional = true } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index b1ca3701fa5..03b120fbf0c 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -248,7 +248,7 @@ use crate::ops::ControlFlow; )] #[rustc_diagnostic_item = "PartialEq"] #[const_trait] -#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized { /// Tests for `self` and `other` values to be equal, and is used by `==`. #[must_use] @@ -1809,7 +1809,7 @@ mod impls { macro_rules! partial_eq_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl const PartialEq for $t { #[inline] fn eq(&self, other: &Self) -> bool { *self == *other } @@ -2017,7 +2017,7 @@ mod impls { // & pointers #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl<A: PointeeSized, B: PointeeSized> const PartialEq<&B> for &A where A: ~const PartialEq<B>, @@ -2089,7 +2089,7 @@ mod impls { // &mut pointers #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl<A: PointeeSized, B: PointeeSized> const PartialEq<&mut B> for &mut A where A: ~const PartialEq<B>, @@ -2159,7 +2159,7 @@ mod impls { impl<A: PointeeSized> Eq for &mut A where A: Eq {} #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl<A: PointeeSized, B: PointeeSized> const PartialEq<&mut B> for &A where A: ~const PartialEq<B>, @@ -2175,7 +2175,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl<A: PointeeSized, B: PointeeSized> const PartialEq<&B> for &mut A where A: ~const PartialEq<B>, diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 7132e712ec5..38381dbdf23 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -445,6 +445,8 @@ pub trait AsMut<T: PointeeSized>: PointeeSized { #[rustc_diagnostic_item = "Into"] #[stable(feature = "rust1", since = "1.0.0")] #[doc(search_unbox)] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait Into<T>: Sized { /// Converts this type into the (usually inferred) input type. #[must_use] @@ -580,6 +582,8 @@ pub trait Into<T>: Sized { note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix", ))] #[doc(search_unbox)] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait From<T>: Sized { /// Converts to this type from the input type. #[rustc_diagnostic_item = "from_fn"] @@ -607,6 +611,8 @@ pub trait From<T>: Sized { /// [`Into`], see there for details. #[rustc_diagnostic_item = "TryInto"] #[stable(feature = "try_from", since = "1.34.0")] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait TryInto<T>: Sized { /// The type returned in the event of a conversion error. #[stable(feature = "try_from", since = "1.34.0")] @@ -685,6 +691,8 @@ pub trait TryInto<T>: Sized { /// [`try_from`]: TryFrom::try_from #[rustc_diagnostic_item = "TryFrom"] #[stable(feature = "try_from", since = "1.34.0")] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait TryFrom<T>: Sized { /// The type returned in the event of a conversion error. #[stable(feature = "try_from", since = "1.34.0")] @@ -754,9 +762,10 @@ where // From implies Into #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U> Into<U> for T +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl<T, U> const Into<U> for T where - U: From<T>, + U: ~const From<T>, { /// Calls `U::from(self)`. /// @@ -771,7 +780,8 @@ where // From (and thus Into) is reflexive #[stable(feature = "rust1", since = "1.0.0")] -impl<T> From<T> for T { +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl<T> const From<T> for T { /// Returns the argument unchanged. #[inline(always)] fn from(t: T) -> T { @@ -787,7 +797,8 @@ impl<T> From<T> for T { #[stable(feature = "convert_infallible", since = "1.34.0")] #[rustc_reservation_impl = "permitting this impl would forbid us from adding \ `impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"] -impl<T> From<!> for T { +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl<T> const From<!> for T { fn from(t: !) -> T { t } @@ -795,9 +806,10 @@ impl<T> From<!> for T { // TryFrom implies TryInto #[stable(feature = "try_from", since = "1.34.0")] -impl<T, U> TryInto<U> for T +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl<T, U> const TryInto<U> for T where - U: TryFrom<T>, + U: ~const TryFrom<T>, { type Error = U::Error; @@ -810,9 +822,10 @@ where // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[stable(feature = "try_from", since = "1.34.0")] -impl<T, U> TryFrom<U> for T +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl<T, U> const TryFrom<U> for T where - U: Into<T>, + U: ~const Into<T>, { type Error = Infallible; diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 8035dccc632..6b9cbb06435 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -230,32 +230,16 @@ pub macro assert_matches { /// ``` /// #![feature(cfg_select)] /// -/// let _some_string = cfg_select! {{ +/// let _some_string = cfg_select! { /// unix => { "With great power comes great electricity bills" } /// _ => { "Behind every successful diet is an unwatched pizza" } -/// }}; +/// }; /// ``` #[unstable(feature = "cfg_select", issue = "115585")] #[rustc_diagnostic_item = "cfg_select"] -#[rustc_macro_transparency = "semitransparent"] -pub macro cfg_select { - ({ $($tt:tt)* }) => {{ - $crate::cfg_select! { $($tt)* } - }}, - (_ => { $($output:tt)* }) => { - $($output)* - }, - ( - $cfg:meta => $output:tt - $($( $rest:tt )+)? - ) => { - #[cfg($cfg)] - $crate::cfg_select! { _ => $output } - $( - #[cfg(not($cfg))] - $crate::cfg_select! { $($rest)+ } - )? - }, +#[rustc_builtin_macro] +pub macro cfg_select($($tt:tt)*) { + /* compiler built-in */ } /// Asserts that a boolean expression is `true` at runtime. diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index c00585de064..1bd12d818cf 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -151,7 +151,7 @@ pub const fn forget<T>(t: T) { /// /// While Rust does not permit unsized locals since its removal in [#111942] it is /// still possible to call functions with unsized values from a function argument -/// or in-place construction. +/// or place expression. /// /// ```rust /// #![feature(unsized_fn_params, forget_unsized)] diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index a5242d60bf1..f9c4cdd0ebe 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -45,8 +45,11 @@ impl From<!> for TryFromIntError { /// An error which can be returned when parsing an integer. /// -/// This error is used as the error type for the `from_str_radix()` functions -/// on the primitive integer types, such as [`i8::from_str_radix`]. +/// For example, this error is returned by the `from_str_radix()` functions +/// on the primitive integer types (such as [`i8::from_str_radix`]) +/// and is used as the error type in their [`FromStr`] implementations. +/// +/// [`FromStr`]: crate::str::FromStr /// /// # Potential causes /// diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index e53c128efe0..7d44b1733b9 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -65,7 +65,7 @@ /// ``` #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +#[rustc_const_unstable(feature = "const_ops", issue = "143802")] #[rustc_on_unimplemented( on(all(Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",), on(all(Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",), @@ -96,7 +96,7 @@ pub trait Add<Rhs = Self> { macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Add for $t { type Output = $t; @@ -179,7 +179,7 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 /// ``` #[lang = "sub"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +#[rustc_const_unstable(feature = "const_ops", issue = "143802")] #[rustc_on_unimplemented( message = "cannot subtract `{Rhs}` from `{Self}`", label = "no implementation for `{Self} - {Rhs}`", @@ -208,7 +208,7 @@ pub trait Sub<Rhs = Self> { macro_rules! sub_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Sub for $t { type Output = $t; @@ -313,7 +313,7 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 /// ``` #[lang = "mul"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +#[rustc_const_unstable(feature = "const_ops", issue = "143802")] #[diagnostic::on_unimplemented( message = "cannot multiply `{Self}` by `{Rhs}`", label = "no implementation for `{Self} * {Rhs}`" @@ -341,7 +341,7 @@ pub trait Mul<Rhs = Self> { macro_rules! mul_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Mul for $t { type Output = $t; @@ -450,7 +450,7 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 /// ``` #[lang = "div"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +#[rustc_const_unstable(feature = "const_ops", issue = "143802")] #[diagnostic::on_unimplemented( message = "cannot divide `{Self}` by `{Rhs}`", label = "no implementation for `{Self} / {Rhs}`" @@ -484,7 +484,7 @@ macro_rules! div_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Div for $t { type Output = $t; @@ -505,7 +505,7 @@ div_impl_integer! { macro_rules! div_impl_float { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Div for $t { type Output = $t; @@ -556,7 +556,7 @@ div_impl_float! { f16 f32 f64 f128 } /// ``` #[lang = "rem"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +#[rustc_const_unstable(feature = "const_ops", issue = "143802")] #[diagnostic::on_unimplemented( message = "cannot calculate the remainder of `{Self}` divided by `{Rhs}`", label = "no implementation for `{Self} % {Rhs}`" @@ -590,7 +590,7 @@ macro_rules! rem_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Rem for $t { type Output = $t; @@ -626,7 +626,7 @@ macro_rules! rem_impl_float { /// assert_eq!(x % y, remainder); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Rem for $t { type Output = $t; diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index db31bd2bbfb..58b7e9a9fdf 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3700,7 +3700,8 @@ impl<T> [T] { /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']); /// ``` #[stable(feature = "slice_rotate", since = "1.26.0")] - pub fn rotate_left(&mut self, mid: usize) { + #[rustc_const_unstable(feature = "const_slice_rotate", issue = "143812")] + pub const fn rotate_left(&mut self, mid: usize) { assert!(mid <= self.len()); let k = self.len() - mid; let p = self.as_mut_ptr(); @@ -3745,7 +3746,8 @@ impl<T> [T] { /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']); /// ``` #[stable(feature = "slice_rotate", since = "1.26.0")] - pub fn rotate_right(&mut self, k: usize) { + #[rustc_const_unstable(feature = "const_slice_rotate", issue = "143812")] + pub const fn rotate_right(&mut self, k: usize) { assert!(k <= self.len()); let mid = self.len() - k; let p = self.as_mut_ptr(); diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs index 80178f297ea..b3b64422884 100644 --- a/library/core/src/slice/rotate.rs +++ b/library/core/src/slice/rotate.rs @@ -1,5 +1,5 @@ use crate::mem::{MaybeUninit, SizedTypeProperties}; -use crate::{cmp, ptr}; +use crate::ptr; type BufType = [usize; 32]; @@ -11,7 +11,7 @@ type BufType = [usize; 32]; /// /// The specified range must be valid for reading and writing. #[inline] -pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) { +pub(super) const unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) { if T::IS_ZST { return; } @@ -21,7 +21,8 @@ pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) { } // `T` is not a zero-sized type, so it's okay to divide by its size. if !cfg!(feature = "optimize_for_size") - && cmp::min(left, right) <= size_of::<BufType>() / size_of::<T>() + // FIXME(const-hack): Use cmp::min when available in const + && const_min(left, right) <= size_of::<BufType>() / size_of::<T>() { // SAFETY: guaranteed by the caller unsafe { ptr_rotate_memmove(left, mid, right) }; @@ -45,7 +46,7 @@ pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) { /// /// The specified range must be valid for reading and writing. #[inline] -unsafe fn ptr_rotate_memmove<T>(left: usize, mid: *mut T, right: usize) { +const unsafe fn ptr_rotate_memmove<T>(left: usize, mid: *mut T, right: usize) { // The `[T; 0]` here is to ensure this is appropriately aligned for T let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit(); let buf = rawarray.as_mut_ptr() as *mut T; @@ -117,7 +118,7 @@ unsafe fn ptr_rotate_memmove<T>(left: usize, mid: *mut T, right: usize) { /// /// The specified range must be valid for reading and writing. #[inline] -unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) { +const unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) { // Algorithm 2 // Microbenchmarks indicate that the average performance for random shifts is better all // the way until about `left + right == 32`, but the worst case performance breaks even @@ -175,7 +176,9 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) { } } // finish the chunk with more rounds - for start in 1..gcd { + // FIXME(const-hack): Use `for start in 1..gcd` when available in const + let mut start = 1; + while start < gcd { // SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for // reading and writing as per the function's safety contract, see [long-safety-expl] // above @@ -201,6 +204,8 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) { i += right; } } + + start += 1; } } @@ -222,7 +227,7 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) { /// /// The specified range must be valid for reading and writing. #[inline] -unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize) { +const unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize) { loop { if left >= right { // Algorithm 3 @@ -265,3 +270,8 @@ unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize) } } } + +// FIXME(const-hack): Use cmp::min when available in const +const fn const_min(left: usize, right: usize) -> usize { + if right < left { right } else { left } +} diff --git a/library/coretests/tests/macros.rs b/library/coretests/tests/macros.rs index d220e628d73..1c6aa90dfbc 100644 --- a/library/coretests/tests/macros.rs +++ b/library/coretests/tests/macros.rs @@ -48,11 +48,12 @@ fn matches_leading_pipe() { fn cfg_select_basic() { cfg_select! { target_pointer_width = "64" => { fn f0_() -> bool { true }} + _ => {} } cfg_select! { unix => { fn f1_() -> bool { true } } - any(target_os = "macos", target_os = "linux") => { fn f1_() -> bool { false }} + _ => { fn f1_() -> bool { false }} } cfg_select! { @@ -70,6 +71,8 @@ fn cfg_select_basic() { #[cfg(unix)] assert!(f1_()); + #[cfg(not(unix))] + assert!(!f1_()); #[cfg(target_pointer_width = "32")] assert!(!f2_()); @@ -183,6 +186,12 @@ fn _accepts_expressions() -> i32 { } } +fn _accepts_only_wildcard() -> i32 { + cfg_select! { + _ => { 1 } + } +} + // The current implementation expands to a macro call, which allows the use of expression // statements. fn _allows_stmt_expr_attributes() { @@ -195,12 +204,12 @@ fn _allows_stmt_expr_attributes() { } fn _expression() { - let _ = cfg_select!({ + let _ = cfg_select!( windows => { " XP" } _ => { "" } - }); + ); } diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index 003ac4f0cd3..668e988abff 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -61,6 +61,7 @@ struct Exception { // and its destructor is executed by the C++ runtime. When we take the Box // out of the exception, we need to leave the exception in a valid state // for its destructor to run without double-dropping the Box. + // We also construct this as None for copies of the exception. data: Option<Box<dyn Any + Send>>, } @@ -264,7 +265,11 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor { // runtime under a try/catch block and the panic that we generate here will be // used as the result of the exception copy. This is used by the C++ runtime to // support capturing exceptions with std::exception_ptr, which we can't support -// because Box<dyn Any> isn't clonable. +// because Box<dyn Any> isn't clonable. Thus we throw an exception without data, +// which the C++ runtime will attempt to copy, which will once again fail, and +// a std::bad_exception instance ends up in the std::exception_ptr instance. +// The lack of data doesn't matter because the exception will never be rethrown +// - it is purely used to signal to the C++ runtime that copying failed. macro_rules! define_cleanup { ($abi:tt $abi2:tt) => { unsafe extern $abi fn exception_cleanup(e: *mut Exception) { @@ -278,7 +283,9 @@ macro_rules! define_cleanup { unsafe extern $abi2 fn exception_copy( _dest: *mut Exception, _src: *mut Exception ) -> *mut Exception { - panic!("Rust panics cannot be copied"); + unsafe { + throw_exception(None); + } } } } @@ -291,6 +298,10 @@ cfg_if::cfg_if! { } pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 { + unsafe { throw_exception(Some(data)) } +} + +unsafe fn throw_exception(data: Option<Box<dyn Any + Send>>) -> ! { use core::intrinsics::{AtomicOrdering, atomic_store}; // _CxxThrowException executes entirely on this stack frame, so there's no @@ -300,8 +311,7 @@ pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 { // The ManuallyDrop is needed here since we don't want Exception to be // dropped when unwinding. Instead it will be dropped by exception_cleanup // which is invoked by the C++ runtime. - let mut exception = - ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data: Some(data) }); + let mut exception = ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data }); let throw_ptr = (&raw mut exception) as *mut _; // This... may seems surprising, and justifiably so. On 32-bit MSVC the diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 466b134d8fa..76e63a69e45 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -210,6 +210,9 @@ pub trait CommandExt: Sealed { /// intentional difference from the underlying `chroot` system call.) #[unstable(feature = "process_chroot", issue = "141298")] fn chroot<P: AsRef<Path>>(&mut self, dir: P) -> &mut process::Command; + + #[unstable(feature = "process_setsid", issue = "105376")] + fn setsid(&mut self, setsid: bool) -> &mut process::Command; } #[stable(feature = "rust1", since = "1.0.0")] @@ -260,6 +263,11 @@ impl CommandExt for process::Command { self.as_inner_mut().chroot(dir.as_ref()); self } + + fn setsid(&mut self, setsid: bool) -> &mut process::Command { + self.as_inner_mut().setsid(setsid); + self + } } /// Unix-specific extensions to [`process::ExitStatus`] and diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs index 6835ba44ee2..884cbd4ac1d 100644 --- a/library/std/src/sys/net/connection/uefi/mod.rs +++ b/library/std/src/sys/net/connection/uefi/mod.rs @@ -1,37 +1,54 @@ use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; +use crate::sync::{Arc, Mutex}; use crate::sys::unsupported; use crate::time::Duration; mod tcp; pub(crate) mod tcp4; -pub struct TcpStream(tcp::Tcp); +pub struct TcpStream { + inner: tcp::Tcp, + read_timeout: Arc<Mutex<Option<Duration>>>, + write_timeout: Arc<Mutex<Option<Duration>>>, +} impl TcpStream { pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> { - tcp::Tcp::connect(addr?).map(Self) + let inner = tcp::Tcp::connect(addr?, None)?; + Ok(Self { + inner, + read_timeout: Arc::new(Mutex::new(None)), + write_timeout: Arc::new(Mutex::new(None)), + }) } - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> { - unsupported() + pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> { + let inner = tcp::Tcp::connect(addr, Some(timeout))?; + Ok(Self { + inner, + read_timeout: Arc::new(Mutex::new(None)), + write_timeout: Arc::new(Mutex::new(None)), + }) } - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unsupported() + pub fn set_read_timeout(&self, t: Option<Duration>) -> io::Result<()> { + self.read_timeout.set(t).unwrap(); + Ok(()) } - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unsupported() + pub fn set_write_timeout(&self, t: Option<Duration>) -> io::Result<()> { + self.write_timeout.set(t).unwrap(); + Ok(()) } pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - unsupported() + Ok(self.read_timeout.get_cloned().unwrap()) } pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - unsupported() + Ok(self.write_timeout.get_cloned().unwrap()) } pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { @@ -39,7 +56,7 @@ impl TcpStream { } pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - self.0.read(buf) + self.inner.read(buf, self.read_timeout()?) } pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> { @@ -56,7 +73,7 @@ impl TcpStream { } pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - self.0.write(buf) + self.inner.write(buf, self.write_timeout()?) } pub fn write_vectored(&self, buf: &[IoSlice<'_>]) -> io::Result<usize> { diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index 55b6dbf2490..1152f69446e 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs @@ -1,33 +1,34 @@ use super::tcp4; use crate::io; use crate::net::SocketAddr; +use crate::time::Duration; pub(crate) enum Tcp { V4(tcp4::Tcp4), } impl Tcp { - pub(crate) fn connect(addr: &SocketAddr) -> io::Result<Self> { + pub(crate) fn connect(addr: &SocketAddr, timeout: Option<Duration>) -> io::Result<Self> { match addr { SocketAddr::V4(x) => { let temp = tcp4::Tcp4::new()?; temp.configure(true, Some(x), None)?; - temp.connect()?; + temp.connect(timeout)?; Ok(Tcp::V4(temp)) } SocketAddr::V6(_) => todo!(), } } - pub(crate) fn write(&self, buf: &[u8]) -> io::Result<usize> { + pub(crate) fn write(&self, buf: &[u8], timeout: Option<Duration>) -> io::Result<usize> { match self { - Self::V4(client) => client.write(buf), + Self::V4(client) => client.write(buf, timeout), } } - pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result<usize> { + pub(crate) fn read(&self, buf: &mut [u8], timeout: Option<Duration>) -> io::Result<usize> { match self { - Self::V4(client) => client.read(buf), + Self::V4(client) => client.read(buf, timeout), } } } diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs index af1ba2be47a..6342718929a 100644 --- a/library/std/src/sys/net/connection/uefi/tcp4.rs +++ b/library/std/src/sys/net/connection/uefi/tcp4.rs @@ -6,6 +6,7 @@ use crate::net::SocketAddrV4; use crate::ptr::NonNull; use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::pal::helpers; +use crate::time::{Duration, Instant}; const TYPE_OF_SERVICE: u8 = 8; const TIME_TO_LIVE: u8 = 255; @@ -66,7 +67,7 @@ impl Tcp4 { if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } - pub(crate) fn connect(&self) -> io::Result<()> { + pub(crate) fn connect(&self, timeout: Option<Duration>) -> io::Result<()> { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -79,7 +80,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut conn_token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -88,7 +89,7 @@ impl Tcp4 { } } - pub(crate) fn write(&self, buf: &[u8]) -> io::Result<usize> { + pub(crate) fn write(&self, buf: &[u8], timeout: Option<Duration>) -> io::Result<usize> { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -119,7 +120,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -128,7 +129,7 @@ impl Tcp4 { } } - pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result<usize> { + pub(crate) fn read(&self, buf: &mut [u8], timeout: Option<Duration>) -> io::Result<usize> { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -158,7 +159,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -167,6 +168,50 @@ impl Tcp4 { } } + /// Wait for an event to finish. This is checked by an atomic boolean that is supposed to be set + /// to true in the event callback. + /// + /// Optionally, allow specifying a timeout. + /// + /// If a timeout is provided, the operation (specified by its `EFI_TCP4_COMPLETION_TOKEN`) is + /// canceled and Error of kind TimedOut is returned. + /// + /// # SAFETY + /// + /// Pointer to a valid `EFI_TCP4_COMPLETION_TOKEN` + unsafe fn wait_or_cancel( + &self, + timeout: Option<Duration>, + token: *mut tcp4::CompletionToken, + ) -> io::Result<()> { + if !self.wait_for_flag(timeout) { + let _ = unsafe { self.cancel(token) }; + return Err(io::Error::new(io::ErrorKind::TimedOut, "Operation Timed out")); + } + + Ok(()) + } + + /// Abort an asynchronous connection, listen, transmission or receive request. + /// + /// If token is NULL, then all pending tokens issued by EFI_TCP4_PROTOCOL.Connect(), + /// EFI_TCP4_PROTOCOL.Accept(), EFI_TCP4_PROTOCOL.Transmit() or EFI_TCP4_PROTOCOL.Receive() are + /// aborted. + /// + /// # SAFETY + /// + /// Pointer to a valid `EFI_TCP4_COMPLETION_TOKEN` or NULL + unsafe fn cancel(&self, token: *mut tcp4::CompletionToken) -> io::Result<()> { + let protocol = self.protocol.as_ptr(); + + let r = unsafe { ((*protocol).cancel)(protocol, token) }; + if r.is_error() { + return Err(io::Error::from_raw_os_error(r.as_usize())); + } else { + Ok(()) + } + } + unsafe fn create_evt(&self) -> io::Result<helpers::OwnedEvent> { self.flag.store(false, Ordering::Relaxed); helpers::OwnedEvent::new( @@ -177,10 +222,19 @@ impl Tcp4 { ) } - fn wait_for_flag(&self) { + fn wait_for_flag(&self, timeout: Option<Duration>) -> bool { + let start = Instant::now(); + while !self.flag.load(Ordering::Relaxed) { let _ = self.poll(); + if let Some(t) = timeout { + if Instant::now().duration_since(start) >= t { + return false; + } + } } + + true } fn poll(&self) -> io::Result<()> { diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs index b6777b76668..6219be60caf 100644 --- a/library/std/src/sys/process/unix/common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -98,6 +98,7 @@ pub struct Command { #[cfg(target_os = "linux")] create_pidfd: bool, pgroup: Option<pid_t>, + setsid: bool, } // passed back to std::process with the pipes connected to the child, if any @@ -185,6 +186,7 @@ impl Command { #[cfg(target_os = "linux")] create_pidfd: false, pgroup: None, + setsid: false, } } @@ -220,6 +222,9 @@ impl Command { self.cwd(&OsStr::new("/")); } } + pub fn setsid(&mut self, setsid: bool) { + self.setsid = setsid; + } #[cfg(target_os = "linux")] pub fn create_pidfd(&mut self, val: bool) { @@ -298,6 +303,10 @@ impl Command { pub fn get_chroot(&self) -> Option<&CStr> { self.chroot.as_deref() } + #[allow(dead_code)] + pub fn get_setsid(&self) -> bool { + self.setsid + } pub fn get_closures(&mut self) -> &mut Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>> { &mut self.closures diff --git a/library/std/src/sys/process/unix/common/tests.rs b/library/std/src/sys/process/unix/common/tests.rs index e5c8dd6e341..5f71bf051f8 100644 --- a/library/std/src/sys/process/unix/common/tests.rs +++ b/library/std/src/sys/process/unix/common/tests.rs @@ -135,6 +135,64 @@ fn test_process_group_no_posix_spawn() { } #[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_setsid_posix_spawn() { + // Spawn a cat subprocess that's just going to hang since there is no I/O. + let mut cmd = Command::new(OsStr::new("cat")); + cmd.setsid(true); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + unsafe { + // Setsid will create a new session and process group, so check that + // we can kill the process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_setsid_no_posix_spawn() { + let mut cmd = Command::new(OsStr::new("cat")); + cmd.setsid(true); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + + unsafe { + // Same as above, create hang-y cat. This time, force using the non-posix_spawn path. + cmd.pre_exec(Box::new(|| Ok(()))); // pre_exec forces fork + exec rather than posix spawn. + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + // Setsid will create a new session and process group, so check that + // we can kill the process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + +#[test] fn test_program_kind() { let vectors = &[ ("foo", ProgramKind::PathLookup), diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index bbd03e2b0c4..5d13d6da185 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -340,6 +340,10 @@ impl Command { cvt(libc::setpgid(0, pgroup))?; } + if self.get_setsid() { + cvt(libc::setsid())?; + } + // emscripten has no signal support. #[cfg(not(target_os = "emscripten"))] { @@ -741,6 +745,16 @@ impl Command { flags |= libc::POSIX_SPAWN_SETSIGDEF; } + if self.get_setsid() { + cfg_if::cfg_if! { + if #[cfg(all(target_os = "linux", target_env = "gnu"))] { + flags |= libc::POSIX_SPAWN_SETSID; + } else { + return Ok(None); + } + } + } + cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; // Make sure we synchronize access to the global `environ` resource diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index 013e886a99b..fc85797dcc2 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -20,6 +20,7 @@ cfg_if::cfg_if! { target_os = "rtems", target_os = "solaris", target_os = "vita", + target_os = "nuttx", ))] { mod arc4random; pub use arc4random::fill_bytes; @@ -44,7 +45,6 @@ cfg_if::cfg_if! { target_os = "hurd", target_os = "l4re", target_os = "nto", - target_os = "nuttx", ))] { mod unix_legacy; pub use unix_legacy::fill_bytes; diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index b7f4656fa37..cce88d936b7 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -11,7 +11,7 @@ //! This is because `sys_common` not only contains platform-independent code, //! but also code that is shared between the different platforms in `sys`. //! Ideally all that shared code should be moved to `sys::common`, -//! and the dependencies between `std`, `sys_common` and `sys` all would form a dag. +//! and the dependencies between `std`, `sys_common` and `sys` all would form a DAG. //! Progress on this is tracked in #84187. #![allow(missing_docs)] diff --git a/library/stdarch/Cargo.lock b/library/stdarch/Cargo.lock index 3b76eed770b..80f424dfdd8 100644 --- a/library/stdarch/Cargo.lock +++ b/library/stdarch/Cargo.lock @@ -147,7 +147,6 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" name = "core_arch" version = "0.1.5" dependencies = [ - "std_detect", "stdarch-test", "syscalls", ] diff --git a/library/stdarch/README.md b/library/stdarch/README.md index 70ec256e681..9a35f4cd6ff 100644 --- a/library/stdarch/README.md +++ b/library/stdarch/README.md @@ -16,3 +16,9 @@ This repository contains two main crates: The `std::simd` component now lives in the [`packed_simd_2`](https://github.com/rust-lang/packed_simd) crate. + +## Synchronizing josh subtree with rustc + +This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. + +You can find a guide on how to perform the synchronization [here](https://rustc-dev-guide.rust-lang.org/external-repos.html#synchronizing-a-josh-subtree). diff --git a/library/stdarch/crates/core_arch/Cargo.toml b/library/stdarch/crates/core_arch/Cargo.toml index f4bd5fc552a..670447a2d5a 100644 --- a/library/stdarch/crates/core_arch/Cargo.toml +++ b/library/stdarch/crates/core_arch/Cargo.toml @@ -22,7 +22,6 @@ maintenance = { status = "experimental" } [dev-dependencies] stdarch-test = { version = "0.*", path = "../stdarch-test" } -std_detect = { version = "0.*", path = "../std_detect" } [target.'cfg(all(target_arch = "x86_64", target_os = "linux"))'.dev-dependencies] syscalls = { version = "0.6.18", default-features = false } diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index 96ed82021b4..32f144bc7ad 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -7925,7 +7925,7 @@ pub fn vcvth_f16_u64(a: u64) -> f16 { #[unstable(feature = "stdarch_neon_f16", issue = "136306")] pub fn vcvth_n_f16_s16<const N: i32>(a: i16) -> f16 { static_assert!(N >= 1 && N <= 16); - vcvth_n_f16_s32::<N>(a as i32) as f16 + vcvth_n_f16_s32::<N>(a as i32) } #[doc = "Fixed-point convert to floating-point"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_f16_s32)"] @@ -7972,7 +7972,7 @@ pub fn vcvth_n_f16_s64<const N: i32>(a: i64) -> f16 { #[unstable(feature = "stdarch_neon_f16", issue = "136306")] pub fn vcvth_n_f16_u16<const N: i32>(a: u16) -> f16 { static_assert!(N >= 1 && N <= 16); - vcvth_n_f16_u32::<N>(a as u32) as f16 + vcvth_n_f16_u32::<N>(a as u32) } #[doc = "Fixed-point convert to floating-point"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_f16_u32)"] @@ -17158,7 +17158,7 @@ pub fn vqdmlalh_s16(a: i32, b: i16, c: i16) -> i32 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqdmlals_s32(a: i64, b: i32, c: i32) -> i64 { let x: i64 = vqaddd_s64(a, vqdmulls_s32(b, c)); - x as i64 + x } #[doc = "Signed saturating doubling multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_lane_s16)"] @@ -17324,7 +17324,7 @@ pub fn vqdmlslh_s16(a: i32, b: i16, c: i16) -> i32 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqdmlsls_s32(a: i64, b: i32, c: i32) -> i64 { let x: i64 = vqsubd_s64(a, vqdmulls_s32(b, c)); - x as i64 + x } #[doc = "Vector saturating doubling multiply high by scalar"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_lane_s16)"] @@ -19495,10 +19495,7 @@ pub fn vqtbl1q_s8(a: int8x16_t, b: uint8x16_t) -> int8x16_t { #[cfg_attr(test, assert_instr(tbl))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbl1_u8(a: uint8x16_t, b: uint8x8_t) -> uint8x8_t { - unsafe { - let x = transmute(vqtbl1(transmute(a), b)); - x - } + unsafe { transmute(vqtbl1(transmute(a), b)) } } #[doc = "Table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1q_u8)"] @@ -19507,10 +19504,7 @@ pub fn vqtbl1_u8(a: uint8x16_t, b: uint8x8_t) -> uint8x8_t { #[cfg_attr(test, assert_instr(tbl))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbl1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t { - unsafe { - let x = transmute(vqtbl1q(transmute(a), b)); - x - } + unsafe { transmute(vqtbl1q(transmute(a), b)) } } #[doc = "Table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1_p8)"] @@ -19519,10 +19513,7 @@ pub fn vqtbl1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t { #[cfg_attr(test, assert_instr(tbl))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbl1_p8(a: poly8x16_t, b: uint8x8_t) -> poly8x8_t { - unsafe { - let x = transmute(vqtbl1(transmute(a), b)); - x - } + unsafe { transmute(vqtbl1(transmute(a), b)) } } #[doc = "Table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1q_p8)"] @@ -19531,10 +19522,7 @@ pub fn vqtbl1_p8(a: poly8x16_t, b: uint8x8_t) -> poly8x8_t { #[cfg_attr(test, assert_instr(tbl))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbl1q_p8(a: poly8x16_t, b: uint8x16_t) -> poly8x16_t { - unsafe { - let x = transmute(vqtbl1q(transmute(a), b)); - x - } + unsafe { transmute(vqtbl1q(transmute(a), b)) } } #[doc = "Table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2)"] @@ -20397,10 +20385,7 @@ pub fn vqtbx1q_s8(a: int8x16_t, b: int8x16_t, c: uint8x16_t) -> int8x16_t { #[cfg_attr(test, assert_instr(tbx))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbx1_u8(a: uint8x8_t, b: uint8x16_t, c: uint8x8_t) -> uint8x8_t { - unsafe { - let x = transmute(vqtbx1(transmute(a), transmute(b), c)); - x - } + unsafe { transmute(vqtbx1(transmute(a), transmute(b), c)) } } #[doc = "Extended table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1q_u8)"] @@ -20409,10 +20394,7 @@ pub fn vqtbx1_u8(a: uint8x8_t, b: uint8x16_t, c: uint8x8_t) -> uint8x8_t { #[cfg_attr(test, assert_instr(tbx))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbx1q_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t { - unsafe { - let x = transmute(vqtbx1q(transmute(a), transmute(b), c)); - x - } + unsafe { transmute(vqtbx1q(transmute(a), transmute(b), c)) } } #[doc = "Extended table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1_p8)"] @@ -20421,10 +20403,7 @@ pub fn vqtbx1q_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t { #[cfg_attr(test, assert_instr(tbx))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbx1_p8(a: poly8x8_t, b: poly8x16_t, c: uint8x8_t) -> poly8x8_t { - unsafe { - let x = transmute(vqtbx1(transmute(a), transmute(b), c)); - x - } + unsafe { transmute(vqtbx1(transmute(a), transmute(b), c)) } } #[doc = "Extended table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1q_p8)"] @@ -20433,10 +20412,7 @@ pub fn vqtbx1_p8(a: poly8x8_t, b: poly8x16_t, c: uint8x8_t) -> poly8x8_t { #[cfg_attr(test, assert_instr(tbx))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbx1q_p8(a: poly8x16_t, b: poly8x16_t, c: uint8x16_t) -> poly8x16_t { - unsafe { - let x = transmute(vqtbx1q(transmute(a), transmute(b), c)); - x - } + unsafe { transmute(vqtbx1q(transmute(a), transmute(b), c)) } } #[doc = "Extended table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2)"] @@ -23785,14 +23761,7 @@ pub fn vrndph_f16(a: f16) -> f16 { #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndx_f16(a: float16x4_t) -> float16x4_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v4f16" - )] - fn _vrndx_f16(a: float16x4_t) -> float16x4_t; - } - unsafe { _vrndx_f16(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f16)"] @@ -23801,14 +23770,7 @@ pub fn vrndx_f16(a: float16x4_t) -> float16x4_t { #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndxq_f16(a: float16x8_t) -> float16x8_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v8f16" - )] - fn _vrndxq_f16(a: float16x8_t) -> float16x8_t; - } - unsafe { _vrndxq_f16(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f32)"] @@ -23817,14 +23779,7 @@ pub fn vrndxq_f16(a: float16x8_t) -> float16x8_t { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndx_f32(a: float32x2_t) -> float32x2_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v2f32" - )] - fn _vrndx_f32(a: float32x2_t) -> float32x2_t; - } - unsafe { _vrndx_f32(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f32)"] @@ -23833,14 +23788,7 @@ pub fn vrndx_f32(a: float32x2_t) -> float32x2_t { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndxq_f32(a: float32x4_t) -> float32x4_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v4f32" - )] - fn _vrndxq_f32(a: float32x4_t) -> float32x4_t; - } - unsafe { _vrndxq_f32(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f64)"] @@ -23849,14 +23797,7 @@ pub fn vrndxq_f32(a: float32x4_t) -> float32x4_t { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndx_f64(a: float64x1_t) -> float64x1_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v1f64" - )] - fn _vrndx_f64(a: float64x1_t) -> float64x1_t; - } - unsafe { _vrndx_f64(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f64)"] @@ -23865,14 +23806,7 @@ pub fn vrndx_f64(a: float64x1_t) -> float64x1_t { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndxq_f64(a: float64x2_t) -> float64x2_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v2f64" - )] - fn _vrndxq_f64(a: float64x2_t) -> float64x2_t; - } - unsafe { _vrndxq_f64(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxh_f16)"] @@ -24082,7 +24016,6 @@ pub fn vrsqrtes_f32(a: f32) -> f32 { #[doc = "Reciprocal square-root estimate."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrteh_f16)"] #[inline] -#[target_feature(enable = "neon,fp16")] #[cfg_attr(test, assert_instr(frsqrte))] #[target_feature(enable = "neon,fp16")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] diff --git a/library/stdarch/crates/core_arch/src/arm_shared/mod.rs b/library/stdarch/crates/core_arch/src/arm_shared/mod.rs index 527b53de99d..8074648a28a 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/mod.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/mod.rs @@ -20,10 +20,10 @@ //! Section 10.1 of ACLE says: //! //! - "In the sequence of Arm architectures { v5, v5TE, v6, v6T2, v7 } each architecture includes -//! its predecessor instruction set." +//! its predecessor's instruction set." //! //! - "In the sequence of Thumb-only architectures { v6-M, v7-M, v7E-M } each architecture includes -//! its predecessor instruction set." +//! its predecessor's instruction set." //! //! From that info and from looking at how LLVM features work (using custom targets) we can identify //! features that are subsets of others: @@ -38,7 +38,7 @@ //! *NOTE*: Section 5.4.7 of ACLE says: //! //! - "__ARM_FEATURE_DSP is defined to 1 if the DSP (v5E) instructions are supported and the -//! intrinsics defined in Saturating intrinsics are available." +//! intrinsics defined in Saturating intrinsics are available." //! //! This does *not* match how LLVM uses the '+dsp' feature; this feature is not set for v5te //! targets so we have to work around this difference. diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index 286f1868852..4df1b741485 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -40758,16 +40758,7 @@ pub fn vqshlu_n_s8<const N: i32>(a: int8x8_t) -> uint8x8_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v8i8")] fn _vqshlu_n_s8(a: int8x8_t, n: int8x8_t) -> uint8x8_t; } - unsafe { - _vqshlu_n_s8( - a, - const { - int8x8_t([ - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - ]) - }, - ) - } + unsafe { _vqshlu_n_s8(a, const { int8x8_t([N as i8; 8]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s8)"] @@ -40783,17 +40774,7 @@ pub fn vqshluq_n_s8<const N: i32>(a: int8x16_t) -> uint8x16_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v16i8")] fn _vqshluq_n_s8(a: int8x16_t, n: int8x16_t) -> uint8x16_t; } - unsafe { - _vqshluq_n_s8( - a, - const { - int8x16_t([ - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - ]) - }, - ) - } + unsafe { _vqshluq_n_s8(a, const { int8x16_t([N as i8; 16]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s16)"] @@ -40809,12 +40790,7 @@ pub fn vqshlu_n_s16<const N: i32>(a: int16x4_t) -> uint16x4_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v4i16")] fn _vqshlu_n_s16(a: int16x4_t, n: int16x4_t) -> uint16x4_t; } - unsafe { - _vqshlu_n_s16( - a, - const { int16x4_t([N as i16, N as i16, N as i16, N as i16]) }, - ) - } + unsafe { _vqshlu_n_s16(a, const { int16x4_t([N as i16; 4]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s16)"] @@ -40830,16 +40806,7 @@ pub fn vqshluq_n_s16<const N: i32>(a: int16x8_t) -> uint16x8_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v8i16")] fn _vqshluq_n_s16(a: int16x8_t, n: int16x8_t) -> uint16x8_t; } - unsafe { - _vqshluq_n_s16( - a, - const { - int16x8_t([ - N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, - ]) - }, - ) - } + unsafe { _vqshluq_n_s16(a, const { int16x8_t([N as i16; 8]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s32)"] @@ -40855,7 +40822,7 @@ pub fn vqshlu_n_s32<const N: i32>(a: int32x2_t) -> uint32x2_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v2i32")] fn _vqshlu_n_s32(a: int32x2_t, n: int32x2_t) -> uint32x2_t; } - unsafe { _vqshlu_n_s32(a, const { int32x2_t([N as i32, N as i32]) }) } + unsafe { _vqshlu_n_s32(a, const { int32x2_t([N; 2]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s32)"] @@ -40871,12 +40838,7 @@ pub fn vqshluq_n_s32<const N: i32>(a: int32x4_t) -> uint32x4_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v4i32")] fn _vqshluq_n_s32(a: int32x4_t, n: int32x4_t) -> uint32x4_t; } - unsafe { - _vqshluq_n_s32( - a, - const { int32x4_t([N as i32, N as i32, N as i32, N as i32]) }, - ) - } + unsafe { _vqshluq_n_s32(a, const { int32x4_t([N; 4]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s64)"] @@ -40908,7 +40870,7 @@ pub fn vqshluq_n_s64<const N: i32>(a: int64x2_t) -> uint64x2_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v2i64")] fn _vqshluq_n_s64(a: int64x2_t, n: int64x2_t) -> uint64x2_t; } - unsafe { _vqshluq_n_s64(a, const { int64x2_t([N as i64, N as i64]) }) } + unsafe { _vqshluq_n_s64(a, const { int64x2_t([N as i64; 2]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s8)"] @@ -40927,16 +40889,7 @@ pub fn vqshlu_n_s8<const N: i32>(a: int8x8_t) -> uint8x8_t { )] fn _vqshlu_n_s8(a: int8x8_t, n: int8x8_t) -> uint8x8_t; } - unsafe { - _vqshlu_n_s8( - a, - const { - int8x8_t([ - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - ]) - }, - ) - } + unsafe { _vqshlu_n_s8(a, const { int8x8_t([N as i8; 8]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s8)"] @@ -40955,17 +40908,7 @@ pub fn vqshluq_n_s8<const N: i32>(a: int8x16_t) -> uint8x16_t { )] fn _vqshluq_n_s8(a: int8x16_t, n: int8x16_t) -> uint8x16_t; } - unsafe { - _vqshluq_n_s8( - a, - const { - int8x16_t([ - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - ]) - }, - ) - } + unsafe { _vqshluq_n_s8(a, const { int8x16_t([N as i8; 16]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s16)"] @@ -40984,12 +40927,7 @@ pub fn vqshlu_n_s16<const N: i32>(a: int16x4_t) -> uint16x4_t { )] fn _vqshlu_n_s16(a: int16x4_t, n: int16x4_t) -> uint16x4_t; } - unsafe { - _vqshlu_n_s16( - a, - const { int16x4_t([N as i16, N as i16, N as i16, N as i16]) }, - ) - } + unsafe { _vqshlu_n_s16(a, const { int16x4_t([N as i16; 4]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s16)"] @@ -41008,16 +40946,7 @@ pub fn vqshluq_n_s16<const N: i32>(a: int16x8_t) -> uint16x8_t { )] fn _vqshluq_n_s16(a: int16x8_t, n: int16x8_t) -> uint16x8_t; } - unsafe { - _vqshluq_n_s16( - a, - const { - int16x8_t([ - N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, - ]) - }, - ) - } + unsafe { _vqshluq_n_s16(a, const { int16x8_t([N as i16; 8]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s32)"] @@ -41036,7 +40965,7 @@ pub fn vqshlu_n_s32<const N: i32>(a: int32x2_t) -> uint32x2_t { )] fn _vqshlu_n_s32(a: int32x2_t, n: int32x2_t) -> uint32x2_t; } - unsafe { _vqshlu_n_s32(a, const { int32x2_t([N as i32, N as i32]) }) } + unsafe { _vqshlu_n_s32(a, const { int32x2_t([N; 2]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s32)"] @@ -41055,12 +40984,7 @@ pub fn vqshluq_n_s32<const N: i32>(a: int32x4_t) -> uint32x4_t { )] fn _vqshluq_n_s32(a: int32x4_t, n: int32x4_t) -> uint32x4_t; } - unsafe { - _vqshluq_n_s32( - a, - const { int32x4_t([N as i32, N as i32, N as i32, N as i32]) }, - ) - } + unsafe { _vqshluq_n_s32(a, const { int32x4_t([N; 4]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s64)"] @@ -41098,7 +41022,7 @@ pub fn vqshluq_n_s64<const N: i32>(a: int64x2_t) -> uint64x2_t { )] fn _vqshluq_n_s64(a: int64x2_t, n: int64x2_t) -> uint64x2_t; } - unsafe { _vqshluq_n_s64(a, const { int64x2_t([N as i64, N as i64]) }) } + unsafe { _vqshluq_n_s64(a, const { int64x2_t([N as i64; 2]) }) } } #[doc = "Signed saturating shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s16)"] diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs index 0683d48ed32..60c9daef68c 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs @@ -777,8 +777,8 @@ pub struct float16x8x2_t(pub float16x8_t, pub float16x8_t); #[repr(C)] #[derive(Copy, Clone, Debug)] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] - pub struct float16x8x3_t(pub float16x8_t, pub float16x8_t, pub float16x8_t); + /// Arm-specific type containing four `float16x8_t` vectors. #[repr(C)] #[derive(Copy, Clone, Debug)] diff --git a/library/stdarch/crates/core_arch/src/lib.rs b/library/stdarch/crates/core_arch/src/lib.rs index 340c4c510d7..c58580f6417 100644 --- a/library/stdarch/crates/core_arch/src/lib.rs +++ b/library/stdarch/crates/core_arch/src/lib.rs @@ -75,9 +75,7 @@ #[cfg(test)] #[macro_use] extern crate std; -#[cfg(test)] -#[macro_use] -extern crate std_detect; + #[path = "mod.rs"] mod core_arch; diff --git a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs index 2deeb53c209..a7bbf35ed8d 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs @@ -360,25 +360,6 @@ unsafe extern "C" { #[link_name = "llvm.ppc.altivec.vsrv"] fn vsrv(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char; - #[link_name = "llvm.fshl.v16i8"] - fn fshlb( - a: vector_unsigned_char, - b: vector_unsigned_char, - c: vector_unsigned_char, - ) -> vector_unsigned_char; - #[link_name = "llvm.fshl.v8i16"] - fn fshlh( - a: vector_unsigned_short, - b: vector_unsigned_short, - c: vector_unsigned_short, - ) -> vector_unsigned_short; - #[link_name = "llvm.fshl.v4i32"] - fn fshlw( - a: vector_unsigned_int, - b: vector_unsigned_int, - c: vector_unsigned_int, - ) -> vector_unsigned_int; - #[link_name = "llvm.nearbyint.v4f32"] fn vrfin(a: vector_float) -> vector_float; } @@ -3193,19 +3174,19 @@ mod sealed { impl_vec_cntlz! { vec_vcntlzw(vector_unsigned_int) } macro_rules! impl_vrl { - ($fun:ident $intr:ident $ty:ident) => { + ($fun:ident $ty:ident) => { #[inline] #[target_feature(enable = "altivec")] #[cfg_attr(test, assert_instr($fun))] unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) { - transmute($intr(transmute(a), transmute(a), transmute(b))) + simd_funnel_shl(a, a, b) } }; } - impl_vrl! { vrlb fshlb u8 } - impl_vrl! { vrlh fshlh u16 } - impl_vrl! { vrlw fshlw u32 } + impl_vrl! { vrlb u8 } + impl_vrl! { vrlh u16 } + impl_vrl! { vrlw u32 } #[unstable(feature = "stdarch_powerpc", issue = "111145")] pub trait VectorRl { diff --git a/library/stdarch/crates/core_arch/src/powerpc/macros.rs b/library/stdarch/crates/core_arch/src/powerpc/macros.rs index af47494e8fb..24d86f1018c 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/macros.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/macros.rs @@ -278,6 +278,7 @@ macro_rules! impl_from { ($s: ident) => { #[unstable(feature = "stdarch_powerpc", issue = "111145")] impl From<$s> for s_t_l!($s) { + #[inline] fn from (v: $s) -> Self { unsafe { transmute(v) @@ -297,6 +298,7 @@ macro_rules! impl_neg { #[unstable(feature = "stdarch_powerpc", issue = "111145")] impl crate::ops::Neg for s_t_l!($s) { type Output = s_t_l!($s); + #[inline] fn neg(self) -> Self::Output { unsafe { simd_neg(self) } } diff --git a/library/stdarch/crates/core_arch/src/s390x/macros.rs b/library/stdarch/crates/core_arch/src/s390x/macros.rs index 4f0f84ec912..26afbaa45a7 100644 --- a/library/stdarch/crates/core_arch/src/s390x/macros.rs +++ b/library/stdarch/crates/core_arch/src/s390x/macros.rs @@ -435,6 +435,7 @@ macro_rules! impl_from { ($s: ident) => { #[unstable(feature = "stdarch_s390x", issue = "135681")] impl From<$s> for s_t_l!($s) { + #[inline] fn from (v: $s) -> Self { unsafe { transmute(v) @@ -454,6 +455,7 @@ macro_rules! impl_neg { #[unstable(feature = "stdarch_s390x", issue = "135681")] impl crate::ops::Neg for s_t_l!($s) { type Output = s_t_l!($s); + #[inline] fn neg(self) -> Self::Output { unsafe { simd_neg(self) } } diff --git a/library/stdarch/crates/core_arch/src/s390x/vector.rs b/library/stdarch/crates/core_arch/src/s390x/vector.rs index ae5c37ce017..1cd33c3554b 100644 --- a/library/stdarch/crates/core_arch/src/s390x/vector.rs +++ b/library/stdarch/crates/core_arch/src/s390x/vector.rs @@ -51,7 +51,7 @@ types! { pub struct vector_double(2 x f64); } -#[repr(packed)] +#[repr(C, packed)] struct PackedTuple<T, U> { x: T, y: U, @@ -83,9 +83,6 @@ unsafe extern "unadjusted" { #[link_name = "llvm.nearbyint.v4f32"] fn nearbyint_v4f32(a: vector_float) -> vector_float; #[link_name = "llvm.nearbyint.v2f64"] fn nearbyint_v2f64(a: vector_double) -> vector_double; - #[link_name = "llvm.rint.v4f32"] fn rint_v4f32(a: vector_float) -> vector_float; - #[link_name = "llvm.rint.v2f64"] fn rint_v2f64(a: vector_double) -> vector_double; - #[link_name = "llvm.roundeven.v4f32"] fn roundeven_v4f32(a: vector_float) -> vector_float; #[link_name = "llvm.roundeven.v2f64"] fn roundeven_v2f64(a: vector_double) -> vector_double; @@ -101,11 +98,6 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.vsld"] fn vsld(a: i8x16, b: i8x16, c: u32) -> i8x16; #[link_name = "llvm.s390.vsrd"] fn vsrd(a: i8x16, b: i8x16, c: u32) -> i8x16; - #[link_name = "llvm.fshl.v16i8"] fn fshlb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> vector_unsigned_char; - #[link_name = "llvm.fshl.v8i16"] fn fshlh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short) -> vector_unsigned_short; - #[link_name = "llvm.fshl.v4i32"] fn fshlf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int) -> vector_unsigned_int; - #[link_name = "llvm.fshl.v2i64"] fn fshlg(a: vector_unsigned_long_long, b: vector_unsigned_long_long, c: vector_unsigned_long_long) -> vector_unsigned_long_long; - #[link_name = "llvm.s390.verimb"] fn verimb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_char, d: i32) -> vector_signed_char; #[link_name = "llvm.s390.verimh"] fn verimh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_short, d: i32) -> vector_signed_short; #[link_name = "llvm.s390.verimf"] fn verimf(a: vector_signed_int, b: vector_signed_int, c: vector_signed_int, d: i32) -> vector_signed_int; @@ -1197,8 +1189,8 @@ mod sealed { test_impl! { vec_round_f32 (a: vector_float) -> vector_float [roundeven_v4f32, _] } test_impl! { vec_round_f64 (a: vector_double) -> vector_double [roundeven_v2f64, _] } - test_impl! { vec_rint_f32 (a: vector_float) -> vector_float [rint_v4f32, "vector-enhancements-1" vfisb] } - test_impl! { vec_rint_f64 (a: vector_double) -> vector_double [rint_v2f64, vfidb] } + test_impl! { vec_rint_f32 (a: vector_float) -> vector_float [simd_round_ties_even, "vector-enhancements-1" vfisb] } + test_impl! { vec_rint_f64 (a: vector_double) -> vector_double [simd_round_ties_even, vfidb] } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorRoundc { @@ -1221,8 +1213,8 @@ mod sealed { impl_vec_trait! { [VectorRound vec_round] vec_round_f32 (vector_float) } impl_vec_trait! { [VectorRound vec_round] vec_round_f64 (vector_double) } - impl_vec_trait! { [VectorRint vec_rint] vec_rint_f32 (vector_float) } - impl_vec_trait! { [VectorRint vec_rint] vec_rint_f64 (vector_double) } + impl_vec_trait! { [VectorRint vec_rint] simd_round_ties_even (vector_float) } + impl_vec_trait! { [VectorRint vec_rint] simd_round_ties_even (vector_double) } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorTrunc { @@ -1411,43 +1403,42 @@ mod sealed { } macro_rules! impl_rot { - ($fun:ident $intr:ident $ty:ident) => { + ($fun:ident $ty:ident) => { #[inline] #[target_feature(enable = "vector")] #[cfg_attr(test, assert_instr($fun))] unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) { - transmute($intr(transmute(a), transmute(a), transmute(b))) + simd_funnel_shl(a, a, b) } }; } - impl_rot! { verllvb fshlb u8 } - impl_rot! { verllvh fshlh u16 } - impl_rot! { verllvf fshlf u32 } - impl_rot! { verllvg fshlg u64 } + impl_rot! { verllvb u8 } + impl_rot! { verllvh u16 } + impl_rot! { verllvf u32 } + impl_rot! { verllvg u64 } impl_vec_shift! { [VectorRl vec_rl] (verllvb, verllvh, verllvf, verllvg) } macro_rules! test_rot_imm { - ($fun:ident $instr:ident $intr:ident $ty:ident) => { + ($fun:ident $instr:ident $ty:ident) => { #[inline] #[target_feature(enable = "vector")] #[cfg_attr(test, assert_instr($instr))] unsafe fn $fun(a: t_t_l!($ty), bits: core::ffi::c_ulong) -> t_t_l!($ty) { // mod by the number of bits in a's element type to prevent UB let bits = (bits % $ty::BITS as core::ffi::c_ulong) as $ty; - let a = transmute(a); let b = <t_t_s!($ty)>::splat(bits); - transmute($intr(a, a, transmute(b))) + simd_funnel_shl(a, a, transmute(b)) } }; } - test_rot_imm! { verllvb_imm verllb fshlb u8 } - test_rot_imm! { verllvh_imm verllh fshlh u16 } - test_rot_imm! { verllvf_imm verllf fshlf u32 } - test_rot_imm! { verllvg_imm verllg fshlg u64 } + test_rot_imm! { verllvb_imm verllb u8 } + test_rot_imm! { verllvh_imm verllh u16 } + test_rot_imm! { verllvf_imm verllf u32 } + test_rot_imm! { verllvg_imm verllg u64 } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorRli { @@ -4787,7 +4778,7 @@ pub unsafe fn vec_splat_s8<const IMM: i8>() -> vector_signed_char { #[unstable(feature = "stdarch_s390x", issue = "135681")] #[cfg_attr(test, assert_instr(vrepih, IMM = 42))] pub unsafe fn vec_splat_s16<const IMM: i16>() -> vector_signed_short { - vector_signed_short([IMM as i16; 8]) + vector_signed_short([IMM; 8]) } /// Vector Splat Signed Word diff --git a/library/stdarch/crates/core_arch/src/wasm32/simd128.rs b/library/stdarch/crates/core_arch/src/wasm32/simd128.rs index fc0d7723fa0..108bc3125c5 100644 --- a/library/stdarch/crates/core_arch/src/wasm32/simd128.rs +++ b/library/stdarch/crates/core_arch/src/wasm32/simd128.rs @@ -141,7 +141,7 @@ unsafe extern "unadjusted" { fn llvm_f64x2_max(x: simd::f64x2, y: simd::f64x2) -> simd::f64x2; } -#[repr(packed)] +#[repr(C, packed)] #[derive(Copy)] struct Unaligned<T>(T); diff --git a/library/stdarch/crates/core_arch/src/x86/avx.rs b/library/stdarch/crates/core_arch/src/x86/avx.rs index df1cb63be30..24e0cf6ba1a 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx.rs @@ -1258,7 +1258,7 @@ pub fn _mm256_permute2f128_si256<const IMM8: i32>(a: __m256i, b: __m256i) -> __m #[cfg_attr(test, assert_instr(vbroadcastss))] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::trivially_copy_pass_by_ref)] -pub unsafe fn _mm256_broadcast_ss(f: &f32) -> __m256 { +pub fn _mm256_broadcast_ss(f: &f32) -> __m256 { _mm256_set1_ps(*f) } @@ -1271,7 +1271,7 @@ pub unsafe fn _mm256_broadcast_ss(f: &f32) -> __m256 { #[cfg_attr(test, assert_instr(vbroadcastss))] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::trivially_copy_pass_by_ref)] -pub unsafe fn _mm_broadcast_ss(f: &f32) -> __m128 { +pub fn _mm_broadcast_ss(f: &f32) -> __m128 { _mm_set1_ps(*f) } @@ -1284,7 +1284,7 @@ pub unsafe fn _mm_broadcast_ss(f: &f32) -> __m128 { #[cfg_attr(test, assert_instr(vbroadcastsd))] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::trivially_copy_pass_by_ref)] -pub unsafe fn _mm256_broadcast_sd(f: &f64) -> __m256d { +pub fn _mm256_broadcast_sd(f: &f64) -> __m256d { _mm256_set1_pd(*f) } @@ -1296,8 +1296,8 @@ pub unsafe fn _mm256_broadcast_sd(f: &f64) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vbroadcastf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_broadcast_ps(a: &__m128) -> __m256 { - simd_shuffle!(*a, _mm_setzero_ps(), [0, 1, 2, 3, 0, 1, 2, 3]) +pub fn _mm256_broadcast_ps(a: &__m128) -> __m256 { + unsafe { simd_shuffle!(*a, _mm_setzero_ps(), [0, 1, 2, 3, 0, 1, 2, 3]) } } /// Broadcasts 128 bits from memory (composed of 2 packed double-precision @@ -1308,8 +1308,8 @@ pub unsafe fn _mm256_broadcast_ps(a: &__m128) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vbroadcastf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_broadcast_pd(a: &__m128d) -> __m256d { - simd_shuffle!(*a, _mm_setzero_pd(), [0, 1, 0, 1]) +pub fn _mm256_broadcast_pd(a: &__m128d) -> __m256d { + unsafe { simd_shuffle!(*a, _mm_setzero_pd(), [0, 1, 0, 1]) } } /// Copies `a` to result, then inserts 128 bits (composed of 4 packed diff --git a/library/stdarch/crates/core_arch/src/x86/avx512f.rs b/library/stdarch/crates/core_arch/src/x86/avx512f.rs index dd224616764..d53f83c0a10 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512f.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512f.rs @@ -33248,7 +33248,7 @@ pub fn _mm512_reduce_add_ps(a: __m512) -> f32 { ); let a = _mm_add_ps(_mm256_extractf128_ps::<0>(a), _mm256_extractf128_ps::<1>(a)); let a = _mm_add_ps(a, simd_shuffle!(a, a, [2, 3, 0, 1])); - simd_extract::<_, f32>(a, 0) + simd_extract::<_, f32>(a, 1) + simd_extract!(a, 0, f32) + simd_extract!(a, 1, f32) } } @@ -33275,7 +33275,7 @@ pub fn _mm512_reduce_add_pd(a: __m512d) -> f64 { _mm512_extractf64x4_pd::<1>(a), ); let a = _mm_add_pd(_mm256_extractf128_pd::<0>(a), _mm256_extractf128_pd::<1>(a)); - simd_extract::<_, f64>(a, 0) + simd_extract::<_, f64>(a, 1) + simd_extract!(a, 0, f64) + simd_extract!(a, 1, f64) } } @@ -33356,7 +33356,7 @@ pub fn _mm512_reduce_mul_ps(a: __m512) -> f32 { ); let a = _mm_mul_ps(_mm256_extractf128_ps::<0>(a), _mm256_extractf128_ps::<1>(a)); let a = _mm_mul_ps(a, simd_shuffle!(a, a, [2, 3, 0, 1])); - simd_extract::<_, f32>(a, 0) * simd_extract::<_, f32>(a, 1) + simd_extract!(a, 0, f32) * simd_extract!(a, 1, f32) } } @@ -33383,7 +33383,7 @@ pub fn _mm512_reduce_mul_pd(a: __m512d) -> f64 { _mm512_extractf64x4_pd::<1>(a), ); let a = _mm_mul_pd(_mm256_extractf128_pd::<0>(a), _mm256_extractf128_pd::<1>(a)); - simd_extract::<_, f64>(a, 0) * simd_extract::<_, f64>(a, 1) + simd_extract!(a, 0, f64) * simd_extract!(a, 1, f64) } } diff --git a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs index 0a81a0581f9..8c914803c66 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs @@ -11032,7 +11032,7 @@ pub fn _mm_reduce_add_ph(a: __m128h) -> f16 { let a = _mm_add_ph(a, b); let b = simd_shuffle!(a, a, [2, 3, 0, 1, 4, 5, 6, 7]); let a = _mm_add_ph(a, b); - simd_extract::<_, f16>(a, 0) + simd_extract::<_, f16>(a, 1) + simd_extract!(a, 0, f16) + simd_extract!(a, 1, f16) } } @@ -11085,7 +11085,7 @@ pub fn _mm_reduce_mul_ph(a: __m128h) -> f16 { let a = _mm_mul_ph(a, b); let b = simd_shuffle!(a, a, [2, 3, 0, 1, 4, 5, 6, 7]); let a = _mm_mul_ph(a, b); - simd_extract::<_, f16>(a, 0) * simd_extract::<_, f16>(a, 1) + simd_extract!(a, 0, f16) * simd_extract!(a, 1, f16) } } diff --git a/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs b/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs index c722f7b370f..09a90e29bf0 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs @@ -500,7 +500,7 @@ pub fn _mm_maskz_expand_epi8(k: __mmask16, a: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] pub fn _mm512_shldv_epi64(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshldvq(a.as_i64x8(), b.as_i64x8(), c.as_i64x8())) } + unsafe { transmute(simd_funnel_shl(a.as_i64x8(), b.as_i64x8(), c.as_i64x8())) } } /// Concatenate packed 64-bit integers in a and b producing an intermediate 128-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -539,7 +539,7 @@ pub fn _mm512_maskz_shldv_epi64(k: __mmask8, a: __m512i, b: __m512i, c: __m512i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] pub fn _mm256_shldv_epi64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshldvq256(a.as_i64x4(), b.as_i64x4(), c.as_i64x4())) } + unsafe { transmute(simd_funnel_shl(a.as_i64x4(), b.as_i64x4(), c.as_i64x4())) } } /// Concatenate packed 64-bit integers in a and b producing an intermediate 128-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -578,7 +578,7 @@ pub fn _mm256_maskz_shldv_epi64(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] pub fn _mm_shldv_epi64(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshldvq128(a.as_i64x2(), b.as_i64x2(), c.as_i64x2())) } + unsafe { transmute(simd_funnel_shl(a.as_i64x2(), b.as_i64x2(), c.as_i64x2())) } } /// Concatenate packed 64-bit integers in a and b producing an intermediate 128-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -617,7 +617,7 @@ pub fn _mm_maskz_shldv_epi64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] pub fn _mm512_shldv_epi32(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshldvd(a.as_i32x16(), b.as_i32x16(), c.as_i32x16())) } + unsafe { transmute(simd_funnel_shl(a.as_i32x16(), b.as_i32x16(), c.as_i32x16())) } } /// Concatenate packed 32-bit integers in a and b producing an intermediate 64-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -656,7 +656,7 @@ pub fn _mm512_maskz_shldv_epi32(k: __mmask16, a: __m512i, b: __m512i, c: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] pub fn _mm256_shldv_epi32(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshldvd256(a.as_i32x8(), b.as_i32x8(), c.as_i32x8())) } + unsafe { transmute(simd_funnel_shl(a.as_i32x8(), b.as_i32x8(), c.as_i32x8())) } } /// Concatenate packed 32-bit integers in a and b producing an intermediate 64-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -695,7 +695,7 @@ pub fn _mm256_maskz_shldv_epi32(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] pub fn _mm_shldv_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshldvd128(a.as_i32x4(), b.as_i32x4(), c.as_i32x4())) } + unsafe { transmute(simd_funnel_shl(a.as_i32x4(), b.as_i32x4(), c.as_i32x4())) } } /// Concatenate packed 32-bit integers in a and b producing an intermediate 64-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -734,7 +734,7 @@ pub fn _mm_maskz_shldv_epi32(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] pub fn _mm512_shldv_epi16(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshldvw(a.as_i16x32(), b.as_i16x32(), c.as_i16x32())) } + unsafe { transmute(simd_funnel_shl(a.as_i16x32(), b.as_i16x32(), c.as_i16x32())) } } /// Concatenate packed 16-bit integers in a and b producing an intermediate 32-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -773,7 +773,7 @@ pub fn _mm512_maskz_shldv_epi16(k: __mmask32, a: __m512i, b: __m512i, c: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] pub fn _mm256_shldv_epi16(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshldvw256(a.as_i16x16(), b.as_i16x16(), c.as_i16x16())) } + unsafe { transmute(simd_funnel_shl(a.as_i16x16(), b.as_i16x16(), c.as_i16x16())) } } /// Concatenate packed 16-bit integers in a and b producing an intermediate 32-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -812,7 +812,7 @@ pub fn _mm256_maskz_shldv_epi16(k: __mmask16, a: __m256i, b: __m256i, c: __m256i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] pub fn _mm_shldv_epi16(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshldvw128(a.as_i16x8(), b.as_i16x8(), c.as_i16x8())) } + unsafe { transmute(simd_funnel_shl(a.as_i16x8(), b.as_i16x8(), c.as_i16x8())) } } /// Concatenate packed 16-bit integers in a and b producing an intermediate 32-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -851,7 +851,7 @@ pub fn _mm_maskz_shldv_epi16(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] pub fn _mm512_shrdv_epi64(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshrdvq(b.as_i64x8(), a.as_i64x8(), c.as_i64x8())) } + unsafe { transmute(simd_funnel_shr(b.as_i64x8(), a.as_i64x8(), c.as_i64x8())) } } /// Concatenate packed 64-bit integers in b and a producing an intermediate 128-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -890,7 +890,7 @@ pub fn _mm512_maskz_shrdv_epi64(k: __mmask8, a: __m512i, b: __m512i, c: __m512i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] pub fn _mm256_shrdv_epi64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshrdvq256(b.as_i64x4(), a.as_i64x4(), c.as_i64x4())) } + unsafe { transmute(simd_funnel_shr(b.as_i64x4(), a.as_i64x4(), c.as_i64x4())) } } /// Concatenate packed 64-bit integers in b and a producing an intermediate 128-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -929,7 +929,7 @@ pub fn _mm256_maskz_shrdv_epi64(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] pub fn _mm_shrdv_epi64(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshrdvq128(b.as_i64x2(), a.as_i64x2(), c.as_i64x2())) } + unsafe { transmute(simd_funnel_shr(b.as_i64x2(), a.as_i64x2(), c.as_i64x2())) } } /// Concatenate packed 64-bit integers in b and a producing an intermediate 128-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -968,7 +968,7 @@ pub fn _mm_maskz_shrdv_epi64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] pub fn _mm512_shrdv_epi32(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshrdvd(b.as_i32x16(), a.as_i32x16(), c.as_i32x16())) } + unsafe { transmute(simd_funnel_shr(b.as_i32x16(), a.as_i32x16(), c.as_i32x16())) } } /// Concatenate packed 32-bit integers in b and a producing an intermediate 64-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -1007,7 +1007,7 @@ pub fn _mm512_maskz_shrdv_epi32(k: __mmask16, a: __m512i, b: __m512i, c: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] pub fn _mm256_shrdv_epi32(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshrdvd256(b.as_i32x8(), a.as_i32x8(), c.as_i32x8())) } + unsafe { transmute(simd_funnel_shr(b.as_i32x8(), a.as_i32x8(), c.as_i32x8())) } } /// Concatenate packed 32-bit integers in b and a producing an intermediate 64-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -1046,7 +1046,7 @@ pub fn _mm256_maskz_shrdv_epi32(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] pub fn _mm_shrdv_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshrdvd128(b.as_i32x4(), a.as_i32x4(), c.as_i32x4())) } + unsafe { transmute(simd_funnel_shr(b.as_i32x4(), a.as_i32x4(), c.as_i32x4())) } } /// Concatenate packed 32-bit integers in b and a producing an intermediate 64-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -1085,7 +1085,7 @@ pub fn _mm_maskz_shrdv_epi32(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] pub fn _mm512_shrdv_epi16(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshrdvw(b.as_i16x32(), a.as_i16x32(), c.as_i16x32())) } + unsafe { transmute(simd_funnel_shr(b.as_i16x32(), a.as_i16x32(), c.as_i16x32())) } } /// Concatenate packed 16-bit integers in b and a producing an intermediate 32-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -1124,7 +1124,7 @@ pub fn _mm512_maskz_shrdv_epi16(k: __mmask32, a: __m512i, b: __m512i, c: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] pub fn _mm256_shrdv_epi16(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshrdvw256(b.as_i16x16(), a.as_i16x16(), c.as_i16x16())) } + unsafe { transmute(simd_funnel_shr(b.as_i16x16(), a.as_i16x16(), c.as_i16x16())) } } /// Concatenate packed 16-bit integers in b and a producing an intermediate 32-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -1163,7 +1163,7 @@ pub fn _mm256_maskz_shrdv_epi16(k: __mmask16, a: __m256i, b: __m256i, c: __m256i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] pub fn _mm_shrdv_epi16(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshrdvw128(b.as_i16x8(), a.as_i16x8(), c.as_i16x8())) } + unsafe { transmute(simd_funnel_shr(b.as_i16x8(), a.as_i16x8(), c.as_i16x8())) } } /// Concatenate packed 16-bit integers in b and a producing an intermediate 32-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -2138,44 +2138,6 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.mask.expand.b.128"] fn vpexpandb128(a: i8x16, src: i8x16, mask: u16) -> i8x16; - #[link_name = "llvm.fshl.v8i64"] - fn vpshldvq(a: i64x8, b: i64x8, c: i64x8) -> i64x8; - #[link_name = "llvm.fshl.v4i64"] - fn vpshldvq256(a: i64x4, b: i64x4, c: i64x4) -> i64x4; - #[link_name = "llvm.fshl.v2i64"] - fn vpshldvq128(a: i64x2, b: i64x2, c: i64x2) -> i64x2; - #[link_name = "llvm.fshl.v16i32"] - fn vpshldvd(a: i32x16, b: i32x16, c: i32x16) -> i32x16; - #[link_name = "llvm.fshl.v8i32"] - fn vpshldvd256(a: i32x8, b: i32x8, c: i32x8) -> i32x8; - #[link_name = "llvm.fshl.v4i32"] - fn vpshldvd128(a: i32x4, b: i32x4, c: i32x4) -> i32x4; - #[link_name = "llvm.fshl.v32i16"] - fn vpshldvw(a: i16x32, b: i16x32, c: i16x32) -> i16x32; - #[link_name = "llvm.fshl.v16i16"] - fn vpshldvw256(a: i16x16, b: i16x16, c: i16x16) -> i16x16; - #[link_name = "llvm.fshl.v8i16"] - fn vpshldvw128(a: i16x8, b: i16x8, c: i16x8) -> i16x8; - - #[link_name = "llvm.fshr.v8i64"] - fn vpshrdvq(a: i64x8, b: i64x8, c: i64x8) -> i64x8; - #[link_name = "llvm.fshr.v4i64"] - fn vpshrdvq256(a: i64x4, b: i64x4, c: i64x4) -> i64x4; - #[link_name = "llvm.fshr.v2i64"] - fn vpshrdvq128(a: i64x2, b: i64x2, c: i64x2) -> i64x2; - #[link_name = "llvm.fshr.v16i32"] - fn vpshrdvd(a: i32x16, b: i32x16, c: i32x16) -> i32x16; - #[link_name = "llvm.fshr.v8i32"] - fn vpshrdvd256(a: i32x8, b: i32x8, c: i32x8) -> i32x8; - #[link_name = "llvm.fshr.v4i32"] - fn vpshrdvd128(a: i32x4, b: i32x4, c: i32x4) -> i32x4; - #[link_name = "llvm.fshr.v32i16"] - fn vpshrdvw(a: i16x32, b: i16x32, c: i16x32) -> i16x32; - #[link_name = "llvm.fshr.v16i16"] - fn vpshrdvw256(a: i16x16, b: i16x16, c: i16x16) -> i16x16; - #[link_name = "llvm.fshr.v8i16"] - fn vpshrdvw128(a: i16x8, b: i16x8, c: i16x8) -> i16x8; - #[link_name = "llvm.x86.avx512.mask.expand.load.b.128"] fn expandloadb_128(mem_addr: *const i8, a: i8x16, mask: u16) -> i8x16; #[link_name = "llvm.x86.avx512.mask.expand.load.w.128"] diff --git a/library/stdarch/crates/core_arch/src/x86/kl.rs b/library/stdarch/crates/core_arch/src/x86/kl.rs index eb9eb83f411..26e5a46c629 100644 --- a/library/stdarch/crates/core_arch/src/x86/kl.rs +++ b/library/stdarch/crates/core_arch/src/x86/kl.rs @@ -127,7 +127,7 @@ unsafe extern "unadjusted" { /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadiwkey) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(loadiwkey))] pub unsafe fn _mm_loadiwkey( control: u32, @@ -153,7 +153,7 @@ pub unsafe fn _mm_loadiwkey( /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_encodekey128_u32) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(encodekey128))] pub unsafe fn _mm_encodekey128_u32(key_params: u32, key: __m128i, handle: *mut u8) -> u32 { let EncodeKey128Output(control, key0, key1, key2, _, _, _) = encodekey128(key_params, key); @@ -176,7 +176,7 @@ pub unsafe fn _mm_encodekey128_u32(key_params: u32, key: __m128i, handle: *mut u /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_encodekey256_u32) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(encodekey256))] pub unsafe fn _mm_encodekey256_u32( key_params: u32, @@ -198,7 +198,7 @@ pub unsafe fn _mm_encodekey256_u32( /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc128kl_u8) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesenc128kl))] pub unsafe fn _mm_aesenc128kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 { let AesOutput(status, result) = aesenc128kl(input, handle); @@ -214,7 +214,7 @@ pub unsafe fn _mm_aesenc128kl_u8(output: *mut __m128i, input: __m128i, handle: * /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec128kl_u8) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesdec128kl))] pub unsafe fn _mm_aesdec128kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 { let AesOutput(status, result) = aesdec128kl(input, handle); @@ -230,7 +230,7 @@ pub unsafe fn _mm_aesdec128kl_u8(output: *mut __m128i, input: __m128i, handle: * /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc256kl_u8) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesenc256kl))] pub unsafe fn _mm_aesenc256kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 { let AesOutput(status, result) = aesenc256kl(input, handle); @@ -246,7 +246,7 @@ pub unsafe fn _mm_aesenc256kl_u8(output: *mut __m128i, input: __m128i, handle: * /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec256kl_u8) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesdec256kl))] pub unsafe fn _mm_aesdec256kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 { let AesOutput(status, result) = aesdec256kl(input, handle); @@ -262,7 +262,7 @@ pub unsafe fn _mm_aesdec256kl_u8(output: *mut __m128i, input: __m128i, handle: * /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesencwide128kl_u8) #[inline] #[target_feature(enable = "widekl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesencwide128kl))] pub unsafe fn _mm_aesencwide128kl_u8( output: *mut __m128i, @@ -285,7 +285,7 @@ pub unsafe fn _mm_aesencwide128kl_u8( /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdecwide128kl_u8) #[inline] #[target_feature(enable = "widekl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesdecwide128kl))] pub unsafe fn _mm_aesdecwide128kl_u8( output: *mut __m128i, @@ -308,7 +308,7 @@ pub unsafe fn _mm_aesdecwide128kl_u8( /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesencwide256kl_u8) #[inline] #[target_feature(enable = "widekl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesencwide256kl))] pub unsafe fn _mm_aesencwide256kl_u8( output: *mut __m128i, @@ -331,7 +331,7 @@ pub unsafe fn _mm_aesencwide256kl_u8( /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdecwide256kl_u8) #[inline] #[target_feature(enable = "widekl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesdecwide256kl))] pub unsafe fn _mm_aesdecwide256kl_u8( output: *mut __m128i, diff --git a/library/stdarch/crates/core_arch/src/x86/mod.rs b/library/stdarch/crates/core_arch/src/x86/mod.rs index 8897258c7dc..79a593e647f 100644 --- a/library/stdarch/crates/core_arch/src/x86/mod.rs +++ b/library/stdarch/crates/core_arch/src/x86/mod.rs @@ -772,5 +772,5 @@ mod avx512fp16; pub use self::avx512fp16::*; mod kl; -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] pub use self::kl::*; diff --git a/library/stdarch/crates/core_arch/src/x86/sha.rs b/library/stdarch/crates/core_arch/src/x86/sha.rs index da568c449a6..9ad1a9f14c1 100644 --- a/library/stdarch/crates/core_arch/src/x86/sha.rs +++ b/library/stdarch/crates/core_arch/src/x86/sha.rs @@ -146,7 +146,7 @@ pub fn _mm_sha256rnds2_epu32(a: __m128i, b: __m128i, k: __m128i) -> __m128i { #[inline] #[target_feature(enable = "sha512,avx")] #[cfg_attr(test, assert_instr(vsha512msg1))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm256_sha512msg1_epi64(a: __m256i, b: __m128i) -> __m256i { unsafe { transmute(vsha512msg1(a.as_i64x4(), b.as_i64x2())) } } @@ -159,7 +159,7 @@ pub fn _mm256_sha512msg1_epi64(a: __m256i, b: __m128i) -> __m256i { #[inline] #[target_feature(enable = "sha512,avx")] #[cfg_attr(test, assert_instr(vsha512msg2))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm256_sha512msg2_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(vsha512msg2(a.as_i64x4(), b.as_i64x4())) } } @@ -175,7 +175,7 @@ pub fn _mm256_sha512msg2_epi64(a: __m256i, b: __m256i) -> __m256i { #[inline] #[target_feature(enable = "sha512,avx")] #[cfg_attr(test, assert_instr(vsha512rnds2))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm256_sha512rnds2_epi64(a: __m256i, b: __m256i, k: __m128i) -> __m256i { unsafe { transmute(vsha512rnds2(a.as_i64x4(), b.as_i64x4(), k.as_i64x2())) } } @@ -188,7 +188,7 @@ pub fn _mm256_sha512rnds2_epi64(a: __m256i, b: __m256i, k: __m128i) -> __m256i { #[inline] #[target_feature(enable = "sm3,avx")] #[cfg_attr(test, assert_instr(vsm3msg1))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm_sm3msg1_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { transmute(vsm3msg1(a.as_i32x4(), b.as_i32x4(), c.as_i32x4())) } } @@ -201,7 +201,7 @@ pub fn _mm_sm3msg1_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { #[inline] #[target_feature(enable = "sm3,avx")] #[cfg_attr(test, assert_instr(vsm3msg2))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm_sm3msg2_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { transmute(vsm3msg2(a.as_i32x4(), b.as_i32x4(), c.as_i32x4())) } } @@ -219,7 +219,7 @@ pub fn _mm_sm3msg2_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { #[target_feature(enable = "sm3,avx")] #[cfg_attr(test, assert_instr(vsm3rnds2, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm_sm3rnds2_epi32<const IMM8: i32>(a: __m128i, b: __m128i, c: __m128i) -> __m128i { static_assert!( IMM8 == (IMM8 & 0x3e), @@ -235,7 +235,7 @@ pub fn _mm_sm3rnds2_epi32<const IMM8: i32>(a: __m128i, b: __m128i, c: __m128i) - #[inline] #[target_feature(enable = "sm4,avx")] #[cfg_attr(test, assert_instr(vsm4key4))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm_sm4key4_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(vsm4key4128(a.as_i32x4(), b.as_i32x4())) } } @@ -247,7 +247,7 @@ pub fn _mm_sm4key4_epi32(a: __m128i, b: __m128i) -> __m128i { #[inline] #[target_feature(enable = "sm4,avx")] #[cfg_attr(test, assert_instr(vsm4key4))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm256_sm4key4_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(vsm4key4256(a.as_i32x8(), b.as_i32x8())) } } @@ -259,7 +259,7 @@ pub fn _mm256_sm4key4_epi32(a: __m256i, b: __m256i) -> __m256i { #[inline] #[target_feature(enable = "sm4,avx")] #[cfg_attr(test, assert_instr(vsm4rnds4))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm_sm4rnds4_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(vsm4rnds4128(a.as_i32x4(), b.as_i32x4())) } } @@ -271,7 +271,7 @@ pub fn _mm_sm4rnds4_epi32(a: __m128i, b: __m128i) -> __m128i { #[inline] #[target_feature(enable = "sm4,avx")] #[cfg_attr(test, assert_instr(vsm4rnds4))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm256_sm4rnds4_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(vsm4rnds4256(a.as_i32x8(), b.as_i32x8())) } } diff --git a/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs b/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs index 46a008245bf..d3e7f62903b 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs @@ -48,7 +48,7 @@ pub unsafe fn cmpxchg16b( success: Ordering, failure: Ordering, ) -> u128 { - debug_assert!(dst as usize % 16 == 0); + debug_assert!(dst.addr().is_multiple_of(16)); let res = crate::sync::atomic::atomic_compare_exchange(dst, old, new, success, failure); res.unwrap_or_else(|x| x) diff --git a/library/stdarch/crates/intrinsic-test/src/common/compare.rs b/library/stdarch/crates/intrinsic-test/src/common/compare.rs index 815ccf89fc6..9e0cbe8cd6a 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/compare.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/compare.rs @@ -48,7 +48,7 @@ pub fn compare_outputs( return Some(FailureReason::RunRust(intrinsic_name.clone())); } - info!("Comparing intrinsic: {}", intrinsic_name); + info!("Comparing intrinsic: {intrinsic_name}"); let c = std::str::from_utf8(&c.stdout) .unwrap() diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs index 84c28cc4bf4..1cfb66c39b9 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs @@ -79,7 +79,7 @@ pub fn compile_c_programs(compiler_commands: &[String]) -> bool { false } } else { - error!("Command failed: {:#?}", output); + error!("Command failed: {output:#?}"); false } }) diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs index a2878502ac9..52bccaf905c 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs @@ -120,7 +120,7 @@ path = "{binary}/main.rs""#, false } } else { - error!("Command failed: {:#?}", output); + error!("Command failed: {output:#?}"); false } } diff --git a/library/stdarch/crates/simd-test-macro/src/lib.rs b/library/stdarch/crates/simd-test-macro/src/lib.rs index 18e4747d94d..855e969e1eb 100644 --- a/library/stdarch/crates/simd-test-macro/src/lib.rs +++ b/library/stdarch/crates/simd-test-macro/src/lib.rs @@ -89,7 +89,7 @@ pub fn simd_test( for feature in target_features { let q = quote_spanned! { proc_macro2::Span::call_site() => - if !#macro_test!(#feature) { + if !::std::arch::#macro_test!(#feature) { missing_features.push(#feature); } }; diff --git a/library/stdarch/crates/std_detect/src/detect/arch/x86.rs b/library/stdarch/crates/std_detect/src/detect/arch/x86.rs index f23cfc33417..28b3e3cfb35 100644 --- a/library/stdarch/crates/std_detect/src/detect/arch/x86.rs +++ b/library/stdarch/crates/std_detect/src/detect/arch/x86.rs @@ -157,11 +157,11 @@ features! { /// AVX (Advanced Vector Extensions) @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx2: "avx2"; /// AVX2 (Advanced Vector Extensions 2) - @FEATURE: #[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] sha512: "sha512"; + @FEATURE: #[stable(feature = "sha512_sm_x86", since = "1.89.0")] sha512: "sha512"; /// SHA512 - @FEATURE: #[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] sm3: "sm3"; + @FEATURE: #[stable(feature = "sha512_sm_x86", since = "1.89.0")] sm3: "sm3"; /// SM3 - @FEATURE: #[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] sm4: "sm4"; + @FEATURE: #[stable(feature = "sha512_sm_x86", since = "1.89.0")] sm4: "sm4"; /// SM4 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512f: "avx512f" ; /// AVX-512 F (Foundation) @@ -259,9 +259,9 @@ features! { /// XSAVEC (Save Processor Extended States Compacted) @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] cmpxchg16b: "cmpxchg16b"; /// CMPXCH16B (16-byte compare-and-swap instruction) - @FEATURE: #[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] kl: "kl"; + @FEATURE: #[stable(feature = "keylocker_x86", since = "1.89.0")] kl: "kl"; /// Intel Key Locker - @FEATURE: #[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] widekl: "widekl"; + @FEATURE: #[stable(feature = "keylocker_x86", since = "1.89.0")] widekl: "widekl"; /// Intel Key Locker Wide @FEATURE: #[stable(feature = "simd_x86_adx", since = "1.33.0")] adx: "adx"; /// ADX, Intel ADX (Multi-Precision Add-Carry Instruction Extensions) diff --git a/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs b/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs index 5506ff31fc7..db20538af95 100644 --- a/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs +++ b/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs @@ -25,6 +25,13 @@ struct riscv_hwprobe { value: u64, } +impl riscv_hwprobe { + // key is overwritten to -1 if not supported by riscv_hwprobe syscall. + pub fn get(&self) -> Option<u64> { + (self.key != -1).then_some(self.value) + } +} + #[allow(non_upper_case_globals)] const __NR_riscv_hwprobe: libc::c_long = 258; @@ -124,8 +131,7 @@ fn _riscv_hwprobe(out: &mut [riscv_hwprobe]) -> bool { } } - let len = out.len(); - unsafe { __riscv_hwprobe(out.as_mut_ptr(), len, 0, ptr::null_mut(), 0) == 0 } + unsafe { __riscv_hwprobe(out.as_mut_ptr(), out.len(), 0, ptr::null_mut(), 0) == 0 } } /// Read list of supported features from (1) the auxiliary vector @@ -156,49 +162,45 @@ pub(crate) fn detect_features() -> cache::Initializer { // Use riscv_hwprobe syscall to query more extensions and // performance-related capabilities. 'hwprobe: { - let mut out = [ - riscv_hwprobe { - key: RISCV_HWPROBE_KEY_BASE_BEHAVIOR, - value: 0, - }, - riscv_hwprobe { - key: RISCV_HWPROBE_KEY_IMA_EXT_0, - value: 0, - }, - riscv_hwprobe { - key: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF, - value: 0, - }, - riscv_hwprobe { - key: RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF, - value: 0, - }, - riscv_hwprobe { - key: RISCV_HWPROBE_KEY_CPUPERF_0, - value: 0, - }, - ]; - if !_riscv_hwprobe(&mut out) { + macro_rules! init { + { $($name: ident : $key: expr),* $(,)? } => { + #[repr(usize)] + enum Indices { $($name),* } + let mut t = [$(riscv_hwprobe { key: $key, value: 0 }),*]; + macro_rules! data_mut { () => { &mut t } } + macro_rules! query { [$idx: ident] => { t[Indices::$idx as usize].get() } } + } + } + init! { + BaseBehavior: RISCV_HWPROBE_KEY_BASE_BEHAVIOR, + Extensions: RISCV_HWPROBE_KEY_IMA_EXT_0, + MisalignedScalarPerf: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF, + MisalignedVectorPerf: RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF, + MisalignedScalarPerfFallback: RISCV_HWPROBE_KEY_CPUPERF_0, + }; + if !_riscv_hwprobe(data_mut!()) { break 'hwprobe; } - // Query scalar/vector misaligned behavior. - if out[2].key != -1 { + // Query scalar misaligned behavior. + if let Some(value) = query![MisalignedScalarPerf] { enable_feature( Feature::unaligned_scalar_mem, - out[2].value == RISCV_HWPROBE_MISALIGNED_SCALAR_FAST, + value == RISCV_HWPROBE_MISALIGNED_SCALAR_FAST, ); - } else if out[4].key != -1 { + } else if let Some(value) = query![MisalignedScalarPerfFallback] { // Deprecated method for fallback enable_feature( Feature::unaligned_scalar_mem, - out[4].value & RISCV_HWPROBE_MISALIGNED_MASK == RISCV_HWPROBE_MISALIGNED_FAST, + value & RISCV_HWPROBE_MISALIGNED_MASK == RISCV_HWPROBE_MISALIGNED_FAST, ); } - if out[3].key != -1 { + + // Query vector misaligned behavior. + if let Some(value) = query![MisalignedVectorPerf] { enable_feature( Feature::unaligned_vector_mem, - out[3].value == RISCV_HWPROBE_MISALIGNED_VECTOR_FAST, + value == RISCV_HWPROBE_MISALIGNED_VECTOR_FAST, ); } @@ -208,22 +210,20 @@ pub(crate) fn detect_features() -> cache::Initializer { // 20240411). // This is a current requirement of // `RISCV_HWPROBE_KEY_IMA_EXT_0`-based tests. - let has_ima = (out[0].key != -1) && (out[0].value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA != 0); - if !has_ima { + if query![BaseBehavior].is_none_or(|value| value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA == 0) { break 'hwprobe; } - has_i |= has_ima; - enable_feature(Feature::zicsr, has_ima); - enable_feature(Feature::zicntr, has_ima); - enable_feature(Feature::zifencei, has_ima); - enable_feature(Feature::m, has_ima); - enable_feature(Feature::a, has_ima); + has_i = true; + enable_feature(Feature::zicsr, true); + enable_feature(Feature::zicntr, true); + enable_feature(Feature::zifencei, true); + enable_feature(Feature::m, true); + enable_feature(Feature::a, true); // Enable features based on `RISCV_HWPROBE_KEY_IMA_EXT_0`. - if out[1].key == -1 { + let Some(ima_ext_0) = query![Extensions] else { break 'hwprobe; - } - let ima_ext_0 = out[1].value; + }; let test = |mask| (ima_ext_0 & mask) != 0; enable_feature(Feature::d, test(RISCV_HWPROBE_IMA_FD)); // F is implied. diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index f658267b9a1..f0dce681d9c 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -1252,7 +1252,7 @@ intrinsics: - [i16, f16, 'h', 'i32', 'as i32'] compose: - FnCall: [static_assert!, ['N >= 1 && N <= 16']] - - "vcvt{type[2]}_n_{type[1]}_{type[3]}::<N>(a {type[4]}) as {type[1]}" + - "vcvt{type[2]}_n_{type[1]}_{type[3]}::<N>(a {type[4]})" - name: "vcvt{type[2]}_n_{type[1]}_{type[0]}" @@ -1270,7 +1270,7 @@ intrinsics: - [u16, f16, 'h', u32] compose: - FnCall: [static_assert!, ['N >= 1 && N <= 16']] - - "vcvt{type[2]}_n_{type[1]}_{type[3]}::<N>(a as {type[3]}) as {type[1]}" + - "vcvt{type[2]}_n_{type[1]}_{type[3]}::<N>(a as {type[3]})" - name: "vcvt{type[2]}" @@ -2976,11 +2976,7 @@ intrinsics: - float64x1_t - float64x2_t compose: - - LLVMLink: - name: "llvm.rint.{neon_type}" - links: - - link: "llvm.rint.{neon_type}" - arch: aarch64,arm64ec + - FnCall: [simd_round_ties_even, [a]] - name: "vrndx{neon_type.no}" @@ -2996,11 +2992,7 @@ intrinsics: - float16x4_t - float16x8_t compose: - - LLVMLink: - name: "llvm.rint.{neon_type}" - links: - - link: "llvm.rint.{neon_type}" - arch: aarch64,arm64ec + - FnCall: [simd_round_ties_even, [a]] - name: "vrndx{type[1]}{type[0]}" @@ -5391,7 +5383,7 @@ intrinsics: attr: - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [fmulx, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['2']] - - *neon-fp16 + - *neon-fp16 - *neon-unstable-f16 static_defs: ["const LANE: i32"] safety: safe @@ -5444,7 +5436,7 @@ intrinsics: attr: - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [fmulx, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['2']] - - *neon-fp16 + - *neon-fp16 - *neon-unstable-f16 static_defs: ["const LANE: i32"] safety: safe @@ -5468,7 +5460,7 @@ intrinsics: return_type: "{neon_type[0]}" attr: - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [fmulx]]}]] - - *neon-fp16 + - *neon-fp16 - *neon-unstable-f16 safety: safe types: @@ -5552,7 +5544,7 @@ intrinsics: arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {type[1]}"] return_type: "{neon_type[0]}" attr: - - *neon-fp16 + - *neon-fp16 - *neon-unstable-f16 assert_instr: [fmla] safety: safe @@ -7320,7 +7312,7 @@ intrinsics: - ["i64", "i32", "i32", "i64"] compose: - Let: [x, i64, {FnCall: [vqaddd_s64, [a, {FnCall: [vqdmulls_s32, [b, c]]}]]}] - - Identifier: ['x as i64', Symbol] + - Identifier: ['x', Symbol] - name: "vqdmlal{type[4]}" doc: "Signed saturating doubling multiply-add long" @@ -7434,7 +7426,7 @@ intrinsics: - ["i64", "i32", "i32", "i64"] compose: - Let: [x, i64, {FnCall: [vqsubd_s64, [a, {FnCall: [vqdmulls_s32, [b, c]]}]]}] - - Identifier: ['x as i64', Symbol] + - Identifier: ['x', Symbol] - name: "vqdmlsl{type[4]}" doc: "Signed saturating doubling multiply-subtract long" @@ -11697,7 +11689,6 @@ intrinsics: arguments: ["a: {type[1]}"] return_type: "{type[1]}" attr: - - *neon-fp16 - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [frsqrte]]}]] - *neon-fp16 - *neon-unstable-f16 @@ -12104,7 +12095,7 @@ intrinsics: - [uint8x8_t, 'uint8x8_t', 'b'] - [poly8x8_t, 'uint8x8_t', 'b'] compose: - - FnCall: + - FnCall: - 'vqtbl1{neon_type[0].no}' - - FnCall: - 'vcombine{neon_type[0].no}' @@ -12174,7 +12165,7 @@ intrinsics: - '{type[2]}_t' - - FnCall: ['vcombine{neon_type[1].no}', ['a.0', 'a.1']] - FnCall: ['vcombine{neon_type[1].no}', ['a.2', 'unsafe {{ crate::mem::zeroed() }}']] - - FnCall: + - FnCall: - transmute - - FnCall: - vqtbl2 @@ -12193,7 +12184,7 @@ intrinsics: types: - [uint8x8x3_t, 'uint8x8_t', 'uint8x16x2', 'uint8x8_t'] - [poly8x8x3_t, 'uint8x8_t', 'poly8x16x2', 'poly8x8_t'] - big_endian_inverse: true + big_endian_inverse: true compose: - Let: - x @@ -12201,7 +12192,7 @@ intrinsics: - '{type[2]}_t' - - FnCall: ['vcombine{neon_type[3].no}', ['a.0', 'a.1']] - FnCall: ['vcombine{neon_type[3].no}', ['a.2', 'unsafe {{ crate::mem::zeroed() }}']] - - FnCall: + - FnCall: - transmute - - FnCall: - vqtbl2 @@ -12288,18 +12279,16 @@ intrinsics: - [poly8x8_t, "poly8x16_t", uint8x8_t, "vqtbx1", "_p8"] - [uint8x16_t, "uint8x16_t", uint8x16_t, "vqtbx1q", "q_u8"] - [poly8x16_t, "poly8x16_t", uint8x16_t, "vqtbx1q", "q_p8"] + big_endian_inverse: false compose: - - Let: - - x - - FnCall: - - transmute - - - FnCall: - - "{type[3]}" - - - FnCall: [transmute, [a]] - - FnCall: [transmute, [b]] - - c - - Identifier: [x, Symbol] - + - FnCall: + - transmute + - - FnCall: + - "{type[3]}" + - - FnCall: [transmute, [a]] + - FnCall: [transmute, [b]] + - c + - name: "vtbx1{neon_type[0].no}" doc: "Extended table look-up" arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {neon_type[1]}"] @@ -12315,13 +12304,13 @@ intrinsics: compose: - FnCall: - simd_select - - - FnCall: + - - FnCall: - "simd_lt::<{type[4]}_t, int8x8_t>" - - c - FnCall: [transmute, ["{type[3]}"]] - FnCall: - transmute - - - FnCall: + - - FnCall: - "vqtbx1" - - "transmute(a)" - FnCall: @@ -12470,16 +12459,14 @@ intrinsics: - ['poly8x16_t', uint8x8_t, 'vqtbl1', 'poly8x8_t'] - ['uint8x16_t', uint8x16_t, 'vqtbl1q', 'uint8x16_t'] - ['poly8x16_t', uint8x16_t, 'vqtbl1q', 'poly8x16_t'] + big_endian_inverse: false compose: - - Let: - - x - - FnCall: - - transmute - - - FnCall: - - '{type[2]}' - - - FnCall: [transmute, ['a']] - - b - - Identifier: [x, Symbol] + - FnCall: + - transmute + - - FnCall: + - '{type[2]}' + - - FnCall: [transmute, ['a']] + - b - name: "vqtbl2{neon_type[3].no}" doc: "Table look-up" @@ -12511,7 +12498,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[2]}' - - FnCall: [transmute, ['a.0']] - FnCall: [transmute, ['a.1']] @@ -12547,7 +12534,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[3]}' - - FnCall: [transmute, [a]] - FnCall: [transmute, ['b.0']] @@ -12584,7 +12571,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[3]}' - - FnCall: [transmute, ['a.0']] - FnCall: [transmute, ['a.1']] @@ -12621,7 +12608,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[3]}' - - FnCall: [transmute, [a]] - FnCall: [transmute, ['b.0']] @@ -12659,7 +12646,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[2]}' - - FnCall: [transmute, ['a.0']] - FnCall: [transmute, ['a.1']] @@ -12697,7 +12684,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[3]}' - - FnCall: [transmute, [a]] - FnCall: [transmute, ['b.0']] @@ -13204,7 +13191,7 @@ intrinsics: assert_instr: [addp] safety: safe types: - - [int32x2_t, i32] + - [int32x2_t, i32] compose: - LLVMLink: name: "vaddv{neon_type[0].no}" @@ -13259,7 +13246,7 @@ intrinsics: assert_instr: [addp] safety: safe types: - - [uint32x2_t, u32, i32] + - [uint32x2_t, u32, i32] compose: - LLVMLink: name: "vaddv{neon_type[0].no}" @@ -13335,7 +13322,7 @@ intrinsics: types: - [int8x8_t, i8, 'smaxv'] - [int16x4_t, i16, 'smaxv'] - - [int32x2_t, i32, 'smaxp'] + - [int32x2_t, i32, 'smaxp'] - [int8x16_t, i8, 'smaxv'] - [int16x8_t, i16, 'smaxv'] - [int32x4_t, i32, 'smaxv'] @@ -13357,7 +13344,7 @@ intrinsics: types: - [uint8x8_t, u8, 'umaxv'] - [uint16x4_t, u16, 'umaxv'] - - [uint32x2_t, u32, 'umaxp'] + - [uint32x2_t, u32, 'umaxp'] - [uint8x16_t, u8, 'umaxv'] - [uint16x8_t, u16, 'umaxv'] - [uint32x4_t, u32, 'umaxv'] @@ -13379,7 +13366,7 @@ intrinsics: types: - [float32x2_t, f32, 'fmaxp'] - [float32x4_t, f32, 'fmaxv'] - - [float64x2_t, f64, 'fmaxp'] + - [float64x2_t, f64, 'fmaxp'] compose: - LLVMLink: name: "vmaxv{neon_type[0].no}" @@ -13398,7 +13385,7 @@ intrinsics: types: - [int8x8_t, i8, 'sminv'] - [int16x4_t, i16, 'sminv'] - - [int32x2_t, i32, 'sminp'] + - [int32x2_t, i32, 'sminp'] - [int8x16_t, i8, 'sminv'] - [int16x8_t, i16, 'sminv'] - [int32x4_t, i32, 'sminv'] @@ -13420,7 +13407,7 @@ intrinsics: types: - [uint8x8_t, u8, 'uminv'] - [uint16x4_t, u16, 'uminv'] - - [uint32x2_t, u32, 'uminp'] + - [uint32x2_t, u32, 'uminp'] - [uint8x16_t, u8, 'uminv'] - [uint16x8_t, u16, 'uminv'] - [uint32x4_t, u32, 'uminv'] @@ -13442,7 +13429,7 @@ intrinsics: types: - [float32x2_t, f32, 'fminp'] - [float32x4_t, f32, 'fminv'] - - [float64x2_t, f64, 'fminp'] + - [float64x2_t, f64, 'fminp'] compose: - LLVMLink: name: "vminv{neon_type[0].no}" @@ -13498,7 +13485,7 @@ intrinsics: safety: safe types: - float32x4_t - - float64x2_t + - float64x2_t compose: - LLVMLink: name: "vpmin{neon_type.no}" @@ -13554,7 +13541,7 @@ intrinsics: safety: safe types: - float32x4_t - - float64x2_t + - float64x2_t compose: - LLVMLink: name: "vpmax{neon_type.no}" diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index 118f5808f75..07959cf380e 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -11447,14 +11447,14 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [int8x8_t, uint8x8_t, '3', 'const { int8x8_t([N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8]) }'] - - [int16x4_t, uint16x4_t, '4', 'const { int16x4_t([N as i16, N as i16, N as i16, N as i16]) }'] - - [int32x2_t, uint32x2_t, '5', 'const { int32x2_t([N as i32, N as i32]) }'] + - [int8x8_t, uint8x8_t, '3', 'const { int8x8_t([N as i8; 8]) }'] + - [int16x4_t, uint16x4_t, '4', 'const { int16x4_t([N as i16; 4]) }'] + - [int32x2_t, uint32x2_t, '5', 'const { int32x2_t([N; 2]) }'] - [int64x1_t, uint64x1_t, '6', 'const { int64x1_t([N as i64]) }'] - - [int8x16_t, uint8x16_t, '3', 'const { int8x16_t([N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8]) }'] - - [int16x8_t, uint16x8_t, '4', 'const { int16x8_t([N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16]) }'] - - [int32x4_t, uint32x4_t, '5', 'const { int32x4_t([N as i32, N as i32, N as i32, N as i32]) }'] - - [int64x2_t, uint64x2_t, '6', 'const { int64x2_t([N as i64, N as i64]) }'] + - [int8x16_t, uint8x16_t, '3', 'const { int8x16_t([N as i8; 16]) }'] + - [int16x8_t, uint16x8_t, '4', 'const { int16x8_t([N as i16; 8]) }'] + - [int32x4_t, uint32x4_t, '5', 'const { int32x4_t([N; 4]) }'] + - [int64x2_t, uint64x2_t, '6', 'const { int64x2_t([N as i64; 2]) }'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[2]}"]] - LLVMLink: @@ -11479,14 +11479,14 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [int8x8_t, uint8x8_t, '3', 'const { int8x8_t([N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8]) }'] - - [int16x4_t, uint16x4_t, '4', 'const { int16x4_t([N as i16, N as i16, N as i16, N as i16]) }'] - - [int32x2_t, uint32x2_t, '5', 'const { int32x2_t([N as i32, N as i32]) }'] + - [int8x8_t, uint8x8_t, '3', 'const { int8x8_t([N as i8; 8]) }'] + - [int16x4_t, uint16x4_t, '4', 'const { int16x4_t([N as i16; 4]) }'] + - [int32x2_t, uint32x2_t, '5', 'const { int32x2_t([N; 2]) }'] - [int64x1_t, uint64x1_t, '6', 'const { int64x1_t([N as i64]) }'] - - [int8x16_t, uint8x16_t, '3', 'const { int8x16_t([N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8]) }'] - - [int16x8_t, uint16x8_t, '4', 'const { int16x8_t([N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16]) }'] - - [int32x4_t, uint32x4_t, '5', 'const { int32x4_t([N as i32, N as i32, N as i32, N as i32]) }'] - - [int64x2_t, uint64x2_t, '6', 'const { int64x2_t([N as i64, N as i64]) }'] + - [int8x16_t, uint8x16_t, '3', 'const { int8x16_t([N as i8; 16]) }'] + - [int16x8_t, uint16x8_t, '4', 'const { int16x8_t([N as i16; 8]) }'] + - [int32x4_t, uint32x4_t, '5', 'const { int32x4_t([N; 4]) }'] + - [int64x2_t, uint64x2_t, '6', 'const { int64x2_t([N as i64; 2]) }'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[2]}"]] - LLVMLink: diff --git a/library/stdarch/josh-sync.toml b/library/stdarch/josh-sync.toml new file mode 100644 index 00000000000..ebdb4576287 --- /dev/null +++ b/library/stdarch/josh-sync.toml @@ -0,0 +1,3 @@ +org = "rust-lang" +repo = "stdarch" +path = "library/stdarch" diff --git a/library/stdarch/rust-version b/library/stdarch/rust-version new file mode 100644 index 00000000000..5102178848e --- /dev/null +++ b/library/stdarch/rust-version @@ -0,0 +1 @@ +040e2f8b9ff2d76fbe2146d6003e297ed4532088 diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index c4937c36d4c..290c2eeed44 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -5,6 +5,10 @@ name = "sysroot" version = "0.0.0" edition = "2024" +[lib] +# make sure this crate isn't included in public standard library docs +doc = false + # this is a dummy crate to ensure that all required crates appear in the sysroot [dependencies] proc_macro = { path = "../proc_macro", public = true } diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 2434a278d55..e091c94eb53 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -386,9 +386,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.172" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libredox" @@ -730,9 +730,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b897c8ea620e181c7955369a31be5f48d9a9121cb59fd33ecef9ff2a34323422" +checksum = "aab138f5c1bb35231de19049060a87977ad23e04f2303e953bc5c2947ac7dec4" dependencies = [ "libc", "memchr", diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 073cebdcae2..8dc41d1dec6 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -58,7 +58,7 @@ walkdir = "2.4" xz2 = "0.1" # Dependencies needed by the build-metrics feature -sysinfo = { version = "0.35.0", default-features = false, optional = true, features = ["system"] } +sysinfo = { version = "0.36.0", default-features = false, optional = true, features = ["system"] } # Dependencies needed by the `tracing` feature tracing = { version = "0.1", optional = true, features = ["attributes"] } diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index e1862a451f2..181d71f63c2 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -8,6 +8,7 @@ use std::fs::{self, OpenOptions}; use std::io::{self, BufRead, BufReader, IsTerminal, Write}; use std::str::FromStr; +use std::time::Instant; use std::{env, process}; use bootstrap::{ @@ -17,11 +18,17 @@ use bootstrap::{ #[cfg(feature = "tracing")] use tracing::instrument; +fn is_bootstrap_profiling_enabled() -> bool { + env::var("BOOTSTRAP_PROFILE").is_ok_and(|v| v == "1") +} + #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "main"))] fn main() { #[cfg(feature = "tracing")] let _guard = setup_tracing(); + let start_time = Instant::now(); + let args = env::args().skip(1).collect::<Vec<_>>(); if Flags::try_parse_verbose_help(&args) { @@ -96,7 +103,8 @@ fn main() { let out_dir = config.out.clone(); debug!("creating new build based on config"); - Build::new(config).build(); + let mut build = Build::new(config); + build.build(); if suggest_setup { println!("WARNING: you have not made a `bootstrap.toml`"); @@ -147,6 +155,10 @@ fn main() { t!(file.write_all(lines.join("\n").as_bytes())); } } + + if is_bootstrap_profiling_enabled() { + build.report_summary(start_time); + } } fn check_version(config: &Config) -> Option<String> { @@ -226,7 +238,7 @@ fn setup_tracing() -> impl Drop { let mut chrome_layer = tracing_chrome::ChromeLayerBuilder::new().include_args(true); // Writes the Chrome profile to trace-<unix-timestamp>.json if enabled - if !env::var("BOOTSTRAP_PROFILE").is_ok_and(|v| v == "1") { + if !is_bootstrap_profiling_enabled() { chrome_layer = chrome_layer.writer(io::sink()); } diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 0497bae86a1..3278b55305c 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -47,6 +47,18 @@ impl Step for Std { } fn make_run(run: RunConfig<'_>) { + if !run.builder.download_rustc() && run.builder.config.skip_std_check_if_no_download_rustc { + eprintln!( + "WARNING: `--skip-std-check-if-no-download-rustc` flag was passed and `rust.download-rustc` is not available. Skipping." + ); + return; + } + + if run.builder.config.compile_time_deps { + // libstd doesn't have any important build scripts and can't have any proc macros + return; + } + let crates = std_crates_for_run_make(&run); run.builder.ensure(Std { build_compiler: prepare_compiler_for_check(run.builder, run.target, Mode::Std), @@ -56,13 +68,6 @@ impl Step for Std { } fn run(self, builder: &Builder<'_>) { - if !builder.download_rustc() && builder.config.skip_std_check_if_no_download_rustc { - eprintln!( - "WARNING: `--skip-std-check-if-no-download-rustc` flag was passed and `rust.download-rustc` is not available. Skipping." - ); - return; - } - let build_compiler = self.build_compiler; let stage = build_compiler.stage; let target = self.target; @@ -250,6 +255,13 @@ fn prepare_compiler_for_check( match mode { Mode::ToolBootstrap => builder.compiler(0, host), Mode::ToolStd => { + if builder.config.compile_time_deps { + // When --compile-time-deps is passed, we can't use any rustc + // other than the bootstrap compiler. Luckily build scripts and + // proc macros for tools are unlikely to need nightly. + return builder.compiler(0, host); + } + // These tools require the local standard library to be checked let build_compiler = builder.compiler(builder.top_stage, host); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 0587d21ecc2..1282a89a5e4 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -449,26 +449,24 @@ fn copy_self_contained_objects( target_deps } -/// Resolves standard library crates for `Std::run_make` for any build kind (like check, build, clippy, etc.). +/// Resolves standard library crates for `Std::run_make` for any build kind (like check, doc, +/// build, clippy, etc.). pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec<String> { - // FIXME: Extend builder tests to cover the `crates` field of `Std` instances. - if cfg!(test) { - return vec![]; - } - - let has_alias = run.paths.iter().any(|set| set.assert_single_path().path.ends_with("library")); + let mut crates = run.make_run_crates(builder::Alias::Library); + + // For no_std targets, we only want to check core and alloc + // Regardless of core/alloc being selected explicitly or via the "library" default alias, + // we only want to keep these two crates. + // The set of no_std crates should be kept in sync with what `Builder::std_cargo` does. + // Note: an alternative design would be to return an enum from this function (Default vs Subset) + // of crates. However, several steps currently pass `-p <package>` even if all crates are + // selected, because Cargo behaves differently in that case. To keep that behavior without + // making further changes, we pre-filter the no-std crates here. let target_is_no_std = run.builder.no_std(run.target).unwrap_or(false); - - // For no_std targets, do not add any additional crates to the compilation other than what `compile::std_cargo` already adds for no_std targets. if target_is_no_std { - vec![] - } - // If the paths include "library", build the entire standard library. - else if has_alias { - run.make_run_crates(builder::Alias::Library) - } else { - run.cargo_crates_in_set() + crates.retain(|c| c == "core" || c == "alloc"); } + crates } /// Tries to find LLVM's `compiler-rt` source directory, for building `library/profiler_builtins`. @@ -2576,7 +2574,7 @@ pub fn stream_cargo( } // Make sure Cargo actually succeeded after we read all of its stdout. - let status = t!(streaming_command.wait()); + let status = t!(streaming_command.wait(&builder.config.exec_ctx)); if builder.is_verbose() && !status.success() { eprintln!( "command did not execute successfully: {cmd:?}\n\ diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index f7c4c5ad0bb..37418f640ac 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -665,7 +665,11 @@ impl Step for Std { } fn metadata(&self) -> Option<StepMetadata> { - Some(StepMetadata::doc("std", self.target).stage(self.stage)) + Some( + StepMetadata::doc("std", self.target) + .stage(self.stage) + .with_metadata(format!("crates=[{}]", self.crates.join(","))), + ) } } @@ -739,10 +743,6 @@ fn doc_std( } for krate in requested_crates { - if krate == "sysroot" { - // The sysroot crate is an implementation detail, don't include it in public docs. - continue; - } cargo.arg("-p").arg(krate); } diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 37fc85518e0..9f9af1d9abe 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -586,12 +586,14 @@ Select which editor you would like to set up [default: None]: "; "b5dd299b93dca3ceeb9b335f929293cb3d4bf4977866fbe7ceeac2a8a9f99088", "631c837b0e98ae35fd48b0e5f743b1ca60adadf2d0a2b23566ba25df372cf1a9", "080955765db84bb6cbf178879f489c4e2369397626a6ecb3debedb94a9d0b3ce", + "f501475c6654187091c924ae26187fa5791d74d4a8ab3fb61fbbe4c0275aade1", ], EditorKind::Helix => &[ "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040", "f252dcc30ca85a193a699581e5e929d5bd6c19d40d7a7ade5e257a9517a124a5", "198c195ed0c070d15907b279b8b4ea96198ca71b939f5376454f3d636ab54da5", + "1c43ead340b20792b91d02b08494ee68708e7e09f56b6766629b4b72079208f1", ], EditorKind::Vim | EditorKind::VsCode => &[ "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", @@ -607,12 +609,14 @@ Select which editor you would like to set up [default: None]: "; "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", "701b73751efd7abd6487f2c79348dab698af7ac4427b79fa3d2087c867144b12", + "a61df796c0c007cb6512127330564e49e57d558dec715703916a928b072a1054", ], EditorKind::Zed => &[ "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c", "a5380cf5dd9328731aecc5dfb240d16dac46ed272126b9728006151ef42f5909", "2e96bf0d443852b12f016c8fc9840ab3d0a2b4fe0b0fb3a157e8d74d5e7e0e26", "4fadd4c87389a601a27db0d3d74a142fa3a2e656ae78982e934dbe24bee32ad6", + "f0bb3d23ab1a49175ab0ef5c4071af95bb03d01d460776cdb716d91333443382", ], } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 716bef3f38c..757eac1475c 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -556,8 +556,13 @@ impl Step for Miri { // Miri has its own "target dir" for ui test dependencies. Make sure it gets cleared when // the sysroot gets rebuilt, to avoid "found possibly newer version of crate `std`" errors. if !builder.config.dry_run() { - let ui_test_dep_dir = - builder.stage_out(miri.build_compiler, Mode::ToolStd).join("miri_ui"); + // This has to match `CARGO_TARGET_TMPDIR` in Miri's `ui.rs`. + // This means we need `host` here as that's the target `ui.rs` is built for. + let ui_test_dep_dir = builder + .stage_out(miri.build_compiler, Mode::ToolStd) + .join(host) + .join("tmp") + .join("miri_ui"); // The mtime of `miri_sysroot` changes when the sysroot gets rebuilt (also see // <https://github.com/RalfJung/rustc-build-sysroot/commit/10ebcf60b80fe2c3dc765af0ff19fdc0da4b7466>). // We can hence use that directly as a signal to clear the ui test dir. @@ -680,9 +685,9 @@ impl Step for CargoMiri { cargo.arg("--doc"); } } - - // Finally, pass test-args and run everything. cargo.arg("--").args(builder.config.test_args()); + + // Finally, run everything. let mut cargo = BootstrapCommand::from(cargo); { let _guard = builder.msg_sysroot_tool(Kind::Test, stage, "cargo-miri", host, target); diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 065d7e45e0f..d5a290d804c 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -747,6 +747,12 @@ impl Builder<'_> { // Make cargo emit diagnostics relative to the rustc src dir. cargo.arg(format!("-Zroot-dir={}", self.src.display())); + if self.config.compile_time_deps { + // Build only build scripts and proc-macros for rust-analyzer when requested. + cargo.arg("-Zunstable-options"); + cargo.arg("--compile-time-deps"); + } + // FIXME: Temporary fix for https://github.com/rust-lang/cargo/issues/3005 // Force cargo to output binaries with disambiguating hashes in the name let mut metadata = if compiler.stage == 0 { diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 7464327fde9..4d606953d99 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -146,6 +146,8 @@ pub struct StepMetadata { target: TargetSelection, built_by: Option<Compiler>, stage: Option<u32>, + /// Additional opaque string printed in the metadata + metadata: Option<String>, } impl StepMetadata { @@ -170,7 +172,7 @@ impl StepMetadata { } fn new(name: &'static str, target: TargetSelection, kind: Kind) -> Self { - Self { name, kind, target, built_by: None, stage: None } + Self { name, kind, target, built_by: None, stage: None, metadata: None } } pub fn built_by(mut self, compiler: Compiler) -> Self { @@ -183,6 +185,11 @@ impl StepMetadata { self } + pub fn with_metadata(mut self, metadata: String) -> Self { + self.metadata = Some(metadata); + self + } + pub fn get_stage(&self) -> Option<u32> { self.stage.or(self .built_by diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index bbcb58fca14..51a90649692 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -637,8 +637,8 @@ mod snapshot { use crate::core::build_steps::{compile, dist, doc, test, tool}; use crate::core::builder::tests::{ - TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, configure, configure_with_args, first, - host_target, render_steps, run_build, + RenderConfig, TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, configure, configure_with_args, + first, host_target, render_steps, run_build, }; use crate::core::builder::{Builder, Kind, StepDescription, StepMetadata}; use crate::core::config::TargetSelection; @@ -994,7 +994,7 @@ mod snapshot { [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustdoc 0 <host> - [doc] std 1 <host> + [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] "); } @@ -1043,12 +1043,12 @@ mod snapshot { [build] rustc 1 <host> -> std 1 <host> [build] rustc 1 <host> -> rustc 2 <host> [build] rustdoc 1 <host> - [doc] std 2 <host> + [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] [build] rustc 2 <host> -> std 2 <host> [build] rustc 0 <host> -> LintDocs 1 <host> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> - [doc] std 2 <host> + [doc] std 2 <host> crates=[] [dist] mingw <host> [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> @@ -1075,12 +1075,12 @@ mod snapshot { [build] rustc 1 <host> -> rustc 2 <host> [build] rustc 1 <host> -> WasmComponentLd 2 <host> [build] rustdoc 1 <host> - [doc] std 2 <host> + [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] [build] rustc 2 <host> -> std 2 <host> [build] rustc 0 <host> -> LintDocs 1 <host> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> - [doc] std 2 <host> + [doc] std 2 <host> crates=[] [dist] mingw <host> [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> @@ -1112,15 +1112,15 @@ mod snapshot { [build] rustc 1 <host> -> std 1 <host> [build] rustc 1 <host> -> rustc 2 <host> [build] rustdoc 1 <host> - [doc] std 2 <host> - [doc] std 2 <target1> + [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] + [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] [build] rustc 2 <host> -> std 2 <host> [build] rustc 0 <host> -> LintDocs 1 <host> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> [dist] docs <target1> - [doc] std 2 <host> - [doc] std 2 <target1> + [doc] std 2 <host> crates=[] + [doc] std 2 <target1> crates=[] [dist] mingw <host> [dist] mingw <target1> [build] rustc 0 <host> -> GenerateCopyright 1 <host> @@ -1149,14 +1149,14 @@ mod snapshot { [build] rustc 1 <host> -> std 1 <host> [build] rustc 1 <host> -> rustc 2 <host> [build] rustdoc 1 <host> - [doc] std 2 <host> + [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] [build] rustc 2 <host> -> std 2 <host> [build] rustc 0 <host> -> LintDocs 1 <host> [build] rustc 1 <host> -> std 1 <target1> [build] rustc 2 <host> -> std 2 <target1> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> - [doc] std 2 <host> + [doc] std 2 <host> crates=[] [dist] mingw <host> [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> @@ -1186,8 +1186,8 @@ mod snapshot { [build] rustc 1 <host> -> std 1 <host> [build] rustc 1 <host> -> rustc 2 <host> [build] rustdoc 1 <host> - [doc] std 2 <host> - [doc] std 2 <target1> + [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] + [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] [build] rustc 2 <host> -> std 2 <host> [build] rustc 0 <host> -> LintDocs 1 <host> [build] rustc 1 <host> -> std 1 <target1> @@ -1195,8 +1195,8 @@ mod snapshot { [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> [dist] docs <target1> - [doc] std 2 <host> - [doc] std 2 <target1> + [doc] std 2 <host> crates=[] + [doc] std 2 <target1> crates=[] [dist] mingw <host> [dist] mingw <target1> [build] rustc 0 <host> -> GenerateCopyright 1 <host> @@ -1228,11 +1228,11 @@ mod snapshot { [build] rustc 1 <host> -> std 1 <host> [build] rustc 1 <host> -> rustc 2 <host> [build] rustdoc 1 <host> - [doc] std 2 <target1> + [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] [build] rustc 2 <host> -> std 2 <host> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <target1> - [doc] std 2 <target1> + [doc] std 2 <target1> crates=[] [dist] mingw <target1> [build] rustc 2 <host> -> std 2 <target1> [dist] rustc 2 <host> -> std 2 <target1> @@ -1260,14 +1260,14 @@ mod snapshot { [build] rustc 1 <host> -> rustc 2 <host> [build] rustc 1 <host> -> WasmComponentLd 2 <host> [build] rustdoc 1 <host> - [doc] std 2 <target1> + [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] [build] rustc 2 <host> -> std 2 <host> [build] rustc 1 <host> -> std 1 <target1> [build] rustc 2 <host> -> std 2 <target1> [build] rustc 0 <host> -> LintDocs 1 <host> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <target1> - [doc] std 2 <target1> + [doc] std 2 <target1> crates=[] [dist] mingw <target1> [build] llvm <target1> [build] rustc 1 <host> -> rustc 2 <target1> @@ -1439,6 +1439,30 @@ mod snapshot { "); } + /// Make sure that we don't check library when download-rustc is disabled + /// when `--skip-std-check-if-no-download-rustc` was passed. + #[test] + fn check_library_skip_without_download_rustc() { + let ctx = TestCtx::new(); + let args = ["--set", "rust.download-rustc=false", "--skip-std-check-if-no-download-rustc"]; + insta::assert_snapshot!( + ctx.config("check") + .paths(&["library"]) + .args(&args) + .render_steps(), @""); + + insta::assert_snapshot!( + ctx.config("check") + .paths(&["library", "compiler"]) + .args(&args) + .render_steps(), @r" + [build] llvm <host> + [check] rustc 0 <host> -> rustc 1 <host> + [check] rustc 0 <host> -> cranelift 1 <host> + [check] rustc 0 <host> -> gcc 1 <host> + "); + } + #[test] fn check_miri_no_explicit_stage() { let ctx = TestCtx::new(); @@ -1575,6 +1599,80 @@ mod snapshot { steps.assert_contains(StepMetadata::test("CrateLibrustc", host)); steps.assert_contains_fuzzy(StepMetadata::build("rustc", host)); } + + #[test] + fn doc_library() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("doc") + .path("library") + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustdoc 0 <host> + [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,sysroot,test,unwind] + "); + } + + #[test] + fn doc_core() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("doc") + .path("core") + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustdoc 0 <host> + [doc] std 1 <host> crates=[core] + "); + } + + #[test] + fn doc_core_no_std_target() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("doc") + .path("core") + .override_target_no_std(&host_target()) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustdoc 0 <host> + [doc] std 1 <host> crates=[core] + "); + } + + #[test] + fn doc_library_no_std_target() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("doc") + .path("library") + .override_target_no_std(&host_target()) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustdoc 0 <host> + [doc] std 1 <host> crates=[alloc,core] + "); + } + + #[test] + fn doc_library_no_std_target_cross_compile() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("doc") + .path("library") + .targets(&[TEST_TRIPLE_1]) + .override_target_no_std(TEST_TRIPLE_1) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustdoc 0 <host> + [doc] std 1 <target1> crates=[alloc,core] + "); + } } struct ExecutedSteps { @@ -1583,7 +1681,11 @@ struct ExecutedSteps { impl ExecutedSteps { fn render(&self) -> String { - render_steps(&self.steps) + self.render_with(RenderConfig::default()) + } + + fn render_with(&self, config: RenderConfig) -> String { + render_steps(&self.steps, config) } #[track_caller] @@ -1592,7 +1694,7 @@ impl ExecutedSteps { if !self.contains(&metadata) { panic!( "Metadata `{}` ({metadata:?}) not found in executed steps:\n{}", - render_metadata(&metadata), + render_metadata(&metadata, &RenderConfig::default()), self.render() ); } @@ -1607,7 +1709,7 @@ impl ExecutedSteps { if !self.contains_fuzzy(&metadata) { panic!( "Metadata `{}` ({metadata:?}) not found in executed steps:\n{}", - render_metadata(&metadata), + render_metadata(&metadata, &RenderConfig::default()), self.render() ); } @@ -1619,7 +1721,7 @@ impl ExecutedSteps { if self.contains(&metadata) { panic!( "Metadata `{}` ({metadata:?}) found in executed steps (it should not be there):\n{}", - render_metadata(&metadata), + render_metadata(&metadata, &RenderConfig::default()), self.render() ); } @@ -1641,7 +1743,7 @@ impl ExecutedSteps { } fn fuzzy_metadata_eq(executed: &StepMetadata, to_match: &StepMetadata) -> bool { - let StepMetadata { name, kind, target, built_by: _, stage: _ } = executed; + let StepMetadata { name, kind, target, built_by: _, stage: _, metadata } = executed; *name == to_match.name && *kind == to_match.kind && *target == to_match.target } @@ -1672,6 +1774,16 @@ impl ConfigBuilder { } } +struct RenderConfig { + normalize_host: bool, +} + +impl Default for RenderConfig { + fn default() -> Self { + Self { normalize_host: true } + } +} + /// Renders the executed bootstrap steps for usage in snapshot tests with insta. /// Only renders certain important steps. /// Each value in `steps` should be a tuple of (Step, step output). @@ -1679,7 +1791,7 @@ impl ConfigBuilder { /// The arrow in the rendered output (`X -> Y`) means `X builds Y`. /// This is similar to the output printed by bootstrap to stdout, but here it is /// generated purely for the purpose of tests. -fn render_steps(steps: &[ExecutedStep]) -> String { +fn render_steps(steps: &[ExecutedStep], config: RenderConfig) -> String { steps .iter() .filter_map(|step| { @@ -1689,32 +1801,35 @@ fn render_steps(steps: &[ExecutedStep]) -> String { return None; }; - Some(render_metadata(&metadata)) + Some(render_metadata(&metadata, &config)) }) .collect::<Vec<_>>() .join("\n") } -fn render_metadata(metadata: &StepMetadata) -> String { +fn render_metadata(metadata: &StepMetadata, config: &RenderConfig) -> String { let mut record = format!("[{}] ", metadata.kind.as_str()); if let Some(compiler) = metadata.built_by { - write!(record, "{} -> ", render_compiler(compiler)); + write!(record, "{} -> ", render_compiler(compiler, config)); } let stage = metadata.get_stage().map(|stage| format!("{stage} ")).unwrap_or_default(); - write!(record, "{} {stage}<{}>", metadata.name, normalize_target(metadata.target)); + write!(record, "{} {stage}<{}>", metadata.name, normalize_target(metadata.target, config)); + if let Some(metadata) = &metadata.metadata { + write!(record, " {metadata}"); + } record } -fn normalize_target(target: TargetSelection) -> String { - target - .to_string() - .replace(&host_target(), "host") - .replace(TEST_TRIPLE_1, "target1") - .replace(TEST_TRIPLE_2, "target2") +fn normalize_target(target: TargetSelection, config: &RenderConfig) -> String { + let mut target = target.to_string(); + if config.normalize_host { + target = target.replace(&host_target(), "host"); + } + target.replace(TEST_TRIPLE_1, "target1").replace(TEST_TRIPLE_2, "target2") } -fn render_compiler(compiler: Compiler) -> String { - format!("rustc {} <{}>", compiler.stage, normalize_target(compiler.host)) +fn render_compiler(compiler: Compiler, config: &RenderConfig) -> String { + format!("rustc {} <{}>", compiler.stage, normalize_target(compiler.host, config)) } fn host_target() -> String { diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 59693dc3e4c..0039d44785c 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -110,6 +110,7 @@ pub struct Config { pub include_default_paths: bool, pub rustc_error_format: Option<String>, pub json_output: bool, + pub compile_time_deps: bool, pub test_compare_mode: bool, pub color: Color, pub patch_binaries_for_nix: Option<bool>, @@ -421,6 +422,7 @@ impl Config { jobs: flags_jobs, warnings: flags_warnings, json_output: flags_json_output, + compile_time_deps: flags_compile_time_deps, color: flags_color, bypass_bootstrap_lock: flags_bypass_bootstrap_lock, rust_profile_generate: flags_rust_profile_generate, @@ -468,6 +470,7 @@ impl Config { config.include_default_paths = flags_include_default_paths; config.rustc_error_format = flags_rustc_error_format; config.json_output = flags_json_output; + config.compile_time_deps = flags_compile_time_deps; config.on_fail = flags_on_fail; config.cmd = flags_cmd; config.incremental = flags_incremental; @@ -1064,6 +1067,13 @@ impl Config { _ => {} } + if config.compile_time_deps && !matches!(config.cmd, Subcommand::Check { .. }) { + eprintln!( + "WARNING: Can't use --compile-time-deps with any subcommand other than check." + ); + exit!(1); + } + // CI should always run stage 2 builds, unless it specifically states otherwise #[cfg(not(test))] if flags_stage.is_none() && config.is_running_on_ci { diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index 19e0d3413bb..155b6f58758 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -132,6 +132,9 @@ pub struct Flags { #[arg(global = true, long)] /// use message-format=json pub json_output: bool, + #[arg(global = true, long)] + /// only build proc-macros and build scripts (for rust-analyzer) + pub compile_time_deps: bool, #[arg(global = true, long, value_name = "STYLE")] #[arg(value_enum, default_value_t = Color::Auto)] diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index ef5c28272b8..66a164703b7 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -22,7 +22,7 @@ use std::collections::{BTreeSet, HashMap, HashSet}; use std::fmt::Display; use std::path::{Path, PathBuf}; use std::sync::OnceLock; -use std::time::SystemTime; +use std::time::{Instant, SystemTime}; use std::{env, fs, io, str}; use build_helper::ci::gha; @@ -775,6 +775,9 @@ impl Build { if self.config.rust_randomize_layout && check("rustc_randomized_layouts") { features.push("rustc_randomized_layouts"); } + if self.config.compile_time_deps && kind == Kind::Check { + features.push("check_only"); + } // If debug logging is on, then we want the default for tracing: // https://github.com/tokio-rs/tracing/blob/3dd5c03d907afdf2c39444a29931833335171554/tracing/src/level_filters.rs#L26 @@ -1318,7 +1321,7 @@ impl Build { if let Some(path) = configured { return Some(path.join("lib").join(target.to_string())); } - let mut env_root = PathBuf::from(std::env::var_os("WASI_SDK_PATH")?); + let mut env_root = self.wasi_sdk_path.clone()?; env_root.push("share"); env_root.push("wasi-sysroot"); env_root.push("lib"); @@ -1928,6 +1931,10 @@ to download LLVM rather than building it. pub fn exec_ctx(&self) -> &ExecutionContext { &self.config.exec_ctx } + + pub fn report_summary(&self, start_time: Instant) { + self.config.exec_ctx.profiler().report_summary(start_time); + } } impl AsRef<ExecutionContext> for Build { diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 29591edc9cc..c5d460ac55b 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -466,4 +466,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "The --extra-checks flag now supports prefixing any check with `auto:` to only run it if relevant files are modified", }, + ChangeInfo { + change_id: 143785, + severity: ChangeSeverity::Info, + summary: "A --compile-time-deps flag has been added to reduce the time it takes rust-analyzer to start", + }, ]; diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 487077835ac..209ff393973 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -10,13 +10,17 @@ use std::collections::HashMap; use std::ffi::{OsStr, OsString}; use std::fmt::{Debug, Formatter}; +use std::fs::File; use std::hash::Hash; +use std::io::{BufWriter, Write}; use std::panic::Location; use std::path::Path; +use std::process; use std::process::{ Child, ChildStderr, ChildStdout, Command, CommandArgs, CommandEnvs, ExitStatus, Output, Stdio, }; use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; use build_helper::ci::CiEnv; use build_helper::drop_bomb::DropBomb; @@ -65,13 +69,159 @@ impl OutputMode { } #[derive(Clone, Debug, PartialEq, Eq, Hash, Default)] -pub struct CommandCacheKey { +pub struct CommandFingerprint { program: OsString, args: Vec<OsString>, envs: Vec<(OsString, Option<OsString>)>, cwd: Option<PathBuf>, } +impl CommandFingerprint { + /// Helper method to format both Command and BootstrapCommand as a short execution line, + /// without all the other details (e.g. environment variables). + pub fn format_short_cmd(&self) -> String { + let program = Path::new(&self.program); + let mut line = vec![program.file_name().unwrap().to_str().unwrap().to_owned()]; + line.extend(self.args.iter().map(|arg| arg.to_string_lossy().into_owned())); + line.extend(self.cwd.iter().map(|p| p.to_string_lossy().into_owned())); + line.join(" ") + } +} + +#[derive(Default, Clone)] +pub struct CommandProfile { + pub traces: Vec<ExecutionTrace>, +} + +#[derive(Default)] +pub struct CommandProfiler { + stats: Mutex<HashMap<CommandFingerprint, CommandProfile>>, +} + +impl CommandProfiler { + pub fn record_execution(&self, key: CommandFingerprint, start_time: Instant) { + let mut stats = self.stats.lock().unwrap(); + let entry = stats.entry(key).or_default(); + entry.traces.push(ExecutionTrace::Executed { duration: start_time.elapsed() }); + } + + pub fn record_cache_hit(&self, key: CommandFingerprint) { + let mut stats = self.stats.lock().unwrap(); + let entry = stats.entry(key).or_default(); + entry.traces.push(ExecutionTrace::CacheHit); + } + + pub fn report_summary(&self, start_time: Instant) { + let pid = process::id(); + let filename = format!("bootstrap-profile-{pid}.txt"); + + let file = match File::create(&filename) { + Ok(f) => f, + Err(e) => { + eprintln!("Failed to create profiler output file: {e}"); + return; + } + }; + + let mut writer = BufWriter::new(file); + let stats = self.stats.lock().unwrap(); + + let mut entries: Vec<_> = stats + .iter() + .map(|(key, profile)| { + let max_duration = profile + .traces + .iter() + .filter_map(|trace| match trace { + ExecutionTrace::Executed { duration, .. } => Some(*duration), + _ => None, + }) + .max(); + + (key, profile, max_duration) + }) + .collect(); + + entries.sort_by(|a, b| b.2.cmp(&a.2)); + + let total_bootstrap_duration = start_time.elapsed(); + + let total_fingerprints = entries.len(); + let mut total_cache_hits = 0; + let mut total_execution_duration = Duration::ZERO; + let mut total_saved_duration = Duration::ZERO; + + for (key, profile, max_duration) in &entries { + writeln!(writer, "Command: {:?}", key.format_short_cmd()).unwrap(); + + let mut hits = 0; + let mut runs = 0; + let mut command_total_duration = Duration::ZERO; + + for trace in &profile.traces { + match trace { + ExecutionTrace::CacheHit => { + hits += 1; + } + ExecutionTrace::Executed { duration, .. } => { + runs += 1; + command_total_duration += *duration; + } + } + } + + total_cache_hits += hits; + total_execution_duration += command_total_duration; + // This makes sense only in our current setup, where: + // - If caching is enabled, we record the timing for the initial execution, + // and all subsequent runs will be cache hits. + // - If caching is disabled or unused, there will be no cache hits, + // and we'll record timings for all executions. + total_saved_duration += command_total_duration * hits as u32; + + let command_vs_bootstrap = if total_bootstrap_duration > Duration::ZERO { + 100.0 * command_total_duration.as_secs_f64() + / total_bootstrap_duration.as_secs_f64() + } else { + 0.0 + }; + + let duration_str = match max_duration { + Some(d) => format!("{d:.2?}"), + None => "-".into(), + }; + + writeln!( + writer, + "Summary: {runs} run(s), {hits} hit(s), max_duration={duration_str} total_duration: {command_total_duration:.2?} ({command_vs_bootstrap:.2?}% of total)\n" + ) + .unwrap(); + } + + let overhead_time = total_bootstrap_duration + .checked_sub(total_execution_duration) + .unwrap_or(Duration::ZERO); + + writeln!(writer, "\n=== Aggregated Summary ===").unwrap(); + writeln!(writer, "Total unique commands (fingerprints): {total_fingerprints}").unwrap(); + writeln!(writer, "Total time spent in command executions: {total_execution_duration:.2?}") + .unwrap(); + writeln!(writer, "Total bootstrap time: {total_bootstrap_duration:.2?}").unwrap(); + writeln!(writer, "Time spent outside command executions: {overhead_time:.2?}").unwrap(); + writeln!(writer, "Total cache hits: {total_cache_hits}").unwrap(); + writeln!(writer, "Estimated time saved due to cache hits: {total_saved_duration:.2?}") + .unwrap(); + + println!("Command profiler report saved to {filename}"); + } +} + +#[derive(Clone)] +pub enum ExecutionTrace { + CacheHit, + Executed { duration: Duration }, +} + /// Wrapper around `std::process::Command`. /// /// By default, the command will exit bootstrap if it fails. @@ -244,12 +394,9 @@ impl<'a> BootstrapCommand { } } - pub fn cache_key(&self) -> Option<CommandCacheKey> { - if !self.should_cache { - return None; - } + pub fn fingerprint(&self) -> CommandFingerprint { let command = &self.command; - Some(CommandCacheKey { + CommandFingerprint { program: command.get_program().into(), args: command.get_args().map(OsStr::to_os_string).collect(), envs: command @@ -257,7 +404,7 @@ impl<'a> BootstrapCommand { .map(|(k, v)| (k.to_os_string(), v.map(|val| val.to_os_string()))) .collect(), cwd: command.get_current_dir().map(Path::to_path_buf), - }) + } } } @@ -400,30 +547,6 @@ impl Default for CommandOutput { } } -/// Helper trait to format both Command and BootstrapCommand as a short execution line, -/// without all the other details (e.g. environment variables). -#[cfg(feature = "tracing")] -pub trait FormatShortCmd { - fn format_short_cmd(&self) -> String; -} - -#[cfg(feature = "tracing")] -impl FormatShortCmd for BootstrapCommand { - fn format_short_cmd(&self) -> String { - self.command.format_short_cmd() - } -} - -#[cfg(feature = "tracing")] -impl FormatShortCmd for Command { - fn format_short_cmd(&self) -> String { - let program = Path::new(self.get_program()); - let mut line = vec![program.file_name().unwrap().to_str().unwrap()]; - line.extend(self.get_args().map(|arg| arg.to_str().unwrap())); - line.join(" ") - } -} - #[derive(Clone, Default)] pub struct ExecutionContext { dry_run: DryRun, @@ -431,11 +554,12 @@ pub struct ExecutionContext { pub fail_fast: bool, delayed_failures: Arc<Mutex<Vec<String>>>, command_cache: Arc<CommandCache>, + profiler: Arc<CommandProfiler>, } #[derive(Default)] pub struct CommandCache { - cache: Mutex<HashMap<CommandCacheKey, CommandOutput>>, + cache: Mutex<HashMap<CommandFingerprint, CommandOutput>>, } enum CommandState<'a> { @@ -446,7 +570,10 @@ enum CommandState<'a> { stdout: OutputMode, stderr: OutputMode, executed_at: &'a Location<'a>, - cache_key: Option<CommandCacheKey>, + fingerprint: CommandFingerprint, + start_time: Instant, + #[cfg(feature = "tracing")] + _span_guard: tracing::span::EnteredSpan, }, } @@ -454,6 +581,10 @@ pub struct StreamingCommand { child: Child, pub stdout: Option<ChildStdout>, pub stderr: Option<ChildStderr>, + fingerprint: CommandFingerprint, + start_time: Instant, + #[cfg(feature = "tracing")] + _span_guard: tracing::span::EnteredSpan, } #[must_use] @@ -462,11 +593,11 @@ pub struct DeferredCommand<'a> { } impl CommandCache { - pub fn get(&self, key: &CommandCacheKey) -> Option<CommandOutput> { + pub fn get(&self, key: &CommandFingerprint) -> Option<CommandOutput> { self.cache.lock().unwrap().get(key).cloned() } - pub fn insert(&self, key: CommandCacheKey, output: CommandOutput) { + pub fn insert(&self, key: CommandFingerprint, output: CommandOutput) { self.cache.lock().unwrap().insert(key, output); } } @@ -483,6 +614,10 @@ impl ExecutionContext { } } + pub fn profiler(&self) -> &CommandProfiler { + &self.profiler + } + pub fn get_dry_run(&self) -> &DryRun { &self.dry_run } @@ -539,12 +674,15 @@ impl ExecutionContext { stdout: OutputMode, stderr: OutputMode, ) -> DeferredCommand<'a> { - let cache_key = command.cache_key(); + let fingerprint = command.fingerprint(); - if let Some(cached_output) = cache_key.as_ref().and_then(|key| self.command_cache.get(key)) - { + #[cfg(feature = "tracing")] + let span_guard = trace_cmd!(command); + + if let Some(cached_output) = self.command_cache.get(&fingerprint) { command.mark_as_executed(); self.verbose(|| println!("Cache hit: {command:?}")); + self.profiler.record_cache_hit(fingerprint); return DeferredCommand { state: CommandState::Cached(cached_output) }; } @@ -559,14 +697,14 @@ impl ExecutionContext { stdout, stderr, executed_at, - cache_key, + fingerprint, + start_time: Instant::now(), + #[cfg(feature = "tracing")] + _span_guard: span_guard, }, }; } - #[cfg(feature = "tracing")] - let _run_span = trace_cmd!(command); - self.verbose(|| { println!("running: {command:?} (created at {created_at}, executed at {executed_at})") }); @@ -575,6 +713,8 @@ impl ExecutionContext { cmd.stdout(stdout.stdio()); cmd.stderr(stderr.stdio()); + let start_time = Instant::now(); + let child = cmd.spawn(); DeferredCommand { @@ -584,7 +724,10 @@ impl ExecutionContext { stdout, stderr, executed_at, - cache_key, + fingerprint, + start_time, + #[cfg(feature = "tracing")] + _span_guard: span_guard, }, } } @@ -638,6 +781,12 @@ impl ExecutionContext { if !command.run_in_dry_run && self.dry_run() { return None; } + + #[cfg(feature = "tracing")] + let span_guard = trace_cmd!(command); + + let start_time = Instant::now(); + let fingerprint = command.fingerprint(); let cmd = &mut command.command; cmd.stdout(stdout.stdio()); cmd.stderr(stderr.stdio()); @@ -649,7 +798,15 @@ impl ExecutionContext { let stdout = child.stdout.take(); let stderr = child.stderr.take(); - Some(StreamingCommand { child, stdout, stderr }) + Some(StreamingCommand { + child, + stdout, + stderr, + fingerprint, + start_time, + #[cfg(feature = "tracing")] + _span_guard: span_guard, + }) } } @@ -660,8 +817,14 @@ impl AsRef<ExecutionContext> for ExecutionContext { } impl StreamingCommand { - pub fn wait(mut self) -> Result<ExitStatus, std::io::Error> { - self.child.wait() + pub fn wait( + mut self, + exec_ctx: impl AsRef<ExecutionContext>, + ) -> Result<ExitStatus, std::io::Error> { + let exec_ctx = exec_ctx.as_ref(); + let output = self.child.wait(); + exec_ctx.profiler().record_execution(self.fingerprint, self.start_time); + output } } @@ -669,16 +832,31 @@ impl<'a> DeferredCommand<'a> { pub fn wait_for_output(self, exec_ctx: impl AsRef<ExecutionContext>) -> CommandOutput { match self.state { CommandState::Cached(output) => output, - CommandState::Deferred { process, command, stdout, stderr, executed_at, cache_key } => { + CommandState::Deferred { + process, + command, + stdout, + stderr, + executed_at, + fingerprint, + start_time, + #[cfg(feature = "tracing")] + _span_guard, + } => { let exec_ctx = exec_ctx.as_ref(); let output = Self::finish_process(process, command, stdout, stderr, executed_at, exec_ctx); + #[cfg(feature = "tracing")] + drop(_span_guard); + if (!exec_ctx.dry_run() || command.run_in_dry_run) - && let (Some(cache_key), Some(_)) = (&cache_key, output.status()) + && output.status().is_some() + && command.should_cache { - exec_ctx.command_cache.insert(cache_key.clone(), output.clone()); + exec_ctx.command_cache.insert(fingerprint.clone(), output.clone()); + exec_ctx.profiler.record_execution(fingerprint.clone(), start_time); } output diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index 934699d736b..40006aca5c5 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -63,7 +63,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) -> renderer.render_all(); } - let status = streaming_command.wait().unwrap(); + let status = streaming_command.wait(&builder.config.exec_ctx).unwrap(); if !status.success() && builder.is_verbose() { println!( "\n\ncommand did not execute successfully: {cmd:?}\n\ diff --git a/src/bootstrap/src/utils/tests/mod.rs b/src/bootstrap/src/utils/tests/mod.rs index 5b568c1df5b..ec87e71e0b6 100644 --- a/src/bootstrap/src/utils/tests/mod.rs +++ b/src/bootstrap/src/utils/tests/mod.rs @@ -48,17 +48,30 @@ impl ConfigBuilder { } pub fn path(mut self, path: &str) -> Self { - self.args.push(path.to_string()); - self + self.arg(path) } pub fn paths(mut self, paths: &[&str]) -> Self { - for path in paths { - self = self.path(path); + self.args(paths) + } + + pub fn arg(mut self, arg: &str) -> Self { + self.args.push(arg.to_string()); + self + } + + pub fn args(mut self, args: &[&str]) -> Self { + for arg in args { + self = self.arg(arg); } self } + /// Set the specified target to be treated as a no_std target. + pub fn override_target_no_std(mut self, target: &str) -> Self { + self.args(&["--set", &format!("target.{target}.no-std=true")]) + } + pub fn hosts(mut self, targets: &[&str]) -> Self { self.args.push("--host".to_string()); self.args.push(targets.join(",")); @@ -77,13 +90,6 @@ impl ConfigBuilder { self } - pub fn args(mut self, args: &[&str]) -> Self { - for arg in args { - self.args.push(arg.to_string()); - } - self - } - pub fn create_config(mut self) -> Config { // Run in dry-check, otherwise the test would be too slow self.args.push("--dry-run".to_string()); diff --git a/src/bootstrap/src/utils/tracing.rs b/src/bootstrap/src/utils/tracing.rs index 99849341dc3..109407bc5f2 100644 --- a/src/bootstrap/src/utils/tracing.rs +++ b/src/bootstrap/src/utils/tracing.rs @@ -52,13 +52,11 @@ macro_rules! error { macro_rules! trace_cmd { ($cmd:expr) => { { - use $crate::utils::exec::FormatShortCmd; - ::tracing::span!( target: "COMMAND", ::tracing::Level::TRACE, "executing command", - cmd = $cmd.format_short_cmd(), + cmd = $cmd.fingerprint().format_short_cmd(), full_cmd = ?$cmd ).entered() } diff --git a/src/build_helper/src/ci.rs b/src/build_helper/src/ci.rs index 9d114c70a67..b5e70eb84cc 100644 --- a/src/build_helper/src/ci.rs +++ b/src/build_helper/src/ci.rs @@ -9,7 +9,7 @@ pub enum CiEnv { impl CiEnv { /// Obtains the current CI environment. pub fn current() -> CiEnv { - if std::env::var("GITHUB_ACTIONS").map_or(false, |e| e == "true") { + if std::env::var("GITHUB_ACTIONS").is_ok_and(|e| e == "true") { CiEnv::GitHubActions } else { CiEnv::None diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 9d1195aadf8..cbefb836c00 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -13,7 +13,7 @@ pub struct GitConfig<'a> { pub fn output_result(cmd: &mut Command) -> Result<String, String> { let output = match cmd.stderr(Stdio::inherit()).output() { Ok(status) => status, - Err(e) => return Err(format!("failed to run command: {:?}: {}", cmd, e)), + Err(e) => return Err(format!("failed to run command: {cmd:?}: {e}")), }; if !output.status.success() { return Err(format!( @@ -62,22 +62,22 @@ pub enum PathFreshness { /// The function behaves differently in CI and outside CI. /// /// - Outside CI, we want to find out if `target_paths` were modified in some local commit on -/// top of the latest upstream commit that is available in local git history. -/// If not, we try to find the most recent upstream commit (which we assume are commits -/// made by bors) that modified `target_paths`. -/// We don't want to simply take the latest master commit to avoid changing the output of -/// this function frequently after rebasing on the latest master branch even if `target_paths` -/// were not modified upstream in the meantime. In that case we would be redownloading CI -/// artifacts unnecessarily. +/// top of the latest upstream commit that is available in local git history. +/// If not, we try to find the most recent upstream commit (which we assume are commits +/// made by bors) that modified `target_paths`. +/// We don't want to simply take the latest master commit to avoid changing the output of +/// this function frequently after rebasing on the latest master branch even if `target_paths` +/// were not modified upstream in the meantime. In that case we would be redownloading CI +/// artifacts unnecessarily. /// /// - In CI, we use a shallow clone of depth 2, i.e., we fetch only a single parent commit -/// (which will be the most recent bors merge commit) and do not have access -/// to the full git history. Luckily, we only need to distinguish between two situations: -/// 1) The current PR made modifications to `target_paths`. -/// In that case, a build is typically necessary. -/// 2) The current PR did not make modifications to `target_paths`. -/// In that case we simply take the latest upstream commit, because on CI there is no need to avoid -/// redownloading. +/// (which will be the most recent bors merge commit) and do not have access +/// to the full git history. Luckily, we only need to distinguish between two situations: +/// 1) The current PR made modifications to `target_paths`. +/// In that case, a build is typically necessary. +/// 2) The current PR did not make modifications to `target_paths`. +/// In that case we simply take the latest upstream commit, because on CI there is no need to avoid +/// redownloading. pub fn check_path_modifications( git_dir: &Path, config: &GitConfig<'_>, @@ -232,7 +232,7 @@ pub fn get_closest_upstream_commit( "--author-date-order", &format!("--author={}", config.git_merge_commit_email), "-n1", - &base, + base, ]); let output = output_result(&mut git)?.trim().to_owned(); diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs index 8b82e62a327..07157e36415 100644 --- a/src/build_helper/src/metrics.rs +++ b/src/build_helper/src/metrics.rs @@ -141,7 +141,7 @@ impl BuildStep { } => { let full_name = format!("{parent_name}-{kind}"); let children: Vec<_> = - children.into_iter().filter_map(|s| parse(s, &full_name)).collect(); + children.iter().filter_map(|s| parse(s, &full_name)).collect(); let children_duration = children.iter().map(|c| c.duration).sum::<Duration>(); Some(BuildStep { r#type: kind.to_string(), diff --git a/src/build_helper/src/util.rs b/src/build_helper/src/util.rs index 80dd6813d13..a8355f774e9 100644 --- a/src/build_helper/src/util.rs +++ b/src/build_helper/src/util.rs @@ -18,29 +18,28 @@ macro_rules! exit { pub fn detail_exit(code: i32, is_test: bool) -> ! { // if in test and code is an error code, panic with status code provided if is_test { - panic!("status code: {}", code); + panic!("status code: {code}"); } else { - // otherwise,exit with provided status code + // otherwise, exit with provided status code std::process::exit(code); } } pub fn fail(s: &str) -> ! { - eprintln!("\n\n{}\n\n", s); + eprintln!("\n\n{s}\n\n"); detail_exit(1, cfg!(test)); } pub fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> Result<(), ()> { let status = match cmd.status() { Ok(status) => status, - Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), + Err(e) => fail(&format!("failed to execute command: {cmd:?}\nerror: {e}")), }; if !status.success() { if print_cmd_on_fail { println!( - "\n\ncommand did not execute successfully: {:?}\n\ - expected success, got: {}\n\n", - cmd, status + "\n\ncommand did not execute successfully: {cmd:?}\n\ + expected success, got: {status}\n\n" ); } Err(()) @@ -60,7 +59,7 @@ pub fn parse_gitmodules(target_dir: &Path) -> Vec<String> { for line in BufReader::new(file).lines().map_while(Result::ok) { let line = line.trim(); if line.starts_with("path") { - let actual_path = line.split(' ').last().expect("Couldn't get value of path"); + let actual_path = line.split(' ').next_back().expect("Couldn't get value of path"); submodules_paths.push(actual_path.to_owned()); } } diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 4e69fb2f370..da7d084d48d 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -361,7 +361,7 @@ docker \ --env TOOLSTATE_REPO \ --env TOOLSTATE_PUBLISH \ --env RUST_CI_OVERRIDE_RELEASE_CHANNEL \ - --env CI_JOB_NAME="${CI_JOB_NAME-$IMAGE}" \ + --env CI_JOB_NAME="${CI_JOB_NAME-$image}" \ --env CI_JOB_DOC_URL="${CI_JOB_DOC_URL}" \ --env BASE_COMMIT="$BASE_COMMIT" \ --env DIST_TRY_BUILD \ diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 01993ad28aa..445fc0dd018 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -46,6 +46,10 @@ runners: os: windows-2025-8core-32gb <<: *base-job + - &job-windows-aarch64 + os: windows-11-arm + <<: *base-job + - &job-aarch64-linux # Free some disk space to avoid running out of space during the build. free_disk: true @@ -561,6 +565,19 @@ auto: SCRIPT: make ci-msvc-ps1 <<: *job-windows + # aarch64-msvc is split into two jobs to run tests in parallel. + - name: aarch64-msvc-1 + env: + RUST_CONFIGURE_ARGS: --build=aarch64-pc-windows-msvc + SCRIPT: make ci-msvc-py + <<: *job-windows-aarch64 + + - name: aarch64-msvc-2 + env: + RUST_CONFIGURE_ARGS: --build=aarch64-pc-windows-msvc + SCRIPT: make ci-msvc-ps1 + <<: *job-windows-aarch64 + # x86_64-msvc-ext is split into multiple jobs to run tests in parallel. - name: x86_64-msvc-ext1 env: @@ -656,14 +673,14 @@ auto: - name: dist-aarch64-msvc env: RUST_CONFIGURE_ARGS: >- - --build=x86_64-pc-windows-msvc + --build=aarch64-pc-windows-msvc --host=aarch64-pc-windows-msvc --target=aarch64-pc-windows-msvc,arm64ec-pc-windows-msvc --enable-full-tools --enable-profiler SCRIPT: python x.py dist bootstrap --include-default-paths DIST_REQUIRE_ALL_TOOLS: 1 - <<: *job-windows + <<: *job-windows-aarch64 - name: dist-i686-mingw env: diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh index a9528e92915..657e1492a6d 100755 --- a/src/ci/scripts/install-clang.sh +++ b/src/ci/scripts/install-clang.sh @@ -56,9 +56,19 @@ elif isWindows && ! isKnownToBeMingwBuild; then mkdir -p citools/clang-rust cd citools - retry curl -f "${MIRRORS_BASE}/LLVM-${LLVM_VERSION}-win64.exe" \ - -o "LLVM-${LLVM_VERSION}-win64.exe" - 7z x -oclang-rust/ "LLVM-${LLVM_VERSION}-win64.exe" + + if [[ "${CI_JOB_NAME}" = *aarch64* ]]; then + suffix=woa64 + + # On Arm64, the Ring crate requires that Clang be on the PATH. + # https://github.com/briansmith/ring/blob/main/BUILDING.md + ciCommandAddPath "$(cygpath -m "$(pwd)/clang-rust/bin")" + else + suffix=win64 + fi + retry curl -f "${MIRRORS_BASE}/LLVM-${LLVM_VERSION}-${suffix}.exe" \ + -o "LLVM-${LLVM_VERSION}-${suffix}.exe" + 7z x -oclang-rust/ "LLVM-${LLVM_VERSION}-${suffix}.exe" ciCommandSetEnv RUST_CONFIGURE_ARGS \ "${RUST_CONFIGURE_ARGS} --set llvm.clang-cl=$(pwd)/clang-rust/bin/clang-cl.exe" diff --git a/src/ci/scripts/install-rust.sh b/src/ci/scripts/install-rust.sh new file mode 100755 index 00000000000..e4aee98c9fb --- /dev/null +++ b/src/ci/scripts/install-rust.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# The Arm64 Windows Runner does not have Rust already installed +# https://github.com/actions/partner-runner-images/issues/77 + +set -euo pipefail +IFS=$'\n\t' + +source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" + +if [[ "${CI_JOB_NAME}" = *aarch64* ]] && isWindows; then + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ + sh -s -- -y -q --default-host aarch64-pc-windows-msvc + ciCommandAddPath "${USERPROFILE}/.cargo/bin" +fi diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md index ed267850401..c9c0d64a604 100644 --- a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md +++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md @@ -168,10 +168,17 @@ For `#[instrument]`, it's recommended to: ### Profiling bootstrap -You can use the `COMMAND` tracing target to trace execution of most commands spawned by bootstrap. If you also use the `BOOTSTRAP_PROFILE=1` environment variable, bootstrap will generate a Chrome JSON trace file, which can be visualized in Chrome's `chrome://tracing` page or on https://ui.perfetto.dev. +You can set the `BOOTSTRAP_PROFILE=1` environment variable to enable command execution profiling during bootstrap. This generates: + +* A Chrome trace file (for visualization in `chrome://tracing` or [Perfetto](https://ui.perfetto.dev)) if tracing is enabled via `BOOTSTRAP_TRACING=COMMAND=trace` +* A plain-text summary file, `bootstrap-profile-{pid}.txt`, listing all commands sorted by execution time (slowest first), along with cache hits and working directories + +Note: the `.txt` report is always generated when `BOOTSTRAP_PROFILE=1` is set — tracing is not required. + +Example usage: ```bash -$ BOOTSTRAP_TRACING=COMMAND=trace BOOTSTRAP_PROFILE=1 ./x build library +$ BOOTSTRAP_PROFILE=1 BOOTSTRAP_TRACING=COMMAND=trace ./x build library ``` ### rust-analyzer integration? diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index e1742631f63..7c688e32bc0 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -46,6 +46,7 @@ - [\*-apple-watchos](platform-support/apple-watchos.md) - [\*-apple-visionos](platform-support/apple-visionos.md) - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md) + - [aarch64-unknown-linux-musl](platform-support/aarch64-unknown-linux-musl.md) - [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md) - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md) - [arm-none-eabi](platform-support/arm-none-eabi.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ed01de4c1c3..65b70630153 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -90,7 +90,7 @@ target | notes -------|------- [`aarch64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ARM64 MinGW (Windows 10+), LLVM ABI [`aarch64-pc-windows-msvc`](platform-support/windows-msvc.md) | ARM64 Windows MSVC -`aarch64-unknown-linux-musl` | ARM64 Linux with musl 1.2.3 +[`aarch64-unknown-linux-musl`](platform-support/aarch64-unknown-linux-musl.md) | ARM64 Linux with musl 1.2.3 [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ARM64 OpenHarmony `arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2+, glibc 2.17) `arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2+, glibc 2.17) diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/aarch64-unknown-linux-musl.md new file mode 100644 index 00000000000..5d9a552e460 --- /dev/null +++ b/src/doc/rustc/src/platform-support/aarch64-unknown-linux-musl.md @@ -0,0 +1,49 @@ +# aarch64-unknown-linux-musl + +**Tier: 2** + +Target for 64-bit little endian ARMv8-A Linux programs using musl libc. + +## Target maintainers + +[@Gelbpunkt](https://github.com/Gelbpunkt) +[@famfo](https://github.com/famfo) + +## Requirements + +Building the target itself requires a 64-bit little endian ARMv8-A compiler +that is supported by `cc-rs`. + +## Building the target + +The target can be built by enabling it for a `rustc` build. + +```toml +[build] +target = ["aarch64-unknown-linux-musl"] +``` + +Make sure your C compiler is included in `$PATH`, then add it to the +`bootstrap.toml`: + +```toml +[target.aarch64-unknown-linux-musl] +cc = "aarch64-linux-musl-gcc" +cxx = "aarch64-linux-musl-g++" +ar = "aarch64-linux-musl-ar" +linker = "aarch64-linux-musl-gcc" +``` + +## Building Rust programs + +This target is distributed through `rustup`, and otherwise requires no +special configuration. + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Testing + +This target can be tested as normal with `x.py` on a 64-bit little endian +ARMv8-A host or via QEMU emulation. diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish index 3009dd85e93..d3da1f353e2 100644 --- a/src/etc/completions/x.fish +++ b/src/etc/completions/x.fish @@ -1,6 +1,6 @@ # Print an optspec for argparse to handle cmd's options that are independent of any subcommand. function __fish_x_global_optspecs - string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= json-output color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= ci= skip-std-check-if-no-download-rustc h/help + string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= json-output compile-time-deps color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= ci= skip-std-check-if-no-download-rustc h/help end function __fish_x_needs_command @@ -52,6 +52,7 @@ complete -c x -n "__fish_x_needs_command" -l include-default-paths -d 'include d complete -c x -n "__fish_x_needs_command" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_needs_command" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_needs_command" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_needs_command" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_needs_command" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_needs_command" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_needs_command" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -103,6 +104,7 @@ complete -c x -n "__fish_x_using_subcommand build" -l include-default-paths -d ' complete -c x -n "__fish_x_using_subcommand build" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand build" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand build" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand build" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand build" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand build" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand build" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -138,6 +140,7 @@ complete -c x -n "__fish_x_using_subcommand check" -l include-default-paths -d ' complete -c x -n "__fish_x_using_subcommand check" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand check" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand check" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand check" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand check" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand check" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand check" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -179,6 +182,7 @@ complete -c x -n "__fish_x_using_subcommand clippy" -l include-default-paths -d complete -c x -n "__fish_x_using_subcommand clippy" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand clippy" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand clippy" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand clippy" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand clippy" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand clippy" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand clippy" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -213,6 +217,7 @@ complete -c x -n "__fish_x_using_subcommand fix" -l include-default-paths -d 'in complete -c x -n "__fish_x_using_subcommand fix" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand fix" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand fix" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand fix" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand fix" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand fix" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand fix" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -249,6 +254,7 @@ complete -c x -n "__fish_x_using_subcommand fmt" -l include-default-paths -d 'in complete -c x -n "__fish_x_using_subcommand fmt" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand fmt" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand fmt" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand fmt" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand fmt" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand fmt" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand fmt" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -285,6 +291,7 @@ complete -c x -n "__fish_x_using_subcommand doc" -l include-default-paths -d 'in complete -c x -n "__fish_x_using_subcommand doc" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand doc" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand doc" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand doc" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand doc" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand doc" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand doc" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -333,6 +340,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l include-default-paths -d 'i complete -c x -n "__fish_x_using_subcommand test" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand test" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand test" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand test" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand test" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand test" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand test" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -371,6 +379,7 @@ complete -c x -n "__fish_x_using_subcommand miri" -l include-default-paths -d 'i complete -c x -n "__fish_x_using_subcommand miri" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand miri" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand miri" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand miri" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand miri" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand miri" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand miri" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -406,6 +415,7 @@ complete -c x -n "__fish_x_using_subcommand bench" -l include-default-paths -d ' complete -c x -n "__fish_x_using_subcommand bench" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand bench" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand bench" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand bench" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand bench" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand bench" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand bench" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -441,6 +451,7 @@ complete -c x -n "__fish_x_using_subcommand clean" -l include-default-paths -d ' complete -c x -n "__fish_x_using_subcommand clean" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand clean" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand clean" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand clean" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand clean" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand clean" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand clean" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -475,6 +486,7 @@ complete -c x -n "__fish_x_using_subcommand dist" -l include-default-paths -d 'i complete -c x -n "__fish_x_using_subcommand dist" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand dist" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand dist" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand dist" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand dist" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand dist" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand dist" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -509,6 +521,7 @@ complete -c x -n "__fish_x_using_subcommand install" -l include-default-paths -d complete -c x -n "__fish_x_using_subcommand install" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand install" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand install" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand install" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand install" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand install" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand install" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -544,6 +557,7 @@ complete -c x -n "__fish_x_using_subcommand run" -l include-default-paths -d 'in complete -c x -n "__fish_x_using_subcommand run" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand run" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand run" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand run" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand run" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand run" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand run" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -578,6 +592,7 @@ complete -c x -n "__fish_x_using_subcommand setup" -l include-default-paths -d ' complete -c x -n "__fish_x_using_subcommand setup" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand setup" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand setup" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand setup" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand setup" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand setup" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand setup" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -613,6 +628,7 @@ complete -c x -n "__fish_x_using_subcommand suggest" -l include-default-paths -d complete -c x -n "__fish_x_using_subcommand suggest" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand suggest" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand suggest" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand suggest" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand suggest" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand suggest" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand suggest" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -649,6 +665,7 @@ complete -c x -n "__fish_x_using_subcommand vendor" -l include-default-paths -d complete -c x -n "__fish_x_using_subcommand vendor" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand vendor" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand vendor" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand vendor" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand vendor" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand vendor" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand vendor" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -683,6 +700,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -725,6 +743,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -762,6 +781,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -799,6 +819,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -836,6 +857,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -870,6 +892,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l dry-run -d 'dry run; don\'t build anything' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l json-output -d 'use message-format=json' +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l enable-bolt-settings -d 'Enable BOLT link flags' diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1 index 8002ec31592..b5b59c58bba 100644 --- a/src/etc/completions/x.ps1 +++ b/src/etc/completions/x.ps1 @@ -52,6 +52,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -110,6 +111,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -152,6 +154,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -200,6 +203,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -241,6 +245,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -284,6 +289,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -327,6 +333,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -382,6 +389,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -427,6 +435,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -469,6 +478,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -511,6 +521,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -552,6 +563,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -593,6 +605,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -635,6 +648,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -676,6 +690,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -718,6 +733,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -761,6 +777,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -802,6 +819,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -851,6 +869,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -895,6 +914,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -939,6 +959,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -983,6 +1004,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -1024,6 +1046,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 4766a5ee0c7..da7680a879d 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -1,6 +1,6 @@ # Print an optspec for argparse to handle cmd's options that are independent of any subcommand. function __fish_x.py_global_optspecs - string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= json-output color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= ci= skip-std-check-if-no-download-rustc h/help + string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= json-output compile-time-deps color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= ci= skip-std-check-if-no-download-rustc h/help end function __fish_x.py_needs_command @@ -52,6 +52,7 @@ complete -c x.py -n "__fish_x.py_needs_command" -l include-default-paths -d 'inc complete -c x.py -n "__fish_x.py_needs_command" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_needs_command" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_needs_command" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_needs_command" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_needs_command" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_needs_command" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_needs_command" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -103,6 +104,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand build" -l include-default-path complete -c x.py -n "__fish_x.py_using_subcommand build" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand build" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand build" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand build" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand build" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand build" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand build" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -138,6 +140,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand check" -l include-default-path complete -c x.py -n "__fish_x.py_using_subcommand check" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand check" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand check" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand check" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand check" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand check" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand check" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -179,6 +182,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l include-default-pat complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -213,6 +217,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand fix" -l include-default-paths complete -c x.py -n "__fish_x.py_using_subcommand fix" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand fix" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand fix" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand fix" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand fix" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand fix" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand fix" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -249,6 +254,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l include-default-paths complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -285,6 +291,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand doc" -l include-default-paths complete -c x.py -n "__fish_x.py_using_subcommand doc" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand doc" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand doc" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand doc" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand doc" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand doc" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand doc" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -333,6 +340,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l include-default-paths complete -c x.py -n "__fish_x.py_using_subcommand test" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand test" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand test" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand test" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand test" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand test" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand test" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -371,6 +379,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand miri" -l include-default-paths complete -c x.py -n "__fish_x.py_using_subcommand miri" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand miri" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand miri" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand miri" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand miri" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand miri" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand miri" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -406,6 +415,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand bench" -l include-default-path complete -c x.py -n "__fish_x.py_using_subcommand bench" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand bench" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand bench" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand bench" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand bench" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand bench" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand bench" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -441,6 +451,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clean" -l include-default-path complete -c x.py -n "__fish_x.py_using_subcommand clean" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand clean" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand clean" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand clean" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand clean" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand clean" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand clean" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -475,6 +486,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand dist" -l include-default-paths complete -c x.py -n "__fish_x.py_using_subcommand dist" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand dist" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand dist" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand dist" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand dist" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand dist" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand dist" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -509,6 +521,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand install" -l include-default-pa complete -c x.py -n "__fish_x.py_using_subcommand install" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand install" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand install" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand install" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand install" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand install" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand install" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -544,6 +557,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand run" -l include-default-paths complete -c x.py -n "__fish_x.py_using_subcommand run" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand run" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand run" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand run" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand run" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand run" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand run" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -578,6 +592,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand setup" -l include-default-path complete -c x.py -n "__fish_x.py_using_subcommand setup" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand setup" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand setup" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand setup" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand setup" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand setup" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand setup" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -613,6 +628,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l include-default-pa complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -649,6 +665,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l include-default-pat complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -683,6 +700,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subc complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -725,6 +743,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -762,6 +781,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -799,6 +819,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -836,6 +857,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l enable-bolt-settings -d 'Enable BOLT link flags' @@ -870,6 +892,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l enable-bolt-settings -d 'Enable BOLT link flags' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index 1aff3c433b4..3fc8e7d5bbd 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -52,6 +52,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -110,6 +111,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -152,6 +154,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -200,6 +203,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -241,6 +245,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -284,6 +289,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -327,6 +333,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -382,6 +389,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -427,6 +435,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -469,6 +478,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -511,6 +521,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -552,6 +563,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -593,6 +605,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -635,6 +648,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -676,6 +690,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -718,6 +733,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -761,6 +777,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -802,6 +819,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -851,6 +869,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -895,6 +914,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -939,6 +959,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -983,6 +1004,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') @@ -1024,6 +1046,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)') [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index fe4ed5c915f..8f13de282fb 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -85,7 +85,7 @@ _x.py() { case "${cmd}" in x.py) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf" + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -271,7 +271,7 @@ _x.py() { return 0 ;; x.py__bench) - opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -461,7 +461,7 @@ _x.py() { return 0 ;; x.py__build) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -647,7 +647,7 @@ _x.py() { return 0 ;; x.py__check) - opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -833,7 +833,7 @@ _x.py() { return 0 ;; x.py__clean) - opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1016,7 +1016,7 @@ _x.py() { return 0 ;; x.py__clippy) - opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1218,7 +1218,7 @@ _x.py() { return 0 ;; x.py__dist) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1404,7 +1404,7 @@ _x.py() { return 0 ;; x.py__doc) - opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1590,7 +1590,7 @@ _x.py() { return 0 ;; x.py__fix) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1776,7 +1776,7 @@ _x.py() { return 0 ;; x.py__fmt) - opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1962,7 +1962,7 @@ _x.py() { return 0 ;; x.py__install) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2148,7 +2148,7 @@ _x.py() { return 0 ;; x.py__miri) - opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2338,7 +2338,7 @@ _x.py() { return 0 ;; x.py__perf) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare" + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2524,7 +2524,7 @@ _x.py() { return 0 ;; x.py__perf__benchmark) - opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <benchmark-id> [PATHS]... [ARGS]..." + opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <benchmark-id> [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2722,7 +2722,7 @@ _x.py() { return 0 ;; x.py__perf__cachegrind) - opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2920,7 +2920,7 @@ _x.py() { return 0 ;; x.py__perf__compare) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <BASE> <MODIFIED> [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <BASE> <MODIFIED> [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3106,7 +3106,7 @@ _x.py() { return 0 ;; x.py__perf__eprintln) - opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3304,7 +3304,7 @@ _x.py() { return 0 ;; x.py__perf__samply) - opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3502,7 +3502,7 @@ _x.py() { return 0 ;; x.py__run) - opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3692,7 +3692,7 @@ _x.py() { return 0 ;; x.py__setup) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3878,7 +3878,7 @@ _x.py() { return 0 ;; x.py__suggest) - opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -4064,7 +4064,7 @@ _x.py() { return 0 ;; x.py__test) - opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -4274,7 +4274,7 @@ _x.py() { return 0 ;; x.py__vendor) - opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index 77f995c1704..60ce9002116 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -46,6 +46,7 @@ _x.py() { '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -97,6 +98,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -141,6 +143,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -191,6 +194,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -234,6 +238,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -279,6 +284,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -324,6 +330,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -381,6 +388,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -428,6 +436,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -472,6 +481,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -516,6 +526,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -559,6 +570,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -602,6 +614,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -646,6 +659,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -689,6 +703,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -734,6 +749,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -779,6 +795,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -822,6 +839,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -877,6 +895,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -923,6 +942,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -969,6 +989,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -1015,6 +1036,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -1059,6 +1081,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh index 105fc668e8e..f6ecf4cebf4 100644 --- a/src/etc/completions/x.sh +++ b/src/etc/completions/x.sh @@ -85,7 +85,7 @@ _x() { case "${cmd}" in x) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf" + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -271,7 +271,7 @@ _x() { return 0 ;; x__bench) - opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -461,7 +461,7 @@ _x() { return 0 ;; x__build) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -647,7 +647,7 @@ _x() { return 0 ;; x__check) - opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -833,7 +833,7 @@ _x() { return 0 ;; x__clean) - opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1016,7 +1016,7 @@ _x() { return 0 ;; x__clippy) - opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1218,7 +1218,7 @@ _x() { return 0 ;; x__dist) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1404,7 +1404,7 @@ _x() { return 0 ;; x__doc) - opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1590,7 +1590,7 @@ _x() { return 0 ;; x__fix) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1776,7 +1776,7 @@ _x() { return 0 ;; x__fmt) - opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1962,7 +1962,7 @@ _x() { return 0 ;; x__install) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2148,7 +2148,7 @@ _x() { return 0 ;; x__miri) - opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2338,7 +2338,7 @@ _x() { return 0 ;; x__perf) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare" + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2524,7 +2524,7 @@ _x() { return 0 ;; x__perf__benchmark) - opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <benchmark-id> [PATHS]... [ARGS]..." + opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <benchmark-id> [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2722,7 +2722,7 @@ _x() { return 0 ;; x__perf__cachegrind) - opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2920,7 +2920,7 @@ _x() { return 0 ;; x__perf__compare) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <BASE> <MODIFIED> [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <BASE> <MODIFIED> [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3106,7 +3106,7 @@ _x() { return 0 ;; x__perf__eprintln) - opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3304,7 +3304,7 @@ _x() { return 0 ;; x__perf__samply) - opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3502,7 +3502,7 @@ _x() { return 0 ;; x__run) - opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3692,7 +3692,7 @@ _x() { return 0 ;; x__setup) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3878,7 +3878,7 @@ _x() { return 0 ;; x__suggest) - opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -4064,7 +4064,7 @@ _x() { return 0 ;; x__test) - opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -4274,7 +4274,7 @@ _x() { return 0 ;; x__vendor) - opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh index 6c6d7b3f49f..452a26fef07 100644 --- a/src/etc/completions/x.zsh +++ b/src/etc/completions/x.zsh @@ -46,6 +46,7 @@ _x() { '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -97,6 +98,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -141,6 +143,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -191,6 +194,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -234,6 +238,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -279,6 +284,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -324,6 +330,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -381,6 +388,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -428,6 +436,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -472,6 +481,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -516,6 +526,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -559,6 +570,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -602,6 +614,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -646,6 +659,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -689,6 +703,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -734,6 +749,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -779,6 +795,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -822,6 +839,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -877,6 +895,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -923,6 +942,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -969,6 +989,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -1015,6 +1036,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ @@ -1059,6 +1081,7 @@ _arguments "${_arguments_options[@]}" : \ '--dry-run[dry run; don'\''t build anything]' \ '--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ '--json-output[use message-format=json]' \ +'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \ '--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ '--enable-bolt-settings[Enable BOLT link flags]' \ diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py index 1806e2be9bb..ddbd256a0d8 100755 --- a/src/etc/htmldocck.py +++ b/src/etc/htmldocck.py @@ -564,10 +564,14 @@ def check_command(c, cache): # hasraw/matchesraw <path> <pat> = string test elif len(c.args) == 2 and "raw" in c.cmd: cerr = "`PATTERN` did not match" + if c.negated: + cerr = "`PATTERN` unexpectedly matched" ret = check_string(cache.get_file(c.args[0]), c.args[1], regexp) # has/matches <path> <pat> <match> = XML tree test elif len(c.args) == 3 and "raw" not in c.cmd: cerr = "`XPATH PATTERN` did not match" + if c.negated: + cerr = "`XPATH PATTERN` unexpectedly matched" ret = get_nb_matching_elements(cache, c, regexp, True) != 0 else: raise InvalidCheck("Invalid number of {} arguments".format(c.cmd)) diff --git a/src/etc/rust_analyzer_eglot.el b/src/etc/rust_analyzer_eglot.el index 3cb229cd98c..3151cb1a6e7 100644 --- a/src/etc/rust_analyzer_eglot.el +++ b/src/etc/rust_analyzer_eglot.el @@ -23,7 +23,8 @@ :overrideCommand ["python3" "x.py" "check" - "--json-output"]) + "--json-output" + "--compile-time-deps"])] :sysrootSrc "./library" :extraEnv (:RUSTC_BOOTSTRAP "1")) :rustc ( :source "./Cargo.toml" ))))))) diff --git a/src/etc/rust_analyzer_helix.toml b/src/etc/rust_analyzer_helix.toml index 1a6a14991ec..8c1782a1abc 100644 --- a/src/etc/rust_analyzer_helix.toml +++ b/src/etc/rust_analyzer_helix.toml @@ -59,4 +59,5 @@ overrideCommand = [ "--json-output", "--build-dir", "build/rust-analyzer", + "--compile-time-deps" ] diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json index a960cc01732..b31169857c5 100644 --- a/src/etc/rust_analyzer_settings.json +++ b/src/etc/rust_analyzer_settings.json @@ -27,7 +27,8 @@ "python3", "x.py", "check", - "--json-output" + "--json-output", + "--compile-time-deps" ], "rust-analyzer.cargo.sysrootSrc": "./library", "rust-analyzer.rustc.source": "./Cargo.toml", diff --git a/src/etc/rust_analyzer_zed.json b/src/etc/rust_analyzer_zed.json index 27fc524e9b5..7eace92500e 100644 --- a/src/etc/rust_analyzer_zed.json +++ b/src/etc/rust_analyzer_zed.json @@ -7,7 +7,7 @@ "enable": true, "invocationLocation": "root", "invocationStrategy": "once", - "overrideCommand": ["python3", "x.py", "check", "--json-output"] + "overrideCommand": ["python3", "x.py", "check", "--json-output", "--compile-time-deps"] }, "extraEnv": { "RUSTC_BOOTSTRAP": "1" diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 96199cb972a..9603399f235 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -152,8 +152,14 @@ pub(crate) fn try_inline( }; cx.inlined.insert(did.into()); - let mut item = - crate::clean::generate_item_with_correct_attrs(cx, kind, did, name, import_def_id, None); + let mut item = crate::clean::generate_item_with_correct_attrs( + cx, + kind, + did, + name, + import_def_id.as_slice(), + None, + ); // The visibility needs to reflect the one from the reexport and not from the "source" DefId. item.inner.inline_stmt_id = import_def_id; ret.push(item); @@ -493,7 +499,7 @@ pub(crate) fn build_impl( impl_ .items .iter() - .map(|item| tcx.hir_impl_item(item.id)) + .map(|&item| tcx.hir_impl_item(item)) .filter(|item| { // Filter out impl items whose corresponding trait item has `doc(hidden)` // not to document such impl items. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c2f3da18cd3..e7a1f4d8397 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -94,12 +94,12 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< // This covers the case where somebody does an import which should pull in an item, // but there's already an item with the same namespace and same name. Rust gives // priority to the not-imported one, so we should, too. - items.extend(doc.items.values().flat_map(|(item, renamed, import_id)| { + items.extend(doc.items.values().flat_map(|(item, renamed, import_ids)| { // First, lower everything other than glob imports. if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { return Vec::new(); } - let v = clean_maybe_renamed_item(cx, item, *renamed, *import_id); + let v = clean_maybe_renamed_item(cx, item, *renamed, import_ids); for item in &v { if let Some(name) = item.name && (cx.render_options.document_hidden || !item.is_doc_hidden()) @@ -162,7 +162,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< kind, doc.def_id.to_def_id(), doc.name, - doc.import_id, + doc.import_id.as_slice(), doc.renamed, ) } @@ -182,22 +182,29 @@ fn generate_item_with_correct_attrs( kind: ItemKind, def_id: DefId, name: Symbol, - import_id: Option<LocalDefId>, + import_ids: &[LocalDefId], renamed: Option<Symbol>, ) -> Item { let target_attrs = inline::load_attrs(cx, def_id); - let attrs = if let Some(import_id) = import_id { - // glob reexports are treated the same as `#[doc(inline)]` items. - // - // For glob re-exports the item may or may not exist to be re-exported (potentially the cfgs - // on the path up until the glob can be removed, and only cfgs on the globbed item itself - // matter), for non-inlined re-exports see #85043. - let is_inline = hir_attr_lists(inline::load_attrs(cx, import_id.to_def_id()), sym::doc) - .get_word_attr(sym::inline) - .is_some() - || (is_glob_import(cx.tcx, import_id) - && (cx.render_options.document_hidden || !cx.tcx.is_doc_hidden(def_id))); - let mut attrs = get_all_import_attributes(cx, import_id, def_id, is_inline); + let attrs = if !import_ids.is_empty() { + let mut attrs = Vec::with_capacity(import_ids.len()); + let mut is_inline = false; + + for import_id in import_ids.iter().copied() { + // glob reexports are treated the same as `#[doc(inline)]` items. + // + // For glob re-exports the item may or may not exist to be re-exported (potentially the + // cfgs on the path up until the glob can be removed, and only cfgs on the globbed item + // itself matter), for non-inlined re-exports see #85043. + let import_is_inline = + hir_attr_lists(inline::load_attrs(cx, import_id.to_def_id()), sym::doc) + .get_word_attr(sym::inline) + .is_some() + || (is_glob_import(cx.tcx, import_id) + && (cx.render_options.document_hidden || !cx.tcx.is_doc_hidden(def_id))); + attrs.extend(get_all_import_attributes(cx, import_id, def_id, is_inline)); + is_inline = is_inline || import_is_inline; + } add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None); attrs } else { @@ -216,7 +223,8 @@ fn generate_item_with_correct_attrs( let name = renamed.or(Some(name)); let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, attrs, cfg); - item.inner.inline_stmt_id = import_id; + // FIXME (GuillaumeGomez): Should we also make `inline_stmt_id` a `Vec` instead of an `Option`? + item.inner.inline_stmt_id = import_ids.first().copied(); item } @@ -2754,7 +2762,7 @@ fn clean_maybe_renamed_item<'tcx>( cx: &mut DocContext<'tcx>, item: &hir::Item<'tcx>, renamed: Option<Symbol>, - import_id: Option<LocalDefId>, + import_ids: &[LocalDefId], ) -> Vec<Item> { use hir::ItemKind; fn get_name( @@ -2825,7 +2833,7 @@ fn clean_maybe_renamed_item<'tcx>( })), item.owner_id.def_id.to_def_id(), name, - import_id, + import_ids, renamed, )); return ret; @@ -2859,7 +2867,7 @@ fn clean_maybe_renamed_item<'tcx>( ItemKind::Trait(_, _, _, generics, bounds, item_ids) => { let items = item_ids .iter() - .map(|ti| clean_trait_item(cx.tcx.hir_trait_item(ti.id), cx)) + .map(|&ti| clean_trait_item(cx.tcx.hir_trait_item(ti), cx)) .collect(); TraitItem(Box::new(Trait { @@ -2880,7 +2888,7 @@ fn clean_maybe_renamed_item<'tcx>( kind, item.owner_id.def_id.to_def_id(), name, - import_id, + import_ids, renamed, )] }) @@ -2902,7 +2910,7 @@ fn clean_impl<'tcx>( let items = impl_ .items .iter() - .map(|ii| clean_impl_item(tcx.hir_impl_item(ii.id), cx)) + .map(|&ii| clean_impl_item(tcx.hir_impl_item(ii), cx)) .collect::<Vec<_>>(); // If this impl block is an implementation of the Deref trait, then we @@ -3151,7 +3159,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>( kind, item.owner_id.def_id.to_def_id(), item.ident.name, - import_id, + import_id.as_slice(), renamed, ) }) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 2889bfae7b0..9058277d72e 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -32,11 +32,29 @@ pub(crate) struct Module<'hir> { pub(crate) def_id: LocalDefId, pub(crate) renamed: Option<Symbol>, pub(crate) import_id: Option<LocalDefId>, - /// The key is the item `ItemId` and the value is: (item, renamed, import_id). + /// The key is the item `ItemId` and the value is: (item, renamed, Vec<import_id>). /// We use `FxIndexMap` to keep the insert order. + /// + /// `import_id` needs to be a `Vec` because we live in a dark world where you can have code + /// like: + /// + /// ``` + /// mod raw { + /// pub fn foo() {} + /// } + /// + /// /// Foobar + /// pub use raw::foo; + /// + /// pub use raw::*; + /// ``` + /// + /// So in this case, we don't want to have two items but just one with attributes from all + /// non-glob imports to be merged. Glob imports attributes are always ignored, whether they're + /// shadowed or not. pub(crate) items: FxIndexMap< (LocalDefId, Option<Symbol>), - (&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>), + (&'hir hir::Item<'hir>, Option<Symbol>, Vec<LocalDefId>), >, /// (def_id, renamed) -> (res, local_import_id) @@ -154,7 +172,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { { let item = self.cx.tcx.hir_expect_item(local_def_id); let (ident, _, _) = item.expect_macro(); - top_level_module.items.insert((local_def_id, Some(ident.name)), (item, None, None)); + top_level_module + .items + .insert((local_def_id, Some(ident.name)), (item, None, Vec::new())); } } @@ -236,7 +256,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { ) -> bool { debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}"); - let glob = renamed.is_none(); if renamed == Some(kw::Underscore) { // We never inline `_` reexports. return false; @@ -261,6 +280,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { return false; } + let is_glob = renamed.is_none(); let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did); let Some(res_did) = ori_res_did.as_local() else { // For cross-crate impl inlining we need to know whether items are @@ -268,7 +288,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // made reachable by cross-crate inlining which we're checking here. // (this is done here because we need to know this upfront). crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did); - if is_hidden || glob { + if is_hidden || is_glob { return false; } // We store inlined foreign items otherwise, it'd mean that the `use` item would be kept @@ -316,10 +336,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // Bang macros are handled a bit on their because of how they are handled by the // compiler. If they have `#[doc(hidden)]` and the re-export doesn't have // `#[doc(inline)]`, then we don't inline it. - Node::Item(_) if is_bang_macro && !please_inline && renamed.is_some() && is_hidden => { + Node::Item(_) if is_bang_macro && !please_inline && !is_glob && is_hidden => { return false; } - Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_, m), .. }) if glob => { + Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_, m), .. }) if is_glob => { let prev = mem::replace(&mut self.inlining, true); for &i in m.item_ids { let i = tcx.hir_item(i); @@ -328,13 +348,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.inlining = prev; true } - Node::Item(it) if !glob => { + Node::Item(it) if !is_glob => { let prev = mem::replace(&mut self.inlining, true); self.visit_item_inner(it, renamed, Some(def_id)); self.inlining = prev; true } - Node::ForeignItem(it) if !glob => { + Node::ForeignItem(it) if !is_glob => { let prev = mem::replace(&mut self.inlining, true); self.visit_foreign_item_inner(it, renamed, Some(def_id)); self.inlining = prev; @@ -378,8 +398,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { fn add_to_current_mod( &mut self, item: &'tcx hir::Item<'_>, - renamed: Option<Symbol>, - parent_id: Option<LocalDefId>, + mut renamed: Option<Symbol>, + import_id: Option<LocalDefId>, ) { if self.is_importable_from_parent // If we're inside an item, only impl blocks and `macro_rules!` with the `macro_export` @@ -392,11 +412,21 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { _ => false, } { - self.modules - .last_mut() - .unwrap() - .items - .insert((item.owner_id.def_id, renamed), (item, renamed, parent_id)); + if renamed == item.kind.ident().map(|ident| ident.name) { + renamed = None; + } + let key = (item.owner_id.def_id, renamed); + if let Some(import_id) = import_id { + self.modules + .last_mut() + .unwrap() + .items + .entry(key) + .and_modify(|v| v.2.push(import_id)) + .or_insert_with(|| (item, renamed, vec![import_id])); + } else { + self.modules.last_mut().unwrap().items.insert(key, (item, renamed, Vec::new())); + } } } @@ -439,8 +469,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { match item.kind { hir::ItemKind::ForeignMod { items, .. } => { - for item in items { - let item = tcx.hir_foreign_item(item.id); + for &item in items { + let item = tcx.hir_foreign_item(item); self.visit_foreign_item_inner(item, None, None); } } @@ -468,7 +498,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { _ => false, }); let ident = match kind { - hir::UseKind::Single(ident) => Some(renamed.unwrap_or(ident.name)), + hir::UseKind::Single(ident) => Some(ident.name), hir::UseKind::Glob => None, hir::UseKind::ListStem => unreachable!(), }; diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 930b4f62cfcd1f0eabdb30a56d91bf6844b739b +Subproject eabb4cd923deb73e714f7ad3f5234d68ca284db diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs index c410a5da775..07df893ae3c 100644 --- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -8,11 +8,13 @@ use clippy_utils::diagnostics::span_lint_and_note; use clippy_utils::is_cfg_test; use rustc_attr_data_structures::AttributeKind; use rustc_hir::{ - AssocItemKind, Attribute, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind, + Attribute, FieldDef, HirId, IsAuto, ImplItemId, Item, ItemKind, Mod, OwnerId, QPath, TraitItemId, TyKind, Variant, VariantData, }; +use rustc_middle::ty::AssocKind; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; +use rustc_span::Ident; declare_clippy_lint! { /// ### What it does @@ -194,22 +196,22 @@ impl ArbitrarySourceItemOrdering { } /// Produces a linting warning for incorrectly ordered impl items. - fn lint_impl_item<T: LintContext>(&self, cx: &T, item: &ImplItemRef, before_item: &ImplItemRef) { + fn lint_impl_item(&self, cx: &LateContext<'_>, item: ImplItemId, before_item: ImplItemId) { span_lint_and_note( cx, ARBITRARY_SOURCE_ITEM_ORDERING, - item.span, + cx.tcx.def_span(item.owner_id), format!( "incorrect ordering of impl items (defined order: {:?})", self.assoc_types_order ), - Some(before_item.span), - format!("should be placed before `{}`", before_item.ident.name), + Some(cx.tcx.def_span(before_item.owner_id)), + format!("should be placed before `{}`", cx.tcx.item_name(before_item.owner_id)), ); } /// Produces a linting warning for incorrectly ordered item members. - fn lint_member_name<T: LintContext>(cx: &T, ident: &rustc_span::Ident, before_ident: &rustc_span::Ident) { + fn lint_member_name<T: LintContext>(cx: &T, ident: Ident, before_ident: Ident) { span_lint_and_note( cx, ARBITRARY_SOURCE_ITEM_ORDERING, @@ -220,7 +222,7 @@ impl ArbitrarySourceItemOrdering { ); } - fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>, msg: &'static str) { + fn lint_member_item(cx: &LateContext<'_>, item: &Item<'_>, before_item: &Item<'_>, msg: &'static str) { let span = if let Some(ident) = item.kind.ident() { ident.span } else { @@ -245,17 +247,17 @@ impl ArbitrarySourceItemOrdering { } /// Produces a linting warning for incorrectly ordered trait items. - fn lint_trait_item<T: LintContext>(&self, cx: &T, item: &TraitItemRef, before_item: &TraitItemRef) { + fn lint_trait_item(&self, cx: &LateContext<'_>, item: TraitItemId, before_item: TraitItemId) { span_lint_and_note( cx, ARBITRARY_SOURCE_ITEM_ORDERING, - item.span, + cx.tcx.def_span(item.owner_id), format!( "incorrect ordering of trait items (defined order: {:?})", self.assoc_types_order ), - Some(before_item.span), - format!("should be placed before `{}`", before_item.ident.name), + Some(cx.tcx.def_span(before_item.owner_id)), + format!("should be placed before `{}`", cx.tcx.item_name(before_item.owner_id)), ); } } @@ -283,7 +285,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { && cur_v.ident.name.as_str() > variant.ident.name.as_str() && cur_v.span != variant.span { - Self::lint_member_name(cx, &variant.ident, &cur_v.ident); + Self::lint_member_name(cx, variant.ident, cur_v.ident); } cur_v = Some(variant); } @@ -299,7 +301,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { && cur_f.ident.name.as_str() > field.ident.name.as_str() && cur_f.span != field.span { - Self::lint_member_name(cx, &field.ident, &cur_f.ident); + Self::lint_member_name(cx, field.ident, cur_f.ident); } cur_f = Some(field); } @@ -307,49 +309,53 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { ItemKind::Trait(is_auto, _safety, _ident, _generics, _generic_bounds, item_ref) if self.enable_ordering_for_trait && *is_auto == IsAuto::No => { - let mut cur_t: Option<&TraitItemRef> = None; + let mut cur_t: Option<(TraitItemId, Ident)> = None; - for item in *item_ref { - if item.span.in_external_macro(cx.sess().source_map()) { + for &item in *item_ref { + let span = cx.tcx.def_span(item.owner_id); + let ident = cx.tcx.item_ident(item.owner_id); + if span.in_external_macro(cx.sess().source_map()) { continue; } - if let Some(cur_t) = cur_t { - let cur_t_kind = convert_assoc_item_kind(cur_t.kind); + if let Some((cur_t, cur_ident)) = cur_t { + let cur_t_kind = convert_assoc_item_kind(cx, cur_t.owner_id); let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind); - let item_kind = convert_assoc_item_kind(item.kind); + let item_kind = convert_assoc_item_kind(cx, item.owner_id); let item_kind_index = self.assoc_types_order.index_of(&item_kind); - if cur_t_kind == item_kind && cur_t.ident.name.as_str() > item.ident.name.as_str() { - Self::lint_member_name(cx, &item.ident, &cur_t.ident); + if cur_t_kind == item_kind && cur_ident.name.as_str() > ident.name.as_str() { + Self::lint_member_name(cx, ident, cur_ident); } else if cur_t_kind_index > item_kind_index { self.lint_trait_item(cx, item, cur_t); } } - cur_t = Some(item); + cur_t = Some((item, ident)); } }, ItemKind::Impl(trait_impl) if self.enable_ordering_for_impl => { - let mut cur_t: Option<&ImplItemRef> = None; + let mut cur_t: Option<(ImplItemId, Ident)> = None; - for item in trait_impl.items { - if item.span.in_external_macro(cx.sess().source_map()) { + for &item in trait_impl.items { + let span = cx.tcx.def_span(item.owner_id); + let ident = cx.tcx.item_ident(item.owner_id); + if span.in_external_macro(cx.sess().source_map()) { continue; } - if let Some(cur_t) = cur_t { - let cur_t_kind = convert_assoc_item_kind(cur_t.kind); + if let Some((cur_t, cur_ident)) = cur_t { + let cur_t_kind = convert_assoc_item_kind(cx, cur_t.owner_id); let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind); - let item_kind = convert_assoc_item_kind(item.kind); + let item_kind = convert_assoc_item_kind(cx, item.owner_id); let item_kind_index = self.assoc_types_order.index_of(&item_kind); - if cur_t_kind == item_kind && cur_t.ident.name.as_str() > item.ident.name.as_str() { - Self::lint_member_name(cx, &item.ident, &cur_t.ident); + if cur_t_kind == item_kind && cur_ident.name.as_str() > ident.name.as_str() { + Self::lint_member_name(cx, ident, cur_ident); } else if cur_t_kind_index > item_kind_index { self.lint_impl_item(cx, item, cur_t); } } - cur_t = Some(item); + cur_t = Some((item, ident)); } }, _ => {}, // Catch-all for `ItemKinds` that don't have fields. @@ -458,18 +464,19 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { } } -/// Converts a [`rustc_hir::AssocItemKind`] to a -/// [`SourceItemOrderingTraitAssocItemKind`]. +/// Converts a [`ty::AssocKind`] to a [`SourceItemOrderingTraitAssocItemKind`]. /// /// This is implemented here because `rustc_hir` is not a dependency of /// `clippy_config`. -fn convert_assoc_item_kind(value: AssocItemKind) -> SourceItemOrderingTraitAssocItemKind { +fn convert_assoc_item_kind(cx: &LateContext<'_>, owner_id: OwnerId) -> SourceItemOrderingTraitAssocItemKind { + let kind = cx.tcx.associated_item(owner_id.def_id).kind; + #[allow(clippy::enum_glob_use)] // Very local glob use for legibility. use SourceItemOrderingTraitAssocItemKind::*; - match value { - AssocItemKind::Const => Const, - AssocItemKind::Type => Type, - AssocItemKind::Fn { .. } => Fn, + match kind { + AssocKind::Const{..} => Const, + AssocKind::Type {..}=> Type, + AssocKind::Fn { .. } => Fn, } } diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs index bf43234ff50..61c2fc49bd7 100644 --- a/src/tools/clippy/clippy_lints/src/booleans.rs +++ b/src/tools/clippy/clippy_lints/src/booleans.rs @@ -1,5 +1,6 @@ use clippy_config::Conf; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; +use clippy_utils::higher::has_let_expr; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::sugg::Sugg; @@ -646,7 +647,9 @@ impl<'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'_, 'tcx> { fn visit_expr(&mut self, e: &'tcx Expr<'_>) { if !e.span.from_expansion() { match &e.kind { - ExprKind::Binary(binop, _, _) if binop.node == BinOpKind::Or || binop.node == BinOpKind::And => { + ExprKind::Binary(binop, _, _) + if binop.node == BinOpKind::Or || binop.node == BinOpKind::And && !has_let_expr(e) => + { self.bool_expr(e); }, ExprKind::Unary(UnOp::Not, inner) => { diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index 10331b3855b..0a481ddcd12 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -192,7 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { && !item.span.from_expansion() && let Some(def_id) = trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::Default, def_id) - && let impl_item_hir = child.id.hir_id() + && let impl_item_hir = child.hir_id() && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b) diff --git a/src/tools/clippy/clippy_lints/src/empty_drop.rs b/src/tools/clippy/clippy_lints/src/empty_drop.rs index d557a36c7ac..4e948701da4 100644 --- a/src/tools/clippy/clippy_lints/src/empty_drop.rs +++ b/src/tools/clippy/clippy_lints/src/empty_drop.rs @@ -41,7 +41,7 @@ impl LateLintPass<'_> for EmptyDrop { .. }) = item.kind && trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait() - && let impl_item_hir = child.id.hir_id() + && let impl_item_hir = child.hir_id() && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b) diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 2cb3b32babe..db2fea1aae9 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -1,7 +1,8 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_hir; use rustc_abi::ExternAbi; -use rustc_hir::{AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind, intravisit}; +use rustc_hir::{Body, FnDecl, HirId, HirIdSet, Node, Pat, PatKind, intravisit}; +use rustc_hir::def::DefKind; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; @@ -84,23 +85,18 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { .def_id; let mut trait_self_ty = None; - if let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_id) { + match cx.tcx.def_kind(parent_id) { // If the method is an impl for a trait, don't warn. - if let ItemKind::Impl(Impl { of_trait: Some(_), .. }) = item.kind { - return; + DefKind::Impl { of_trait: true } => { + return } // find `self` ty for this trait if relevant - if let ItemKind::Trait(_, _, _, _, _, items) = item.kind { - for trait_item in items { - if trait_item.id.owner_id.def_id == fn_def_id - // be sure we have `self` parameter in this function - && trait_item.kind == (AssocItemKind::Fn { has_self: true }) - { - trait_self_ty = Some(TraitRef::identity(cx.tcx, trait_item.id.owner_id.to_def_id()).self_ty()); - } - } + DefKind::Trait => { + trait_self_ty = Some(TraitRef::identity(cx.tcx, parent_id.to_def_id()).self_ty()); } + + _ => {} } let mut v = EscapeDelegate { diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs index 68d0cd19c8a..552cd721f4e 100644 --- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs +++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs @@ -52,20 +52,20 @@ declare_lint_pass!(FallibleImplFrom => [FALLIBLE_IMPL_FROM]); impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { // check for `impl From<???> for ..` - if let hir::ItemKind::Impl(impl_) = &item.kind + if let hir::ItemKind::Impl(_) = &item.kind && let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id) && cx .tcx .is_diagnostic_item(sym::From, impl_trait_ref.skip_binder().def_id) { - lint_impl_body(cx, item.span, impl_.items); + lint_impl_body(cx, item.owner_id, item.span); } } } -fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::ImplItemRef]) { +fn lint_impl_body(cx: &LateContext<'_>, item_def_id: hir::OwnerId, impl_span: Span) { use rustc_hir::intravisit::{self, Visitor}; - use rustc_hir::{Expr, ImplItemKind}; + use rustc_hir::Expr; struct FindPanicUnwrap<'a, 'tcx> { lcx: &'a LateContext<'tcx>, @@ -96,35 +96,35 @@ fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::Impl } } - for impl_item in impl_items { - if impl_item.ident.name == sym::from - && let ImplItemKind::Fn(_, body_id) = cx.tcx.hir_impl_item(impl_item.id).kind - { - // check the body for `begin_panic` or `unwrap` - let body = cx.tcx.hir_body(body_id); - let mut fpu = FindPanicUnwrap { - lcx: cx, - typeck_results: cx.tcx.typeck(impl_item.id.owner_id.def_id), - result: Vec::new(), - }; - fpu.visit_expr(body.value); + for impl_item in cx.tcx.associated_items(item_def_id) + .filter_by_name_unhygienic_and_kind(sym::from, ty::AssocTag::Fn) + { + let impl_item_def_id= impl_item.def_id.expect_local(); - // if we've found one, lint - if !fpu.result.is_empty() { - span_lint_and_then( - cx, - FALLIBLE_IMPL_FROM, - impl_span, - "consider implementing `TryFrom` instead", - move |diag| { - diag.help( - "`From` is intended for infallible conversions only. \ - Use `TryFrom` if there's a possibility for the conversion to fail", - ); - diag.span_note(fpu.result, "potential failure(s)"); - }, - ); - } + // check the body for `begin_panic` or `unwrap` + let body = cx.tcx.hir_body_owned_by(impl_item_def_id); + let mut fpu = FindPanicUnwrap { + lcx: cx, + typeck_results: cx.tcx.typeck(impl_item_def_id), + result: Vec::new(), + }; + fpu.visit_expr(body.value); + + // if we've found one, lint + if !fpu.result.is_empty() { + span_lint_and_then( + cx, + FALLIBLE_IMPL_FROM, + impl_span, + "consider implementing `TryFrom` instead", + move |diag| { + diag.help( + "`From` is intended for infallible conversions only. \ + Use `TryFrom` if there's a possibility for the conversion to fail", + ); + diag.span_note(fpu.result, "potential failure(s)"); + }, + ); } } } diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs index be887b03ae4..85b40ba7419 100644 --- a/src/tools/clippy/clippy_lints/src/from_over_into.rs +++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs @@ -9,7 +9,7 @@ use clippy_utils::source::SpanRangeExt; use rustc_errors::Applicability; use rustc_hir::intravisit::{Visitor, walk_path}; use rustc_hir::{ - FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemRef, Item, ItemKind, PatKind, Path, + FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemId, Item, ItemKind, PatKind, Path, PathSegment, Ty, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; @@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { middle_trait_ref.self_ty() ); if let Some(suggestions) = - convert_to_from(cx, into_trait_seg, target_ty.as_unambig_ty(), self_ty, impl_item_ref) + convert_to_from(cx, into_trait_seg, target_ty.as_unambig_ty(), self_ty, *impl_item_ref) { diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable); } else { @@ -164,14 +164,14 @@ fn convert_to_from( into_trait_seg: &PathSegment<'_>, target_ty: &Ty<'_>, self_ty: &Ty<'_>, - impl_item_ref: &ImplItemRef, + impl_item_ref: ImplItemId, ) -> Option<Vec<(Span, String)>> { if !target_ty.find_self_aliases().is_empty() { // It's tricky to expand self-aliases correctly, we'll ignore it to not cause a // bad suggestion/fix. return None; } - let impl_item = cx.tcx.hir_impl_item(impl_item_ref.id); + let impl_item = cx.tcx.hir_impl_item(impl_item_ref); let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else { return None; }; diff --git a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs index 2d22bb157a9..0d6191f2c97 100644 --- a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs +++ b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::hir_id::OwnerId; -use rustc_hir::{Impl, ImplItem, ImplItemKind, ImplItemRef, ItemKind, Node, TraitRef}; +use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node, TraitRef}; use rustc_lint::LateContext; use rustc_span::Span; use rustc_span::symbol::{Ident, kw}; @@ -15,11 +15,10 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored && let parent_node = cx.tcx.parent_hir_node(item.hir_id()) && let Node::Item(parent_item) = parent_node && let ItemKind::Impl(Impl { - items, of_trait: Some(trait_ref), .. }) = &parent_item.kind - && let Some(did) = trait_item_def_id_of_impl(items, item.owner_id) + && let Some(did) = trait_item_def_id_of_impl(cx, item.owner_id) && !is_from_ignored_trait(trait_ref, ignored_traits) { let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id); @@ -93,14 +92,8 @@ impl RenamedFnArgs { } /// Get the [`trait_item_def_id`](ImplItemRef::trait_item_def_id) of a relevant impl item. -fn trait_item_def_id_of_impl(items: &[ImplItemRef], target: OwnerId) -> Option<DefId> { - items.iter().find_map(|item| { - if item.id.owner_id == target { - item.trait_item_def_id - } else { - None - } - }) +fn trait_item_def_id_of_impl(cx: &LateContext<'_>, target: OwnerId) -> Option<DefId> { + cx.tcx.associated_item(target).trait_item_def_id } fn is_from_ignored_trait(of_trait: &TraitRef<'_>, ignored_traits: &DefIdSet) -> bool { diff --git a/src/tools/clippy/clippy_lints/src/if_not_else.rs b/src/tools/clippy/clippy_lints/src/if_not_else.rs index ab7a965b367..25fed0d4dd1 100644 --- a/src/tools/clippy/clippy_lints/src/if_not_else.rs +++ b/src/tools/clippy/clippy_lints/src/if_not_else.rs @@ -51,7 +51,6 @@ declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]); impl LateLintPass<'_> for IfNotElse { fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) { if let ExprKind::If(cond, cond_inner, Some(els)) = e.kind - && let ExprKind::DropTemps(cond) = cond.kind && let ExprKind::Block(..) = els.kind { let (msg, help) = match cond.kind { diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs index cab7a9fb709..b3c90f364e8 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs @@ -130,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { }); let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target); - for item in impl_.items.iter().map(|item| cx.tcx.hir_impl_item(item.id)) { + for item in impl_.items.iter().map(|&item| cx.tcx.hir_impl_item(item)) { ctr_vis.visit_impl_item(item); } diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs index 185fc2aa2d4..0fdbf679738 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs @@ -41,8 +41,7 @@ declare_lint_pass!(ImplicitSaturatingAdd => [IMPLICIT_SATURATING_ADD]); impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if let ExprKind::If(cond, then, None) = expr.kind - && let ExprKind::DropTemps(expr1) = cond.kind - && let Some((c, op_node, l)) = get_const(cx, expr1) + && let Some((c, op_node, l)) = get_const(cx, cond) && let BinOpKind::Ne | BinOpKind::Lt = op_node && let ExprKind::Block(block, None) = then.kind && let Block { @@ -66,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd { && Some(c) == get_int_max(ty) && let ctxt = expr.span.ctxt() && ex.span.ctxt() == ctxt - && expr1.span.ctxt() == ctxt + && cond.span.ctxt() == ctxt && clippy_utils::SpanlessEq::new(cx).eq_expr(l, target) && AssignOpKind::AddAssign == op1.node && let ExprKind::Lit(lit) = value.kind diff --git a/src/tools/clippy/clippy_lints/src/infallible_try_from.rs b/src/tools/clippy/clippy_lints/src/infallible_try_from.rs index b54c289fa7e..e79fcec6e6a 100644 --- a/src/tools/clippy/clippy_lints/src/infallible_try_from.rs +++ b/src/tools/clippy/clippy_lints/src/infallible_try_from.rs @@ -1,8 +1,9 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::sym; use rustc_errors::MultiSpan; -use rustc_hir::{AssocItemKind, Item, ItemKind}; +use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::AssocTag; use rustc_session::declare_lint_pass; declare_clippy_lint! { @@ -51,25 +52,23 @@ impl<'tcx> LateLintPass<'tcx> for InfallibleTryFrom { if !cx.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id) { return; } - for ii in imp.items { - if ii.kind == AssocItemKind::Type { - let ii = cx.tcx.hir_impl_item(ii.id); - if ii.ident.name != sym::Error { - continue; - } - let ii_ty = ii.expect_type(); - let ii_ty_span = ii_ty.span; - let ii_ty = clippy_utils::ty::ty_from_hir_ty(cx, ii_ty); - if !ii_ty.is_inhabited_from(cx.tcx, ii.owner_id.to_def_id(), cx.typing_env()) { - let mut span = MultiSpan::from_span(cx.tcx.def_span(item.owner_id.to_def_id())); - span.push_span_label(ii_ty_span, "infallible error type"); - span_lint( - cx, - INFALLIBLE_TRY_FROM, - span, - "infallible TryFrom impl; consider implementing From, instead", - ); - } + for ii in cx.tcx.associated_items(item.owner_id.def_id) + .filter_by_name_unhygienic_and_kind(sym::Error, AssocTag::Type) + { + let ii_ty = cx.tcx.type_of(ii.def_id).instantiate_identity(); + if !ii_ty.is_inhabited_from(cx.tcx, ii.def_id, cx.typing_env()) { + let mut span = MultiSpan::from_span(cx.tcx.def_span(item.owner_id.to_def_id())); + let ii_ty_span = cx.tcx.hir_node_by_def_id(ii.def_id.expect_local()) + .expect_impl_item() + .expect_type() + .span; + span.push_span_label(ii_ty_span, "infallible error type"); + span_lint( + cx, + INFALLIBLE_TRY_FROM, + span, + "infallible TryFrom impl; consider implementing From, instead", + ); } } } diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs index 900b20aa9cf..03038f0ab49 100644 --- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs +++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs @@ -139,13 +139,12 @@ impl LateLintPass<'_> for IterWithoutIntoIter { // We can't check inherent impls for slices, but we know that they have an `iter(_mut)` method ty.peel_refs().is_slice() || get_adt_inherent_method(cx, ty, expected_method_name).is_some() }) - && let Some(iter_assoc_span) = imp.items.iter().find_map(|item| { - if item.ident.name == sym::IntoIter { - Some(cx.tcx.hir_impl_item(item.id).expect_type().span) - } else { - None - } - }) + && let Some(iter_assoc_span) = cx.tcx.associated_items(item.owner_id) + .filter_by_name_unhygienic_and_kind(sym::IntoIter, ty::AssocTag::Type) + .next() + .map(|assoc_item| { + cx.tcx.hir_node_by_def_id(assoc_item.def_id.expect_local()).expect_impl_item().expect_type().span + }) && is_ty_exported(cx, ty) { span_lint_and_then( diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index aded31971ce..d32017a8b41 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -10,14 +10,15 @@ use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::{ - AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind, + BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind, ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatExprKind, PatKind, PathSegment, PrimTy, - QPath, TraitItemRef, TyKind, + QPath, TraitItemId, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, FnSig, Ty}; use rustc_session::declare_lint_pass; use rustc_span::source_map::Spanned; +use rustc_span::symbol::kw; use rustc_span::{Ident, Span, Symbol}; use rustc_trait_selection::traits::supertrait_def_ids; @@ -264,22 +265,13 @@ fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span { } } -fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemRef]) { - fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool { - item.ident.name == name - && if let AssocItemKind::Fn { has_self } = item.kind { - has_self && { - cx.tcx - .fn_sig(item.id.owner_id) - .skip_binder() - .inputs() - .skip_binder() - .len() - == 1 - } - } else { - false - } +fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemId]) { + fn is_named_self(cx: &LateContext<'_>, item: &TraitItemId, name: Symbol) -> bool { + cx.tcx.item_name(item.owner_id) == name + && matches!( + cx.tcx.fn_arg_idents(item.owner_id), + [Some(Ident { name: kw::SelfLower, .. })], + ) } // fill the set with current and super traits diff --git a/src/tools/clippy/clippy_lints/src/let_if_seq.rs b/src/tools/clippy/clippy_lints/src/let_if_seq.rs index 5db28e9ae9b..e480c8fbed5 100644 --- a/src/tools/clippy/clippy_lints/src/let_if_seq.rs +++ b/src/tools/clippy/clippy_lints/src/let_if_seq.rs @@ -62,15 +62,8 @@ impl<'tcx> LateLintPass<'tcx> for LetIfSeq { if let hir::StmtKind::Let(local) = stmt.kind && let hir::PatKind::Binding(mode, canonical_id, ident, None) = local.pat.kind && let hir::StmtKind::Expr(if_) = next.kind - && let hir::ExprKind::If( - hir::Expr { - kind: hir::ExprKind::DropTemps(cond), - .. - }, - then, - else_, - ) = if_.kind - && !is_local_used(cx, *cond, canonical_id) + && let hir::ExprKind::If(cond, then, else_) = if_.kind + && !is_local_used(cx, cond, canonical_id) && let hir::ExprKind::Block(then, _) = then.kind && let Some(value) = check_assign(cx, canonical_id, then) && !is_local_used(cx, value, canonical_id) diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index caf17c10484..35c9d2fd4eb 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -716,7 +716,7 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<' walk_trait_ref(&mut checker, trait_ref); } walk_unambig_ty(&mut checker, impl_.self_ty); - for item in impl_.items { + for &item in impl_.items { walk_impl_item_ref(&mut checker, item); } diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs index d4d33029dbd..760ecf07589 100644 --- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs +++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs @@ -8,7 +8,7 @@ use rustc_ast::LitKind; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{ - Block, Expr, ExprKind, Impl, ImplItem, ImplItemKind, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData, + Block, Expr, ExprKind, Impl, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{Ty, TypeckResults}; @@ -200,7 +200,7 @@ fn check_struct<'tcx>( impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { // is this an `impl Debug for X` block? - if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, items, .. }) = item.kind + if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, .. }) = item.kind && let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res && let TyKind::Path(QPath::Resolved(_, self_path)) = &self_ty.kind // make sure that the self type is either a struct, an enum or a union @@ -212,9 +212,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { && !cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) && !item.span.from_expansion() // find `Debug::fmt` function - && let Some(fmt_item) = items.iter().find(|i| i.ident.name == sym::fmt) - && let ImplItem { kind: ImplItemKind::Fn(_, body_id), .. } = cx.tcx.hir_impl_item(fmt_item.id) - && let body = cx.tcx.hir_body(*body_id) + && let Some(fmt_item) = cx.tcx.associated_items(item.owner_id).filter_by_name_unhygienic(sym::fmt).next() + && let body = cx.tcx.hir_body_owned_by(fmt_item.def_id.expect_local()) && let ExprKind::Block(block, _) = body.value.kind // inspect `self` && let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs() @@ -222,7 +221,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { && let Some(self_def_id) = self_adt.did().as_local() && let Node::Item(self_item) = cx.tcx.hir_node_by_def_id(self_def_id) // NB: can't call cx.typeck_results() as we are not in a body - && let typeck_results = cx.tcx.typeck_body(*body_id) + && let typeck_results = cx.tcx.typeck_body(body.id()) && should_lint(cx, typeck_results, block) // we intentionally only lint structs, see lint description && let ItemKind::Struct(_, _, data) = &self_item.kind diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 25c95d23436..329f7193437 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -104,16 +104,16 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _ident, _generics, _bounds, trait_items) => { // note: we need to check if the trait is exported so we can't use // `LateLintPass::check_trait_item` here. - for tit in trait_items { - let tit_ = cx.tcx.hir_trait_item(tit.id); + for &tit in trait_items { + let tit_ = cx.tcx.hir_trait_item(tit); match tit_.kind { hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {}, hir::TraitItemKind::Fn(..) => { - if cx.tcx.defaultness(tit.id.owner_id).has_value() { + if cx.tcx.defaultness(tit.owner_id).has_value() { // trait method with default body needs inline in case // an impl is not provided let desc = "a default trait method"; - let item = cx.tcx.hir_trait_item(tit.id); + let item = cx.tcx.hir_trait_item(tit); let attrs = cx.tcx.hir_attrs(item.hir_id()); check_missing_inline_attrs(cx, attrs, item.span, desc); } diff --git a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs index e266c36b6e7..fa61d0fa11a 100644 --- a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs +++ b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs @@ -61,15 +61,14 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods { if !is_lint_allowed(cx, MISSING_TRAIT_METHODS, item.hir_id()) && span_is_local(item.span) && let ItemKind::Impl(Impl { - items, of_trait: Some(trait_ref), .. }) = item.kind && let Some(trait_id) = trait_ref.trait_def_id() { - let trait_item_ids: DefIdSet = items - .iter() - .filter_map(|impl_item| impl_item.trait_item_def_id) + let trait_item_ids: DefIdSet = cx.tcx.associated_items(item.owner_id) + .in_definition_order() + .filter_map(|assoc_item| assoc_item.trait_item_def_id) .collect(); for assoc in cx diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs index 4b73a4455f5..3b86f1d1f59 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -6,6 +6,7 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::HirIdSet; use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::ty::AssocKind; use rustc_session::impl_lint_pass; use rustc_span::sym; @@ -61,18 +62,18 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { of_trait: None, generics, self_ty: impl_self_ty, - items, .. }) = item.kind { - for assoc_item in *items { - if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) { - let impl_item = cx.tcx.hir_impl_item(assoc_item.id); + for assoc_item in cx.tcx.associated_items(item.owner_id.def_id) + .filter_by_name_unhygienic(sym::new) + { + if let AssocKind::Fn { has_self: false, .. } = assoc_item.kind { + let impl_item = cx.tcx.hir_node_by_def_id(assoc_item.def_id.expect_local()).expect_impl_item(); if impl_item.span.in_external_macro(cx.sess().source_map()) { return; } if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind { - let name = impl_item.ident.name; let id = impl_item.owner_id; if sig.header.is_unsafe() { // can't be implemented for unsafe new @@ -88,11 +89,9 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { return; } if sig.decl.inputs.is_empty() - && name == sym::new && cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id) - && let self_def_id = cx.tcx.hir_get_parent_item(id.into()) - && let self_ty = cx.tcx.type_of(self_def_id).instantiate_identity() - && self_ty == return_ty(cx, id) + && let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && self_ty == return_ty(cx, impl_item.owner_id) && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default) { if self.impling_types.is_none() { @@ -111,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { // Check if a Default implementation exists for the Self type, regardless of // generics if let Some(ref impling_types) = self.impling_types - && let self_def = cx.tcx.type_of(self_def_id).instantiate_identity() + && let self_def = cx.tcx.type_of(item.owner_id).instantiate_identity() && let Some(self_def) = self_def.ty_adt_def() && let Some(self_local_did) = self_def.did().as_local() && let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did) diff --git a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs index 8eaf65e6306..301b2cd4bf2 100644 --- a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs +++ b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs @@ -43,12 +43,12 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl { && trait_ref.path.res.def_id() == eq_trait { for impl_item in *impl_items { - if impl_item.ident.name == sym::ne { + if cx.tcx.item_name(impl_item.owner_id) == sym::ne { span_lint_hir( cx, PARTIALEQ_NE_IMPL, - impl_item.id.hir_id(), - impl_item.span, + impl_item.hir_id(), + cx.tcx.def_span(impl_item.owner_id), "re-implementing `PartialEq::ne` is unnecessary", ); } diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 226e8ff6adb..85fde780e68 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -3,7 +3,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::AssocItem; +use rustc_middle::ty::{AssocKind, AssocItem}; use rustc_session::declare_lint_pass; use rustc_span::Span; use rustc_span::symbol::Symbol; @@ -54,7 +54,6 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. }) && let item = cx.tcx.hir_item(id) && let ItemKind::Impl(Impl { - items, of_trait, self_ty, .. @@ -115,13 +114,11 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { } }; - for impl_item_ref in (*items) - .iter() - .filter(|impl_item_ref| matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. })) - { - let method_name = impl_item_ref.ident.name; - methods_in_trait.remove(&method_name); - check_trait_method(method_name, impl_item_ref.span); + for assoc_item in cx.tcx.associated_items(id.owner_id).in_definition_order() { + if let AssocKind::Fn { name, .. } = assoc_item.kind { + methods_in_trait.remove(&name); + check_trait_method(name, cx.tcx.def_span(assoc_item.def_id)); + } } for method_name in methods_in_trait { @@ -129,14 +126,11 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { } }, None => { - for impl_item_ref in (*items) - .iter() - .filter(|impl_item_ref| matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. })) - { - let method_name = impl_item_ref.ident.name; - let impl_span = impl_item_ref.span; - let hir_id = impl_item_ref.id.hir_id(); - if let Some(trait_spans) = existing_name.trait_methods.get(&method_name) { + for assoc_item in cx.tcx.associated_items(id.owner_id).in_definition_order() { + let AssocKind::Fn { name, .. } = assoc_item.kind else { continue }; + let impl_span = cx.tcx.def_span(assoc_item.def_id); + let hir_id = cx.tcx.local_def_id_to_hir_id(assoc_item.def_id.expect_local()); + if let Some(trait_spans) = existing_name.trait_methods.get(&name) { span_lint_hir_and_then( cx, SAME_NAME_METHOD, @@ -148,12 +142,12 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { // iterate on trait_spans? diag.span_note( trait_spans[0], - format!("existing `{method_name}` defined here"), + format!("existing `{name}` defined here"), ); }, ); } - existing_name.impl_methods.insert(method_name, (impl_span, hir_id)); + existing_name.impl_methods.insert(name, (impl_span, hir_id)); } }, } diff --git a/src/tools/clippy/clippy_lints/src/serde_api.rs b/src/tools/clippy/clippy_lints/src/serde_api.rs index b36a5d6d502..2de22e4b6a3 100644 --- a/src/tools/clippy/clippy_lints/src/serde_api.rs +++ b/src/tools/clippy/clippy_lints/src/serde_api.rs @@ -36,9 +36,9 @@ impl<'tcx> LateLintPass<'tcx> for SerdeApi { let mut seen_str = None; let mut seen_string = None; for item in *items { - match item.ident.name { - sym::visit_str => seen_str = Some(item.span), - sym::visit_string => seen_string = Some(item.span), + match cx.tcx.item_name(item.owner_id) { + sym::visit_str => seen_str = Some(cx.tcx.def_span(item.owner_id)), + sym::visit_string => seen_string = Some(cx.tcx.def_span(item.owner_id)), _ => {}, } } diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index 45c0d459d90..cf603c6190b 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -9,7 +9,7 @@ use clippy_utils::visitors::{Descend, for_each_expr}; use hir::HirId; use rustc_hir as hir; use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource}; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; use rustc_span::{BytePos, Pos, RelativeBytePos, Span, SyntaxContext}; @@ -760,7 +760,7 @@ fn text_has_safety_comment(src: &str, line_starts: &[RelativeBytePos], start_pos loop { if line.starts_with("/*") { let src = &src[line_start..line_starts.last().unwrap().to_usize()]; - let mut tokens = tokenize(src); + let mut tokens = tokenize(src, FrontmatterAllowed::No); return (src[..tokens.next().unwrap().len as usize] .to_ascii_uppercase() .contains("SAFETY:") diff --git a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs index 8f314ce7a60..6629a67f78b 100644 --- a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs @@ -3,7 +3,7 @@ use clippy_utils::source::SpanRangeExt; use itertools::Itertools; use rustc_ast::{Crate, Expr, ExprKind, FormatArgs}; use rustc_data_structures::fx::FxHashMap; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::impl_lint_pass; use rustc_span::{Span, hygiene}; @@ -82,7 +82,7 @@ fn has_span_from_proc_macro(cx: &EarlyContext<'_>, args: &FormatArgs) -> bool { .all(|sp| { sp.check_source_text(cx, |src| { // text should be either `, name` or `, name =` - let mut iter = tokenize(src).filter(|t| { + let mut iter = tokenize(src, FrontmatterAllowed::No).filter(|t| { !matches!( t.kind, TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 94b7055ad20..25afa12e95d 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::{ BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp, }; -use rustc_lexer::tokenize; +use rustc_lexer::{FrontmatterAllowed, tokenize}; use rustc_lint::LateContext; use rustc_middle::mir::ConstValue; use rustc_middle::mir::interpret::{Scalar, alloc_range}; @@ -711,7 +711,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { && let Some(src) = src.as_str() { use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace}; - if !tokenize(src) + if !tokenize(src, FrontmatterAllowed::No) .map(|t| t.kind) .filter(|t| !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)) .eq([OpenBrace]) diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs index 6971b488013..4e0b00df950 100644 --- a/src/tools/clippy/clippy_utils/src/higher.rs +++ b/src/tools/clippy/clippy_utils/src/higher.rs @@ -54,7 +54,7 @@ impl<'tcx> ForLoop<'tcx> { } } -/// An `if` expression without `DropTemps` +/// An `if` expression without `let` pub struct If<'hir> { /// `if` condition pub cond: &'hir Expr<'hir>, @@ -66,16 +66,10 @@ pub struct If<'hir> { impl<'hir> If<'hir> { #[inline] - /// Parses an `if` expression + /// Parses an `if` expression without `let` pub const fn hir(expr: &Expr<'hir>) -> Option<Self> { - if let ExprKind::If( - Expr { - kind: ExprKind::DropTemps(cond), - .. - }, - then, - r#else, - ) = expr.kind + if let ExprKind::If(cond, then, r#else) = expr.kind + && !has_let_expr(cond) { Some(Self { cond, then, r#else }) } else { @@ -198,18 +192,10 @@ impl<'hir> IfOrIfLet<'hir> { /// Parses an `if` or `if let` expression pub const fn hir(expr: &Expr<'hir>) -> Option<Self> { if let ExprKind::If(cond, then, r#else) = expr.kind { - if let ExprKind::DropTemps(new_cond) = cond.kind { - return Some(Self { - cond: new_cond, - then, - r#else, - }); - } - if let ExprKind::Let(..) = cond.kind { - return Some(Self { cond, then, r#else }); - } + Some(Self { cond, then, r#else }) + } else { + None } - None } } @@ -343,15 +329,7 @@ impl<'hir> While<'hir> { Block { expr: Some(Expr { - kind: - ExprKind::If( - Expr { - kind: ExprKind::DropTemps(condition), - .. - }, - body, - _, - ), + kind: ExprKind::If(condition, body, _), .. }), .. @@ -360,6 +338,7 @@ impl<'hir> While<'hir> { LoopSource::While, span, ) = expr.kind + && !has_let_expr(condition) { return Some(Self { condition, body, span }); } @@ -493,3 +472,13 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) - } None } + +/// Checks that a condition doesn't have a `let` expression, to keep `If` and `While` from accepting +/// `if let` and `while let`. +pub const fn has_let_expr<'tcx>(cond: &'tcx Expr<'tcx>) -> bool { + match &cond.kind { + ExprKind::Let(_) => true, + ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs), + _ => false, + } +} diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 6f19ce80cf6..f0d7fb89c44 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -13,7 +13,7 @@ use rustc_hir::{ Node, Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr, TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind, }; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::LateContext; use rustc_middle::ty::TypeckResults; use rustc_span::{BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext, sym}; @@ -687,7 +687,7 @@ fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &' // `{}` => `()` ([], None) if block.span.check_source_text(cx, |src| { - tokenize(src) + tokenize(src, FrontmatterAllowed::No) .map(|t| t.kind) .filter(|t| { !matches!( diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 2e03743e621..54de9baeb12 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -107,7 +107,7 @@ use rustc_hir::{ Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, TraitFn, TraitItem, TraitItemKind, TraitRef, TyKind, UnOp, def, }; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_middle::hir::nested_filter; use rustc_middle::hir::place::PlaceBase; @@ -2765,7 +2765,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'tcx>) -> ExprUseCtx /// Tokenizes the input while keeping the text associated with each token. pub fn tokenize_with_text(s: &str) -> impl Iterator<Item = (TokenKind, &str, InnerSpan)> { let mut pos = 0; - tokenize(s).map(move |t| { + tokenize(s, FrontmatterAllowed::No).map(move |t| { let end = pos + t.len; let range = pos as usize..end as usize; let inner = InnerSpan::new(range.start, range.end); @@ -2780,7 +2780,7 @@ pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool { let Ok(snippet) = sm.span_to_snippet(span) else { return false; }; - return tokenize(&snippet).any(|token| { + return tokenize(&snippet, FrontmatterAllowed::No).any(|token| { matches!( token.kind, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. } diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs index 8bbcb220210..c681806517a 100644 --- a/src/tools/clippy/clippy_utils/src/paths.rs +++ b/src/tools/clippy/clippy_utils/src/paths.rs @@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::Namespace::{MacroNS, TypeNS, ValueNS}; use rustc_hir::def::{DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; -use rustc_hir::{ImplItemRef, ItemKind, Node, OwnerId, TraitItemRef, UseKind}; +use rustc_hir::{ItemKind, Node, UseKind}; use rustc_lint::LateContext; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{FloatTy, IntTy, Ty, TyCtxt, UintTy}; @@ -284,14 +284,6 @@ fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, n _ => return None, }; - let res = |ident: Ident, owner_id: OwnerId| { - if ident.name == name && ns.matches(tcx.def_kind(owner_id).ns()) { - Some(owner_id.to_def_id()) - } else { - None - } - }; - match item_kind { ItemKind::Mod(_, r#mod) => r#mod.item_ids.iter().find_map(|&item_id| { let item = tcx.hir_item(item_id); @@ -307,17 +299,19 @@ fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, n } else { None } + } else if let Some(ident) = item.kind.ident() + && ident.name == name + && ns.matches(tcx.def_kind(item.owner_id).ns()) + { + Some(item.owner_id.to_def_id()) } else { - res(item.kind.ident()?, item_id.owner_id) + None } }), - ItemKind::Impl(r#impl) => r#impl - .items - .iter() - .find_map(|&ImplItemRef { ident, id, .. }| res(ident, id.owner_id)), - ItemKind::Trait(.., trait_item_refs) => trait_item_refs - .iter() - .find_map(|&TraitItemRef { ident, id, .. }| res(ident, id.owner_id)), + ItemKind::Impl(..) | ItemKind::Trait(..) + => tcx.associated_items(local_id).filter_by_name_unhygienic(name) + .find(|assoc_item| ns.matches(Some(assoc_item.namespace()))) + .map(|assoc_item| assoc_item.def_id), _ => None, } } diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs index 7f2bf99daff..7d21336be1c 100644 --- a/src/tools/clippy/clippy_utils/src/source.rs +++ b/src/tools/clippy/clippy_utils/src/source.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use rustc_ast::{LitKind, StrStyle}; use rustc_errors::Applicability; use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource}; -use rustc_lexer::{LiteralKind, TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, LiteralKind, TokenKind, tokenize}; use rustc_lint::{EarlyContext, LateContext}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; @@ -277,7 +277,7 @@ fn map_range( } fn ends_with_line_comment_or_broken(text: &str) -> bool { - let Some(last) = tokenize(text).last() else { + let Some(last) = tokenize(text, FrontmatterAllowed::No).last() else { return false; }; match last.kind { @@ -310,7 +310,8 @@ fn with_leading_whitespace_inner(lines: &[RelativeBytePos], src: &str, range: Ra && ends_with_line_comment_or_broken(&start[prev_start..]) && let next_line = lines.partition_point(|&pos| pos.to_usize() < range.end) && let next_start = lines.get(next_line).map_or(src.len(), |&x| x.to_usize()) - && tokenize(src.get(range.end..next_start)?).any(|t| !matches!(t.kind, TokenKind::Whitespace)) + && tokenize(src.get(range.end..next_start)?, FrontmatterAllowed::No) + .any(|t| !matches!(t.kind, TokenKind::Whitespace)) { Some(range.start) } else { diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index aa786334711..57d623b2cfc 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -125,8 +125,17 @@ impl TestContext { let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into())); let mut config = Config { output_conflict_handling: error_on_output_conflict, + // Pre-fill filters with TESTNAME; will be later extended with `self.args`. filter_files: env::var("TESTNAME") - .map(|filters| filters.split(',').map(str::to_string).collect()) + .map(|filters| { + filters + .split(',') + // Make sure that if TESTNAME is empty we produce the empty list here, + // not a list containing an empty string. + .filter(|s| !s.is_empty()) + .map(str::to_string) + .collect() + }) .unwrap_or_default(), target: None, bless_command: Some(if IS_RUSTC_TEST_SUITE { diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr index a3c35a31c33..87e4b0c5c7d 100644 --- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr +++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr @@ -136,13 +136,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5 | LL | const A: bool; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `SomeType` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5 | LL | type SomeType; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: incorrect ordering of items (must be alphabetically ordered) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11 @@ -172,13 +172,13 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5 | LL | const A: bool = false; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `SomeType` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5 | LL | type SomeType = (); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 15 previous errors diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr index a3c35a31c33..87e4b0c5c7d 100644 --- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr +++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr @@ -136,13 +136,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5 | LL | const A: bool; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `SomeType` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5 | LL | type SomeType; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: incorrect ordering of items (must be alphabetically ordered) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11 @@ -172,13 +172,13 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5 | LL | const A: bool = false; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `SomeType` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5 | LL | type SomeType = (); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 15 previous errors diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr index 3fdd706fc62..40505e2a1c4 100644 --- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr +++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr @@ -211,13 +211,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5 | LL | const A: bool; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `SomeType` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5 | LL | type SomeType; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: incorrect ordering of items (must be alphabetically ordered) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11 @@ -247,13 +247,13 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5 | LL | const A: bool = false; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `SomeType` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5 | LL | type SomeType = (); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: incorrect ordering of items (must be alphabetically ordered) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:207:11 diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr index 730f12c38a0..d8db2243d41 100644 --- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr +++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr @@ -28,25 +28,25 @@ error: incorrect ordering of impl items (defined order: [Fn, Type, Const]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5 | LL | type SomeType = (); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `A` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:117:5 | LL | const A: bool = false; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: incorrect ordering of impl items (defined order: [Fn, Type, Const]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:122:5 | LL | fn a() {} - | ^^^^^^^^^ + | ^^^^^^ | note: should be placed before `SomeType` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5 | LL | type SomeType = (); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: incorrect ordering of items (must be alphabetically ordered) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:149:8 @@ -76,13 +76,13 @@ error: incorrect ordering of trait items (defined order: [Fn, Type, Const]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:163:5 | LL | type SomeType; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `A` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:161:5 | LL | const A: bool; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: incorrect ordering of trait items (defined order: [Fn, Type, Const]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:166:5 @@ -94,7 +94,7 @@ note: should be placed before `SomeType` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:163:5 | LL | type SomeType; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr index 77596ba2394..7f6bddf8005 100644 --- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr +++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr @@ -16,25 +16,25 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:46:5 | LL | type SomeType = i8; - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `a` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:43:5 | LL | fn a() {} - | ^^^^^^^^^ + | ^^^^^^ error: incorrect ordering of impl items (defined order: [Const, Type, Fn]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:49:5 | LL | const A: bool = true; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `SomeType` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:46:5 | LL | type SomeType = i8; - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr index 3d903330be8..a7cff238b78 100644 --- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr +++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr @@ -28,13 +28,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn]) --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:45:5 | LL | const A: bool; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | note: should be placed before `SomeType` --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:43:5 | LL | type SomeType; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/author/if.stdout b/src/tools/clippy/tests/ui/author/if.stdout index da359866bff..dbff55634ea 100644 --- a/src/tools/clippy/tests/ui/author/if.stdout +++ b/src/tools/clippy/tests/ui/author/if.stdout @@ -1,8 +1,7 @@ if let StmtKind::Let(local) = stmt.kind && let Some(init) = local.init && let ExprKind::If(cond, then, Some(else_expr)) = init.kind - && let ExprKind::DropTemps(expr) = cond.kind - && let ExprKind::Lit(ref lit) = expr.kind + && let ExprKind::Lit(ref lit) = cond.kind && let LitKind::Bool(true) = lit.node && let ExprKind::Block(block, None) = then.kind && block.stmts.len() == 1 diff --git a/src/tools/clippy/tests/ui/author/struct.stdout b/src/tools/clippy/tests/ui/author/struct.stdout index 1e8fbafd30c..2dedab56dce 100644 --- a/src/tools/clippy/tests/ui/author/struct.stdout +++ b/src/tools/clippy/tests/ui/author/struct.stdout @@ -2,8 +2,7 @@ if let ExprKind::Struct(qpath, fields, None) = expr.kind && fields.len() == 1 && fields[0].ident.as_str() == "field" && let ExprKind::If(cond, then, Some(else_expr)) = fields[0].expr.kind - && let ExprKind::DropTemps(expr1) = cond.kind - && let ExprKind::Lit(ref lit) = expr1.kind + && let ExprKind::Lit(ref lit) = cond.kind && let LitKind::Bool(true) = lit.node && let ExprKind::Block(block, None) = then.kind && block.stmts.is_empty() diff --git a/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr b/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr index dc01a375060..0f700654f7c 100644 --- a/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr +++ b/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr @@ -1,12 +1,8 @@ error: re-implementing `PartialEq::ne` is unnecessary --> tests/ui/partialeq_ne_impl.rs:9:5 | -LL | / fn ne(&self, _: &Foo) -> bool { -LL | | -LL | | -LL | | false -LL | | } - | |_____^ +LL | fn ne(&self, _: &Foo) -> bool { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::partialeq-ne-impl` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::partialeq_ne_impl)]` diff --git a/src/tools/clippy/tests/ui/same_name_method.stderr b/src/tools/clippy/tests/ui/same_name_method.stderr index b2624ac4d26..bf7456d80e2 100644 --- a/src/tools/clippy/tests/ui/same_name_method.stderr +++ b/src/tools/clippy/tests/ui/same_name_method.stderr @@ -2,13 +2,13 @@ error: method's name is the same as an existing method in a trait --> tests/ui/same_name_method.rs:20:13 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ | note: existing `foo` defined here --> tests/ui/same_name_method.rs:25:13 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ = note: `-D clippy::same-name-method` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::same_name_method)]` @@ -16,7 +16,7 @@ error: method's name is the same as an existing method in a trait --> tests/ui/same_name_method.rs:35:13 | LL | fn clone() {} - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^ | note: existing `clone` defined here --> tests/ui/same_name_method.rs:31:18 @@ -28,19 +28,19 @@ error: method's name is the same as an existing method in a trait --> tests/ui/same_name_method.rs:46:13 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ | note: existing `foo` defined here --> tests/ui/same_name_method.rs:51:13 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ error: method's name is the same as an existing method in a trait --> tests/ui/same_name_method.rs:61:13 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ | note: existing `foo` defined here --> tests/ui/same_name_method.rs:65:9 @@ -52,7 +52,7 @@ error: method's name is the same as an existing method in a trait --> tests/ui/same_name_method.rs:74:13 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ | note: existing `foo` defined here --> tests/ui/same_name_method.rs:79:9 @@ -64,7 +64,7 @@ error: method's name is the same as an existing method in a trait --> tests/ui/same_name_method.rs:74:13 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ | note: existing `foo` defined here --> tests/ui/same_name_method.rs:81:9 diff --git a/src/tools/clippy/tests/ui/serde.stderr b/src/tools/clippy/tests/ui/serde.stderr index eb6b7c6b0c3..652248e3578 100644 --- a/src/tools/clippy/tests/ui/serde.stderr +++ b/src/tools/clippy/tests/ui/serde.stderr @@ -5,10 +5,7 @@ LL | / fn visit_string<E>(self, _v: String) -> Result<Self::Value, E> LL | | LL | | where LL | | E: serde::de::Error, -LL | | { -LL | | unimplemented!() -LL | | } - | |_____^ + | |____________________________^ | = note: `-D clippy::serde-api-misuse` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::serde_api_misuse)]` diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 7122746fa87..849f44031b7 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -1,63 +1,20 @@ use std::collections::{BTreeSet, HashMap, HashSet}; +use std::iter; use std::process::Command; -use std::str::FromStr; use std::sync::OnceLock; -use std::{fmt, iter}; use build_helper::git::GitConfig; use camino::{Utf8Path, Utf8PathBuf}; use semver::Version; use serde::de::{Deserialize, Deserializer, Error as _}; -pub use self::Mode::*; use crate::executor::{ColorConfig, OutputFormat}; use crate::fatal; -use crate::util::{Utf8PathBufExt, add_dylib_path}; - -macro_rules! string_enum { - ($(#[$meta:meta])* $vis:vis enum $name:ident { $($variant:ident => $repr:expr,)* }) => { - $(#[$meta])* - $vis enum $name { - $($variant,)* - } - - impl $name { - $vis const VARIANTS: &'static [Self] = &[$(Self::$variant,)*]; - $vis const STR_VARIANTS: &'static [&'static str] = &[$(Self::$variant.to_str(),)*]; - - $vis const fn to_str(&self) -> &'static str { - match self { - $(Self::$variant => $repr,)* - } - } - } - - impl fmt::Display for $name { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.to_str(), f) - } - } - - impl FromStr for $name { - type Err = String; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s { - $($repr => Ok(Self::$variant),)* - _ => Err(format!(concat!("unknown `", stringify!($name), "` variant: `{}`"), s)), - } - } - } - } -} - -// Make the macro visible outside of this module, for tests. -#[cfg(test)] -pub(crate) use string_enum; +use crate::util::{Utf8PathBufExt, add_dylib_path, string_enum}; string_enum! { #[derive(Clone, Copy, PartialEq, Debug)] - pub enum Mode { + pub enum TestMode { Pretty => "pretty", DebugInfo => "debuginfo", Codegen => "codegen", @@ -76,18 +33,12 @@ string_enum! { } } -impl Default for Mode { - fn default() -> Self { - Mode::Ui - } -} - -impl Mode { +impl TestMode { pub fn aux_dir_disambiguator(self) -> &'static str { // Pretty-printing tests could run concurrently, and if they do, // they need to keep their output segregated. match self { - Pretty => ".pretty", + TestMode::Pretty => ".pretty", _ => "", } } @@ -96,7 +47,7 @@ impl Mode { // Coverage tests use the same test files for multiple test modes, // so each mode should have a separate output directory. match self { - CoverageMap | CoverageRun => self.to_str(), + TestMode::CoverageMap | TestMode::CoverageRun => self.to_str(), _ => "", } } @@ -193,9 +144,9 @@ pub enum Sanitizer { /// /// FIXME: audit these options to make sure we are not hashing less than necessary for build stamp /// (for changed test detection). -#[derive(Debug, Default, Clone)] +#[derive(Debug, Clone)] pub struct Config { - /// Some test [`Mode`]s support [snapshot testing], where a *reference snapshot* of outputs (of + /// Some [`TestMode`]s support [snapshot testing], where a *reference snapshot* of outputs (of /// `stdout`, `stderr`, or other form of artifacts) can be compared to the *actual output*. /// /// This option can be set to `true` to update the *reference snapshots* in-place, otherwise @@ -317,20 +268,20 @@ pub struct Config { /// FIXME: reconsider this string; this is hashed for test build stamp. pub stage_id: String, - /// The test [`Mode`]. E.g. [`Mode::Ui`]. Each test mode can correspond to one or more test + /// The [`TestMode`]. E.g. [`TestMode::Ui`]. Each test mode can correspond to one or more test /// suites. /// /// FIXME: stop using stringly-typed test suites! - pub mode: Mode, + pub mode: TestMode, /// The test suite. /// - /// Example: `tests/ui/` is the "UI" test *suite*, which happens to also be of the [`Mode::Ui`] - /// test *mode*. + /// Example: `tests/ui/` is the "UI" test *suite*, which happens to also be of the + /// [`TestMode::Ui`] test *mode*. /// /// Note that the same test directory (e.g. `tests/coverage/`) may correspond to multiple test - /// modes, e.g. `tests/coverage/` can be run under both [`Mode::CoverageRun`] and - /// [`Mode::CoverageMap`]. + /// modes, e.g. `tests/coverage/` can be run under both [`TestMode::CoverageRun`] and + /// [`TestMode::CoverageMap`]. /// /// FIXME: stop using stringly-typed test suites! pub suite: String, @@ -586,8 +537,8 @@ pub struct Config { // Configuration for various run-make tests frobbing things like C compilers or querying about // various LLVM component information. // - // FIXME: this really should be better packaged together. - // FIXME: these need better docs, e.g. for *host*, or for *target*? + // FIXME: this really should be better packaged together. FIXME: these need better docs, e.g. + // for *host*, or for *target*? pub cc: String, pub cxx: String, pub cflags: String, @@ -653,6 +604,107 @@ pub struct Config { } impl Config { + /// Incomplete config intended for `src/tools/rustdoc-gui-test` **only** as + /// `src/tools/rustdoc-gui-test` wants to reuse `compiletest`'s directive -> test property + /// handling for `//@ {compile,run}-flags`, do not use for any other purpose. + /// + /// FIXME(#143827): this setup feels very hacky. It so happens that `tests/rustdoc-gui/` + /// **only** uses `//@ {compile,run}-flags` for now and not any directives that actually rely on + /// info that is assumed available in a fully populated [`Config`]. + pub fn incomplete_for_rustdoc_gui_test() -> Config { + // FIXME(#143827): spelling this out intentionally, because this is questionable. + // + // For instance, `//@ ignore-stage1` will not work at all. + Config { + mode: TestMode::Rustdoc, + + // Dummy values. + edition: Default::default(), + bless: Default::default(), + fail_fast: Default::default(), + compile_lib_path: Utf8PathBuf::default(), + run_lib_path: Utf8PathBuf::default(), + rustc_path: Utf8PathBuf::default(), + cargo_path: Default::default(), + stage0_rustc_path: Default::default(), + rustdoc_path: Default::default(), + coverage_dump_path: Default::default(), + python: Default::default(), + jsondocck_path: Default::default(), + jsondoclint_path: Default::default(), + llvm_filecheck: Default::default(), + llvm_bin_dir: Default::default(), + run_clang_based_tests_with: Default::default(), + src_root: Utf8PathBuf::default(), + src_test_suite_root: Utf8PathBuf::default(), + build_root: Utf8PathBuf::default(), + build_test_suite_root: Utf8PathBuf::default(), + sysroot_base: Utf8PathBuf::default(), + stage: Default::default(), + stage_id: String::default(), + suite: Default::default(), + debugger: Default::default(), + run_ignored: Default::default(), + with_rustc_debug_assertions: Default::default(), + with_std_debug_assertions: Default::default(), + filters: Default::default(), + skip: Default::default(), + filter_exact: Default::default(), + force_pass_mode: Default::default(), + run: Default::default(), + runner: Default::default(), + host_rustcflags: Default::default(), + target_rustcflags: Default::default(), + rust_randomized_layout: Default::default(), + optimize_tests: Default::default(), + target: Default::default(), + host: Default::default(), + cdb: Default::default(), + cdb_version: Default::default(), + gdb: Default::default(), + gdb_version: Default::default(), + lldb_version: Default::default(), + llvm_version: Default::default(), + system_llvm: Default::default(), + android_cross_path: Default::default(), + adb_path: Default::default(), + adb_test_dir: Default::default(), + adb_device_status: Default::default(), + lldb_python_dir: Default::default(), + verbose: Default::default(), + format: Default::default(), + color: Default::default(), + remote_test_client: Default::default(), + compare_mode: Default::default(), + rustfix_coverage: Default::default(), + has_html_tidy: Default::default(), + has_enzyme: Default::default(), + channel: Default::default(), + git_hash: Default::default(), + cc: Default::default(), + cxx: Default::default(), + cflags: Default::default(), + cxxflags: Default::default(), + ar: Default::default(), + target_linker: Default::default(), + host_linker: Default::default(), + llvm_components: Default::default(), + nodejs: Default::default(), + npm: Default::default(), + force_rerun: Default::default(), + only_modified: Default::default(), + target_cfgs: Default::default(), + builtin_cfg_names: Default::default(), + supported_crate_types: Default::default(), + nocapture: Default::default(), + nightly_branch: Default::default(), + git_merge_commit_email: Default::default(), + profiler_runtime: Default::default(), + diff_command: Default::default(), + minicore_path: Default::default(), + } + } + /// FIXME: this run scheme is... confusing. pub fn run_enabled(&self) -> bool { self.run.unwrap_or_else(|| { diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs index 0edc3d82d4f..8afe3289fa4 100644 --- a/src/tools/compiletest/src/debuggers.rs +++ b/src/tools/compiletest/src/debuggers.rs @@ -51,17 +51,6 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> { pub(crate) fn configure_lldb(config: &Config) -> Option<Arc<Config>> { config.lldb_python_dir.as_ref()?; - // FIXME: this is super old - if let Some(350) = config.lldb_version { - println!( - "WARNING: The used version of LLDB (350) has a \ - known issue that breaks debuginfo tests. See \ - issue #32520 for more information. Skipping all \ - LLDB-based tests!", - ); - return None; - } - Some(Arc::new(Config { debugger: Some(Debugger::Lldb), ..config.clone() })) } diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index a6242cf0c22..7fadb4dae2a 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -9,7 +9,7 @@ use camino::{Utf8Path, Utf8PathBuf}; use semver::Version; use tracing::*; -use crate::common::{Config, Debugger, FailMode, Mode, PassMode}; +use crate::common::{Config, Debugger, FailMode, PassMode, TestMode}; use crate::debuggers::{extract_cdb_version, extract_gdb_version}; use crate::directives::auxiliary::{AuxProps, parse_and_update_aux}; use crate::directives::needs::CachedNeedsConditions; @@ -328,7 +328,7 @@ impl TestProps { props.exec_env.push(("RUSTC".to_string(), config.rustc_path.to_string())); match (props.pass_mode, props.fail_mode) { - (None, None) if config.mode == Mode::Ui => props.fail_mode = Some(FailMode::Check), + (None, None) if config.mode == TestMode::Ui => props.fail_mode = Some(FailMode::Check), (Some(_), Some(_)) => panic!("cannot use a *-fail and *-pass mode together"), _ => {} } @@ -609,11 +609,11 @@ impl TestProps { self.failure_status = Some(101); } - if config.mode == Mode::Incremental { + if config.mode == TestMode::Incremental { self.incremental = true; } - if config.mode == Mode::Crashes { + if config.mode == TestMode::Crashes { // we don't want to pollute anything with backtrace-files // also turn off backtraces in order to save some execution // time on the tests; we only need to know IF it crashes @@ -641,11 +641,11 @@ impl TestProps { fn update_fail_mode(&mut self, ln: &str, config: &Config) { let check_ui = |mode: &str| { // Mode::Crashes may need build-fail in order to trigger llvm errors or stack overflows - if config.mode != Mode::Ui && config.mode != Mode::Crashes { + if config.mode != TestMode::Ui && config.mode != TestMode::Crashes { panic!("`{}-fail` directive is only supported in UI tests", mode); } }; - if config.mode == Mode::Ui && config.parse_name_directive(ln, "compile-fail") { + if config.mode == TestMode::Ui && config.parse_name_directive(ln, "compile-fail") { panic!("`compile-fail` directive is useless in UI tests"); } let fail_mode = if config.parse_name_directive(ln, "check-fail") { @@ -669,10 +669,10 @@ impl TestProps { fn update_pass_mode(&mut self, ln: &str, revision: Option<&str>, config: &Config) { let check_no_run = |s| match (config.mode, s) { - (Mode::Ui, _) => (), - (Mode::Crashes, _) => (), - (Mode::Codegen, "build-pass") => (), - (Mode::Incremental, _) => { + (TestMode::Ui, _) => (), + (TestMode::Crashes, _) => (), + (TestMode::Codegen, "build-pass") => (), + (TestMode::Incremental, _) => { if revision.is_some() && !self.revisions.iter().all(|r| r.starts_with("cfail")) { panic!("`{s}` directive is only supported in `cfail` incremental tests") } @@ -715,7 +715,7 @@ impl TestProps { pub fn update_add_core_stubs(&mut self, ln: &str, config: &Config) { let add_core_stubs = config.parse_name_directive(ln, directives::ADD_CORE_STUBS); if add_core_stubs { - if !matches!(config.mode, Mode::Ui | Mode::Codegen | Mode::Assembly) { + if !matches!(config.mode, TestMode::Ui | TestMode::Codegen | TestMode::Assembly) { panic!( "`add-core-stubs` is currently only supported for ui, codegen and assembly test modes" ); @@ -833,7 +833,7 @@ pub(crate) struct CheckDirectiveResult<'ln> { pub(crate) fn check_directive<'a>( directive_ln: &'a str, - mode: Mode, + mode: TestMode, original_line: &str, ) -> CheckDirectiveResult<'a> { let (directive_name, post) = directive_ln.split_once([':', ' ']).unwrap_or((directive_ln, "")); @@ -842,11 +842,11 @@ pub(crate) fn check_directive<'a>( let is_known = |s: &str| { KNOWN_DIRECTIVE_NAMES.contains(&s) || match mode { - Mode::Rustdoc | Mode::RustdocJson => { + TestMode::Rustdoc | TestMode::RustdocJson => { original_line.starts_with("//@") && match mode { - Mode::Rustdoc => KNOWN_HTMLDOCCK_DIRECTIVE_NAMES, - Mode::RustdocJson => KNOWN_JSONDOCCK_DIRECTIVE_NAMES, + TestMode::Rustdoc => KNOWN_HTMLDOCCK_DIRECTIVE_NAMES, + TestMode::RustdocJson => KNOWN_JSONDOCCK_DIRECTIVE_NAMES, _ => unreachable!(), } .contains(&s) @@ -868,7 +868,7 @@ pub(crate) fn check_directive<'a>( const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@"; fn iter_directives( - mode: Mode, + mode: TestMode, _suite: &str, poisoned: &mut bool, testfile: &Utf8Path, @@ -883,7 +883,7 @@ fn iter_directives( // specify them manually in every test file. // // FIXME(jieyouxu): I feel like there's a better way to do this, leaving for later. - if mode == Mode::CoverageRun { + if mode == TestMode::CoverageRun { let extra_directives: &[&str] = &[ "needs-profiler-runtime", // FIXME(pietroalbini): this test currently does not work on cross-compiled targets @@ -964,7 +964,7 @@ impl Config { ["CHECK", "COM", "NEXT", "SAME", "EMPTY", "NOT", "COUNT", "DAG", "LABEL"]; if let Some(raw) = self.parse_name_value_directive(line, "revisions") { - if self.mode == Mode::RunMake { + if self.mode == TestMode::RunMake { panic!("`run-make` tests do not support revisions: {}", testfile); } @@ -981,7 +981,7 @@ impl Config { ); } - if matches!(self.mode, Mode::Assembly | Mode::Codegen | Mode::MirOpt) + if matches!(self.mode, TestMode::Assembly | TestMode::Codegen | TestMode::MirOpt) && FILECHECK_FORBIDDEN_REVISION_NAMES.contains(&revision) { panic!( @@ -1443,7 +1443,7 @@ pub(crate) fn make_test_description<R: Read>( // since we run the pretty printer across all tests by default. // If desired, we could add a `should-fail-pretty` annotation. let should_panic = match config.mode { - crate::common::Pretty => ShouldPanic::No, + TestMode::Pretty => ShouldPanic::No, _ if should_fail => ShouldPanic::Yes, _ => ShouldPanic::No, }; diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index d4570f82677..9c5751b416b 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -7,7 +7,7 @@ use super::{ DirectivesCache, EarlyProps, extract_llvm_version, extract_version_range, iter_directives, parse_normalize_rule, }; -use crate::common::{Config, Debugger, Mode}; +use crate::common::{Config, Debugger, TestMode}; use crate::executor::{CollectedTestDesc, ShouldPanic}; fn make_test_description<R: Read>( @@ -785,7 +785,7 @@ fn threads_support() { fn run_path(poisoned: &mut bool, path: &Utf8Path, buf: &[u8]) { let rdr = std::io::Cursor::new(&buf); - iter_directives(Mode::Ui, "ui", poisoned, path, rdr, &mut |_| {}); + iter_directives(TestMode::Ui, "ui", poisoned, path, rdr, &mut |_| {}); } #[test] diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 9819079e284..be82f8cb480 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -39,8 +39,8 @@ use walkdir::WalkDir; use self::directives::{EarlyProps, make_test_description}; use crate::common::{ - CompareMode, Config, Debugger, Mode, PassMode, TestPaths, UI_EXTENSIONS, expected_output_path, - output_base_dir, output_relative_path, + CompareMode, Config, Debugger, PassMode, TestMode, TestPaths, UI_EXTENSIONS, + expected_output_path, output_base_dir, output_relative_path, }; use crate::directives::DirectivesCache; use crate::executor::{CollectedTest, ColorConfig, OutputFormat}; @@ -268,7 +268,7 @@ pub fn parse_config(args: Vec<String>) -> Config { let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions"); let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions"); let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode"); - let has_html_tidy = if mode == Mode::Rustdoc { + let has_html_tidy = if mode == TestMode::Rustdoc { Command::new("tidy") .arg("--version") .stdout(Stdio::null()) @@ -279,7 +279,7 @@ pub fn parse_config(args: Vec<String>) -> Config { false }; let has_enzyme = matches.opt_present("has-enzyme"); - let filters = if mode == Mode::RunMake { + let filters = if mode == TestMode::RunMake { matches .free .iter() @@ -545,7 +545,7 @@ pub fn run_tests(config: Arc<Config>) { unsafe { env::set_var("TARGET", &config.target) }; let mut configs = Vec::new(); - if let Mode::DebugInfo = config.mode { + if let TestMode::DebugInfo = config.mode { // Debugging emscripten code doesn't make sense today if !config.target.contains("emscripten") { match config.debugger { @@ -783,7 +783,7 @@ fn collect_tests_from_dir( } // For run-make tests, a "test file" is actually a directory that contains an `rmake.rs`. - if cx.config.mode == Mode::RunMake { + if cx.config.mode == TestMode::RunMake { let mut collector = TestCollector::new(); if dir.join("rmake.rs").exists() { let paths = TestPaths { @@ -869,7 +869,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te // For run-make tests, each "test file" is actually a _directory_ containing an `rmake.rs`. But // for the purposes of directive parsing, we want to look at that recipe file, not the directory // itself. - let test_path = if cx.config.mode == Mode::RunMake { + let test_path = if cx.config.mode == TestMode::RunMake { testpaths.file.join("rmake.rs") } else { testpaths.file.clone() @@ -884,7 +884,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te // - Incremental tests inherently can't run their revisions in parallel, so // we treat them like non-revisioned tests here. Incremental revisions are // handled internally by `runtest::run` instead. - let revisions = if early_props.revisions.is_empty() || cx.config.mode == Mode::Incremental { + let revisions = if early_props.revisions.is_empty() || cx.config.mode == TestMode::Incremental { vec![None] } else { early_props.revisions.iter().map(|r| Some(r.as_str())).collect() @@ -1116,11 +1116,11 @@ fn check_for_overlapping_test_paths(found_path_stems: &HashSet<Utf8PathBuf>) { } pub fn early_config_check(config: &Config) { - if !config.has_html_tidy && config.mode == Mode::Rustdoc { + if !config.has_html_tidy && config.mode == TestMode::Rustdoc { warning!("`tidy` (html-tidy.org) is not installed; diffs will not be generated"); } - if !config.profiler_runtime && config.mode == Mode::CoverageRun { + if !config.profiler_runtime && config.mode == TestMode::CoverageRun { let actioned = if config.bless { "blessed" } else { "checked" }; warning!("profiler runtime is not available, so `.coverage` files won't be {actioned}"); help!("try setting `profiler = true` in the `[build]` section of `bootstrap.toml`"); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 933a32392bd..12111e9c6ef 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -16,11 +16,10 @@ use regex::{Captures, Regex}; use tracing::*; use crate::common::{ - Assembly, Codegen, CodegenUnits, CompareMode, Config, CoverageMap, CoverageRun, Crashes, - DebugInfo, Debugger, FailMode, Incremental, MirOpt, PassMode, Pretty, RunMake, Rustdoc, - RustdocJs, RustdocJson, TestPaths, UI_EXTENSIONS, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT, - UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, Ui, expected_output_path, incremental_dir, - output_base_dir, output_base_name, output_testname_unique, + CompareMode, Config, Debugger, FailMode, PassMode, TestMode, TestPaths, UI_EXTENSIONS, + UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT, UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, + expected_output_path, incremental_dir, output_base_dir, output_base_name, + output_testname_unique, }; use crate::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff}; use crate::directives::TestProps; @@ -154,7 +153,7 @@ pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) { cx.init_incremental_test(); } - if config.mode == Incremental { + if config.mode == TestMode::Incremental { // Incremental tests are special because they cannot be run in // parallel. assert!(!props.revisions.is_empty(), "Incremental tests require revisions."); @@ -203,7 +202,7 @@ pub fn compute_stamp_hash(config: &Config) -> String { None => {} } - if let Ui = config.mode { + if config.mode == TestMode::Ui { config.force_pass_mode.hash(&mut hash); } @@ -251,25 +250,28 @@ impl<'test> TestCx<'test> { /// Code executed for each revision in turn (or, if there are no /// revisions, exactly once, with revision == None). fn run_revision(&self) { - if self.props.should_ice && self.config.mode != Incremental && self.config.mode != Crashes { + if self.props.should_ice + && self.config.mode != TestMode::Incremental + && self.config.mode != TestMode::Crashes + { self.fatal("cannot use should-ice in a test that is not cfail"); } match self.config.mode { - Pretty => self.run_pretty_test(), - DebugInfo => self.run_debuginfo_test(), - Codegen => self.run_codegen_test(), - Rustdoc => self.run_rustdoc_test(), - RustdocJson => self.run_rustdoc_json_test(), - CodegenUnits => self.run_codegen_units_test(), - Incremental => self.run_incremental_test(), - RunMake => self.run_rmake_test(), - Ui => self.run_ui_test(), - MirOpt => self.run_mir_opt_test(), - Assembly => self.run_assembly_test(), - RustdocJs => self.run_rustdoc_js_test(), - CoverageMap => self.run_coverage_map_test(), // see self::coverage - CoverageRun => self.run_coverage_run_test(), // see self::coverage - Crashes => self.run_crash_test(), + TestMode::Pretty => self.run_pretty_test(), + TestMode::DebugInfo => self.run_debuginfo_test(), + TestMode::Codegen => self.run_codegen_test(), + TestMode::Rustdoc => self.run_rustdoc_test(), + TestMode::RustdocJson => self.run_rustdoc_json_test(), + TestMode::CodegenUnits => self.run_codegen_units_test(), + TestMode::Incremental => self.run_incremental_test(), + TestMode::RunMake => self.run_rmake_test(), + TestMode::Ui => self.run_ui_test(), + TestMode::MirOpt => self.run_mir_opt_test(), + TestMode::Assembly => self.run_assembly_test(), + TestMode::RustdocJs => self.run_rustdoc_js_test(), + TestMode::CoverageMap => self.run_coverage_map_test(), // see self::coverage + TestMode::CoverageRun => self.run_coverage_run_test(), // see self::coverage + TestMode::Crashes => self.run_crash_test(), } } @@ -279,9 +281,13 @@ impl<'test> TestCx<'test> { fn should_run(&self, pm: Option<PassMode>) -> WillExecute { let test_should_run = match self.config.mode { - Ui if pm == Some(PassMode::Run) || self.props.fail_mode == Some(FailMode::Run) => true, - MirOpt if pm == Some(PassMode::Run) => true, - Ui | MirOpt => false, + TestMode::Ui + if pm == Some(PassMode::Run) || self.props.fail_mode == Some(FailMode::Run) => + { + true + } + TestMode::MirOpt if pm == Some(PassMode::Run) => true, + TestMode::Ui | TestMode::MirOpt => false, mode => panic!("unimplemented for mode {:?}", mode), }; if test_should_run { self.run_if_enabled() } else { WillExecute::No } @@ -293,17 +299,17 @@ impl<'test> TestCx<'test> { fn should_run_successfully(&self, pm: Option<PassMode>) -> bool { match self.config.mode { - Ui | MirOpt => pm == Some(PassMode::Run), + TestMode::Ui | TestMode::MirOpt => pm == Some(PassMode::Run), mode => panic!("unimplemented for mode {:?}", mode), } } fn should_compile_successfully(&self, pm: Option<PassMode>) -> bool { match self.config.mode { - RustdocJs => true, - Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build), - Crashes => false, - Incremental => { + TestMode::RustdocJs => true, + TestMode::Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build), + TestMode::Crashes => false, + TestMode::Incremental => { let revision = self.revision.expect("incremental tests require a list of revisions"); if revision.starts_with("cpass") @@ -349,7 +355,7 @@ impl<'test> TestCx<'test> { if proc_res.status.success() { { self.error(&format!("{} test did not emit an error", self.config.mode)); - if self.config.mode == crate::common::Mode::Ui { + if self.config.mode == crate::common::TestMode::Ui { println!("note: by default, ui tests are expected not to compile"); } proc_res.fatal(None, || ()); @@ -892,7 +898,9 @@ impl<'test> TestCx<'test> { fn should_emit_metadata(&self, pm: Option<PassMode>) -> Emit { match (pm, self.props.fail_mode, self.config.mode) { - (Some(PassMode::Check), ..) | (_, Some(FailMode::Check), Ui) => Emit::Metadata, + (Some(PassMode::Check), ..) | (_, Some(FailMode::Check), TestMode::Ui) => { + Emit::Metadata + } _ => Emit::None, } } @@ -926,7 +934,7 @@ impl<'test> TestCx<'test> { }; let allow_unused = match self.config.mode { - Ui => { + TestMode::Ui => { // UI tests tend to have tons of unused code as // it's just testing various pieces of the compile, but we don't // want to actually assert warnings about all this code. Instead @@ -1021,7 +1029,7 @@ impl<'test> TestCx<'test> { .args(&self.props.compile_flags) .args(&self.props.doc_flags); - if self.config.mode == RustdocJson { + if self.config.mode == TestMode::RustdocJson { rustdoc.arg("--output-format").arg("json").arg("-Zunstable-options"); } @@ -1372,7 +1380,7 @@ impl<'test> TestCx<'test> { || self.is_vxworks_pure_static() || self.config.target.contains("bpf") || !self.config.target_cfg().dynamic_linking - || matches!(self.config.mode, CoverageMap | CoverageRun) + || matches!(self.config.mode, TestMode::CoverageMap | TestMode::CoverageRun) { // We primarily compile all auxiliary libraries as dynamic libraries // to avoid code size bloat and large binaries as much as possible @@ -1562,14 +1570,14 @@ impl<'test> TestCx<'test> { rustc.args(&["-Z", "incremental-verify-ich"]); } - if self.config.mode == CodegenUnits { + if self.config.mode == TestMode::CodegenUnits { rustc.args(&["-Z", "human_readable_cgu_names"]); } } if self.config.optimize_tests && !is_rustdoc { match self.config.mode { - Ui => { + TestMode::Ui => { // If optimize-tests is true we still only want to optimize tests that actually get // executed and that don't specify their own optimization levels. // Note: aux libs don't have a pass-mode, so they won't get optimized @@ -1585,8 +1593,8 @@ impl<'test> TestCx<'test> { rustc.arg("-O"); } } - DebugInfo => { /* debuginfo tests must be unoptimized */ } - CoverageMap | CoverageRun => { + TestMode::DebugInfo => { /* debuginfo tests must be unoptimized */ } + TestMode::CoverageMap | TestMode::CoverageRun => { // Coverage mappings and coverage reports are affected by // optimization level, so they ignore the optimize-tests // setting and set an optimization level in their mode's @@ -1607,7 +1615,7 @@ impl<'test> TestCx<'test> { }; match self.config.mode { - Incremental => { + TestMode::Incremental => { // If we are extracting and matching errors in the new // fashion, then you want JSON mode. Old-skool error // patterns still match the raw compiler output. @@ -1620,7 +1628,7 @@ impl<'test> TestCx<'test> { rustc.arg("-Zui-testing"); rustc.arg("-Zdeduplicate-diagnostics=no"); } - Ui => { + TestMode::Ui => { if !self.props.compile_flags.iter().any(|s| s.starts_with("--error-format")) { rustc.args(&["--error-format", "json"]); rustc.args(&["--json", "future-incompat"]); @@ -1633,7 +1641,7 @@ impl<'test> TestCx<'test> { // FIXME: use this for other modes too, for perf? rustc.arg("-Cstrip=debuginfo"); } - MirOpt => { + TestMode::MirOpt => { // We check passes under test to minimize the mir-opt test dump // if files_for_miropt_test parses the passes, we dump only those passes // otherwise we conservatively pass -Zdump-mir=all @@ -1663,7 +1671,7 @@ impl<'test> TestCx<'test> { set_mir_dump_dir(&mut rustc); } - CoverageMap => { + TestMode::CoverageMap => { rustc.arg("-Cinstrument-coverage"); // These tests only compile to LLVM IR, so they don't need the // profiler runtime to be present. @@ -1673,23 +1681,28 @@ impl<'test> TestCx<'test> { // by `compile-flags`. rustc.arg("-Copt-level=2"); } - CoverageRun => { + TestMode::CoverageRun => { rustc.arg("-Cinstrument-coverage"); // Coverage reports are sometimes sensitive to optimizations, // and the current snapshots assume `opt-level=2` unless // overridden by `compile-flags`. rustc.arg("-Copt-level=2"); } - Assembly | Codegen => { + TestMode::Assembly | TestMode::Codegen => { rustc.arg("-Cdebug-assertions=no"); } - Crashes => { + TestMode::Crashes => { set_mir_dump_dir(&mut rustc); } - CodegenUnits => { + TestMode::CodegenUnits => { rustc.arg("-Zprint-mono-items"); } - Pretty | DebugInfo | Rustdoc | RustdocJson | RunMake | RustdocJs => { + TestMode::Pretty + | TestMode::DebugInfo + | TestMode::Rustdoc + | TestMode::RustdocJson + | TestMode::RunMake + | TestMode::RustdocJs => { // do not use JSON output } } @@ -1962,7 +1975,7 @@ impl<'test> TestCx<'test> { /// The revision, ignored for incremental compilation since it wants all revisions in /// the same directory. fn safe_revision(&self) -> Option<&str> { - if self.config.mode == Incremental { None } else { self.revision } + if self.config.mode == TestMode::Incremental { None } else { self.revision } } /// Gets the absolute path to the directory where all output for the given diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 60e8e16e25e..c8d5190c039 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -225,6 +225,19 @@ impl TestCx<'_> { cmd.env("RUNNER", runner); } + // Guard against externally-set env vars. + cmd.env_remove("__RUSTC_DEBUG_ASSERTIONS_ENABLED"); + if self.config.with_rustc_debug_assertions { + // Used for `run_make_support::env::rustc_debug_assertions_enabled`. + cmd.env("__RUSTC_DEBUG_ASSERTIONS_ENABLED", "1"); + } + + cmd.env_remove("__STD_DEBUG_ASSERTIONS_ENABLED"); + if self.config.with_std_debug_assertions { + // Used for `run_make_support::env::std_debug_assertions_enabled`. + cmd.env("__STD_DEBUG_ASSERTIONS_ENABLED", "1"); + } + // We don't want RUSTFLAGS set from the outside to interfere with // compiler flags set in the test cases: cmd.env_remove("RUSTFLAGS"); diff --git a/src/tools/compiletest/src/tests.rs b/src/tools/compiletest/src/tests.rs index e3e4a81755d..174ec9381f6 100644 --- a/src/tools/compiletest/src/tests.rs +++ b/src/tools/compiletest/src/tests.rs @@ -67,11 +67,7 @@ fn is_test_test() { #[test] fn string_enums() { - // These imports are needed for the macro-generated code - use std::fmt; - use std::str::FromStr; - - crate::common::string_enum! { + crate::util::string_enum! { #[derive(Clone, Copy, Debug, PartialEq)] enum Animal { Cat => "meow", diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 202582bea8c..fb047548c45 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -104,3 +104,42 @@ macro_rules! static_regex { }}; } pub(crate) use static_regex; + +macro_rules! string_enum { + ($(#[$meta:meta])* $vis:vis enum $name:ident { $($variant:ident => $repr:expr,)* }) => { + $(#[$meta])* + $vis enum $name { + $($variant,)* + } + + impl $name { + $vis const VARIANTS: &'static [Self] = &[$(Self::$variant,)*]; + $vis const STR_VARIANTS: &'static [&'static str] = &[$(Self::$variant.to_str(),)*]; + + $vis const fn to_str(&self) -> &'static str { + match self { + $(Self::$variant => $repr,)* + } + } + } + + impl ::std::fmt::Display for $name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::std::fmt::Display::fmt(self.to_str(), f) + } + } + + impl ::std::str::FromStr for $name { + type Err = String; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + $($repr => Ok(Self::$variant),)* + _ => Err(format!(concat!("unknown `", stringify!($name), "` variant: `{}`"), s)), + } + } + } + } +} + +pub(crate) use string_enum; diff --git a/src/tools/lint-docs/src/groups.rs b/src/tools/lint-docs/src/groups.rs index 78d4f87ed0d..a24fbbc0cea 100644 --- a/src/tools/lint-docs/src/groups.rs +++ b/src/tools/lint-docs/src/groups.rs @@ -26,6 +26,10 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[ "Lints that detect identifiers which will be come keywords in later editions", ), ("deprecated-safe", "Lints for functions which were erroneously marked as safe in the past"), + ( + "unknown-or-malformed-diagnostic-attributes", + "detects unknown or malformed diagnostic attributes", + ), ]; type LintGroups = BTreeMap<String, BTreeSet<String>>; diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 0af6b8c6fc7..adf3f7389c6 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -32cd9114712a24010b0583624dc52ac302194128 +9c3064e131f4939cc95a29bb11413c49bbda1491 diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index d7432a7300e..a2a23c4813f 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs @@ -255,7 +255,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { .collect::<Vec<libffi::high::Arg<'_>>>(); // Prepare all exposed memory (both previously exposed, and just newly exposed since a - // pointer was passed as argument). + // pointer was passed as argument). Uninitialised memory is left as-is, but any data + // exposed this way is garbage anyway. this.visit_reachable_allocs(this.exposed_allocs(), |this, alloc_id, info| { // If there is no data behind this pointer, skip this. if !matches!(info.kind, AllocKind::LiveData) { @@ -275,8 +276,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Prepare for possible write from native code if mutable. if info.mutbl.is_mut() { - let alloc = &mut this.get_alloc_raw_mut(alloc_id)?.0; - alloc.prepare_for_native_access(); + let (alloc, cx) = this.get_alloc_raw_mut(alloc_id)?; + alloc.process_native_write(&cx.tcx, None); // Also expose *mutable* provenance for the interpreter-level allocation. std::hint::black_box(alloc.get_bytes_unchecked_raw_mut().expose_provenance()); } diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index 5239f8338ee..43f855d57dd 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -97,6 +97,8 @@ fn miri_config( let mut config = Config { target: Some(target.to_owned()), program, + // When changing this, remember to also adjust the logic in bootstrap, in Miri's test step, + // that deletes the `miri_ui` dir when it needs a rebuild. out_dir: PathBuf::from(env!("CARGO_TARGET_TMPDIR")).join("miri_ui"), threads: std::env::var("MIRI_TEST_THREADS") .ok() diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml index dfa884bc3f7..2ed3fbac709 100644 --- a/src/tools/opt-dist/Cargo.toml +++ b/src/tools/opt-dist/Cargo.toml @@ -10,7 +10,7 @@ log = "0.4" anyhow = "1" humantime = "2" humansize = "2" -sysinfo = { version = "0.35.0", default-features = false, features = ["disk"] } +sysinfo = { version = "0.36.0", default-features = false, features = ["disk"] } fs_extra = "1" camino = "1" tar = "0.4" diff --git a/src/tools/run-make-support/src/env.rs b/src/tools/run-make-support/src/env.rs index 9acbb16d73e..cf1a6f7351a 100644 --- a/src/tools/run-make-support/src/env.rs +++ b/src/tools/run-make-support/src/env.rs @@ -18,11 +18,20 @@ pub fn env_var_os(name: &str) -> OsString { } } -/// Check if `NO_DEBUG_ASSERTIONS` is set (usually this may be set in CI jobs). +/// Check if staged `rustc`-under-test was built with debug assertions. #[track_caller] #[must_use] -pub fn no_debug_assertions() -> bool { - std::env::var_os("NO_DEBUG_ASSERTIONS").is_some() +pub fn rustc_debug_assertions_enabled() -> bool { + // Note: we assume this env var is set when the test recipe is being executed. + std::env::var_os("__RUSTC_DEBUG_ASSERTIONS_ENABLED").is_some() +} + +/// Check if staged `std`-under-test was built with debug assertions. +#[track_caller] +#[must_use] +pub fn std_debug_assertions_enabled() -> bool { + // Note: we assume this env var is set when the test recipe is being executed. + std::env::var_os("__STD_DEBUG_ASSERTIONS_ENABLED").is_some() } /// A wrapper around [`std::env::set_current_dir`] which includes the directory diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs index e6c92dec681..bff9acd78fa 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -11,8 +11,8 @@ use std::ops; use rustc_literal_escaper::{ - EscapeError, Mode, unescape_byte, unescape_byte_str, unescape_c_str, unescape_char, - unescape_str, + unescape_byte, unescape_byte_str, unescape_c_str, unescape_char, unescape_str, EscapeError, + Mode, }; use crate::{ @@ -44,7 +44,9 @@ impl<'a> LexedStr<'a> { // Re-create the tokenizer from scratch every token because `GuardedStrPrefix` is one token in the lexer // but we want to split it to two in edition <2024. - while let Some(token) = rustc_lexer::tokenize(&text[conv.offset..]).next() { + while let Some(token) = + rustc_lexer::tokenize(&text[conv.offset..], rustc_lexer::FrontmatterAllowed::No).next() + { let token_text = &text[conv.offset..][..token.len as usize]; conv.extend_token(&token.kind, token_text); @@ -58,7 +60,7 @@ impl<'a> LexedStr<'a> { return None; } - let token = rustc_lexer::tokenize(text).next()?; + let token = rustc_lexer::tokenize(text, rustc_lexer::FrontmatterAllowed::No).next()?; if token.len as usize != text.len() { return None; } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs index dd576f23ae9..662f6257642 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs @@ -121,7 +121,7 @@ pub(super) fn literal_from_str<Span: Copy>( use proc_macro::bridge::LitKind; use rustc_lexer::{LiteralKind, Token, TokenKind}; - let mut tokens = rustc_lexer::tokenize(s); + let mut tokens = rustc_lexer::tokenize(s, rustc_lexer::FrontmatterAllowed::No); let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 }); let lit = if minus_or_lit.kind == TokenKind::Minus { diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 14574a6456b..44123385c8c 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -579,7 +579,7 @@ where { use rustc_lexer::LiteralKind; - let token = rustc_lexer::tokenize(text).next_tuple(); + let token = rustc_lexer::tokenize(text, rustc_lexer::FrontmatterAllowed::No).next_tuple(); let Some((rustc_lexer::Token { kind: rustc_lexer::TokenKind::Literal { kind, suffix_start }, .. diff --git a/src/tools/rustdoc-gui-test/src/main.rs b/src/tools/rustdoc-gui-test/src/main.rs index 6461f38f527..0e35861fbf7 100644 --- a/src/tools/rustdoc-gui-test/src/main.rs +++ b/src/tools/rustdoc-gui-test/src/main.rs @@ -112,11 +112,7 @@ If you want to install the `browser-ui-test` dependency, run `npm install browse .current_dir(path); if let Some(librs) = find_librs(entry.path()) { - let compiletest_c = compiletest::common::Config { - edition: None, - mode: compiletest::common::Mode::Rustdoc, - ..Default::default() - }; + let compiletest_c = compiletest::common::Config::incomplete_for_rustdoc_gui_test(); let test_props = TestProps::from_file( &camino::Utf8PathBuf::try_from(librs).unwrap(), diff --git a/src/tools/x/Cargo.toml b/src/tools/x/Cargo.toml index 84a42ca36ef..c59f5ff52a0 100644 --- a/src/tools/x/Cargo.toml +++ b/src/tools/x/Cargo.toml @@ -2,5 +2,5 @@ name = "x" version = "0.1.1" description = "Run x.py slightly more conveniently" -edition = "2021" +edition = "2024" publish = false diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index b288cfcd5be..93167141d34 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -19,15 +19,14 @@ const PYTHON2: &str = "python2"; const PYTHON3: &str = "python3"; fn python() -> &'static str { - let val = match env::var_os("PATH") { - Some(val) => val, - None => return PYTHON, + let Some(path) = env::var_os("PATH") else { + return PYTHON; }; let mut python2 = false; let mut python3 = false; - for dir in env::split_paths(&val) { + for dir in env::split_paths(&path) { // `python` should always take precedence over python2 / python3 if it exists if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() { return PYTHON; @@ -89,7 +88,7 @@ fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> { fn handle_result(result: io::Result<ExitStatus>, cmd: Command) { match result { Err(error) => { - eprintln!("Failed to invoke `{:?}`: {}", cmd, error); + eprintln!("Failed to invoke `{cmd:?}`: {error}"); } Ok(status) => { process::exit(status.code().unwrap_or(1)); @@ -98,14 +97,12 @@ fn handle_result(result: io::Result<ExitStatus>, cmd: Command) { } fn main() { - match env::args().skip(1).next().as_deref() { - Some("--wrapper-version") => { - let version = env!("CARGO_PKG_VERSION"); - println!("{}", version); - return; - } - _ => {} + if env::args().nth(1).is_some_and(|s| s == "--wrapper-version") { + let version = env!("CARGO_PKG_VERSION"); + println!("{version}"); + return; } + let current = match env::current_dir() { Ok(dir) => dir, Err(err) => { @@ -113,7 +110,6 @@ fn main() { process::exit(1); } }; - for dir in current.ancestors() { let candidate = dir.join("x.py"); if candidate.exists() { diff --git a/tests/assembly/emit-intel-att-syntax.rs b/tests/assembly/emit-intel-att-syntax.rs new file mode 100644 index 00000000000..7b479a0f79e --- /dev/null +++ b/tests/assembly/emit-intel-att-syntax.rs @@ -0,0 +1,75 @@ +//@ assembly-output: emit-asm +//@ revisions: att intel +//@ [att] compile-flags: -Cllvm-args=-x86-asm-syntax=att +//@ [intel] compile-flags: -Cllvm-args=-x86-asm-syntax=intel +//@ only-x86_64 + +#![crate_type = "lib"] + +// CHECK-LABEL: naked_att: +// intel-CHECK: mov rax, qword ptr [rdi] +// intel-CHECK: ret +// att-CHECK: movq (%rdi), %rax +// att-CHECK: retq + +#[unsafe(naked)] +#[unsafe(no_mangle)] +extern "sysv64" fn naked_att() { + std::arch::naked_asm!( + " + movq (%rdi), %rax + retq + ", + options(att_syntax), + ); +} + +// CHECK-LABEL: naked_intel: +// intel-CHECK: mov rax, rdi +// intel-CHECK: ret +// att-CHECK: movq (%rdi), %rax +// att-CHECK: retq + +#[unsafe(naked)] +#[unsafe(no_mangle)] +extern "sysv64" fn naked_intel() { + std::arch::naked_asm!( + " + mov rax, rdi + ret + ", + options(), + ); +} + +// CHECK-LABEL: global_att: +// intel-CHECK: mov rax, rdi +// intel-CHECK: ret +// att-CHECK: movq (%rdi), %rax +// att-CHECK: retq + +core::arch::global_asm!( + " + .globl global_att + global_att: + movq (%rdi), %rax + retq + ", + options(att_syntax), +); + +// CHECK-LABEL: global_intel: +// intel-CHECK: mov rax, rdi +// intel-CHECK: ret +// att-CHECK: movq (%rdi), %rax +// att-CHECK: retq + +core::arch::global_asm!( + " + .globl global_intel + global_intel: + mov rax, rdi + ret + ", + options(), +); diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 392ad1cee14..47dadd51ce0 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -142,6 +142,10 @@ pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ } +#[rustc_builtin_macro] +pub macro cfg_select($($tt:tt)*) { + /* compiler built-in */ +} #[rustc_builtin_macro] #[macro_export] diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index e375724bc1b..c9a1cd58af3 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -29,28 +29,28 @@ pub struct Aggregate8(u8); // CHECK-LABEL: @check_bigger_size( #[no_mangle] pub unsafe fn check_bigger_size(x: u16) -> u32 { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_size( #[no_mangle] pub unsafe fn check_smaller_size(x: u32) -> u16 { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_array( #[no_mangle] pub unsafe fn check_smaller_array(x: [u32; 7]) -> [u32; 3] { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } // CHECK-LABEL: @check_bigger_array( #[no_mangle] pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } @@ -58,9 +58,9 @@ pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] { - // CHECK-NOT: trap - // CHECK: call void @llvm.trap - // CHECK-NOT: trap + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { { RET = CastTransmute(x); @@ -73,9 +73,9 @@ pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] { - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { { RET = CastTransmute(x); @@ -88,9 +88,9 @@ pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_uninhabited(x: u16) { - // CHECK-NOT: trap - // CHECK: call void @llvm.trap - // CHECK-NOT: trap + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { let temp: BigNever; { @@ -104,7 +104,9 @@ pub unsafe fn check_to_uninhabited(x: u16) { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 { - // CHECK: ret i16 poison + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret i16 poison mir! { { RET = CastTransmute(x); @@ -401,9 +403,9 @@ pub unsafe fn check_issue_109992(x: ()) -> [(); 1] { pub unsafe fn check_unit_to_never(x: ()) { // This uses custom MIR to avoid MIR optimizations having removed ZST ops. - // CHECK-NOT: trap - // CHECK: call void @llvm.trap - // CHECK-NOT: trap + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { let temp: ZstNever; { @@ -420,6 +422,7 @@ pub unsafe fn check_unit_from_never(x: ZstNever) -> () { // This uses custom MIR to avoid MIR optimizations having removed ZST ops. // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 // CHECK-NEXT: ret void mir! { { diff --git a/tests/incremental/hashes/inherent_impls.rs b/tests/incremental/hashes/inherent_impls.rs index caea394977a..044c3d2b86c 100644 --- a/tests/incremental/hashes/inherent_impls.rs +++ b/tests/incremental/hashes/inherent_impls.rs @@ -150,7 +150,7 @@ impl Foo { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes")] +#[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes")] #[rustc_clean(cfg="cfail6")] diff --git a/tests/incremental/hashes/trait_impls.rs b/tests/incremental/hashes/trait_impls.rs index 8faf6806b90..a89b5b3e782 100644 --- a/tests/incremental/hashes/trait_impls.rs +++ b/tests/incremental/hashes/trait_impls.rs @@ -141,7 +141,7 @@ pub trait ChangeMethodSelfnessTrait { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")] +#[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] @@ -179,7 +179,7 @@ pub trait RemoveMethodSelfnessTrait { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")] +#[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] diff --git a/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-abort.diff index 285cd0f6527..40e8c06f357 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-abort.diff +++ b/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-abort.diff @@ -7,13 +7,14 @@ let mut _3: &T; bb0: { - _2 = copy _1; +- _2 = copy _1; _3 = &_1; _0 = opaque::<&T>(copy _3) -> [return: bb1, unwind unreachable]; } bb1: { - _0 = opaque::<T>(copy _2) -> [return: bb2, unwind unreachable]; +- _0 = opaque::<T>(copy _2) -> [return: bb2, unwind unreachable]; ++ _0 = opaque::<T>(copy _1) -> [return: bb2, unwind unreachable]; } bb2: { diff --git a/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-unwind.diff index f189615ea95..d09c96c0f2b 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-unwind.diff +++ b/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-unwind.diff @@ -7,13 +7,14 @@ let mut _3: &T; bb0: { - _2 = copy _1; +- _2 = copy _1; _3 = &_1; _0 = opaque::<&T>(copy _3) -> [return: bb1, unwind continue]; } bb1: { - _0 = opaque::<T>(copy _2) -> [return: bb2, unwind continue]; +- _0 = opaque::<T>(copy _2) -> [return: bb2, unwind continue]; ++ _0 = opaque::<T>(copy _1) -> [return: bb2, unwind continue]; } bb2: { diff --git a/tests/mir-opt/copy-prop/borrowed_local.rs b/tests/mir-opt/copy-prop/borrowed_local.rs index 68cdc57483a..08c46fea5f0 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.rs +++ b/tests/mir-opt/copy-prop/borrowed_local.rs @@ -50,11 +50,10 @@ fn compare_address() -> bool { fn borrowed<T: Copy + Freeze>(x: T) -> bool { // CHECK-LABEL: fn borrowed( // CHECK: bb0: { - // CHECK-NEXT: _2 = copy _1; // CHECK-NEXT: _3 = &_1; // CHECK-NEXT: _0 = opaque::<&T>(copy _3) // CHECK: bb1: { - // CHECK-NEXT: _0 = opaque::<T>(copy _2) + // CHECK-NEXT: _0 = opaque::<T>(copy _1) mir! { { let a = x; diff --git a/tests/mir-opt/copy-prop/write_to_borrowed.main.CopyProp.diff b/tests/mir-opt/copy-prop/write_to_borrowed.main.CopyProp.diff index baa71501047..eab06b1ba1e 100644 --- a/tests/mir-opt/copy-prop/write_to_borrowed.main.CopyProp.diff +++ b/tests/mir-opt/copy-prop/write_to_borrowed.main.CopyProp.diff @@ -16,10 +16,11 @@ _3 = const 'b'; _5 = copy _3; _6 = &_3; - _4 = copy _5; +- _4 = copy _5; (*_1) = copy (*_6); _6 = &_5; - _7 = dump_var::<char>(copy _4) -> [return: bb1, unwind unreachable]; +- _7 = dump_var::<char>(copy _4) -> [return: bb1, unwind unreachable]; ++ _7 = dump_var::<char>(copy _5) -> [return: bb1, unwind unreachable]; } bb1: { diff --git a/tests/mir-opt/copy-prop/write_to_borrowed.rs b/tests/mir-opt/copy-prop/write_to_borrowed.rs index 05aa2fba18d..06e617b8bfb 100644 --- a/tests/mir-opt/copy-prop/write_to_borrowed.rs +++ b/tests/mir-opt/copy-prop/write_to_borrowed.rs @@ -27,13 +27,12 @@ fn main() { _5 = _3; // CHECK-NEXT: _6 = &_3; _6 = &_3; - // CHECK-NEXT: _4 = copy _5; _4 = _5; // CHECK-NEXT: (*_1) = copy (*_6); *_1 = *_6; // CHECK-NEXT: _6 = &_5; _6 = &_5; - // CHECK-NEXT: _7 = dump_var::<char>(copy _4) + // CHECK-NEXT: _7 = dump_var::<char>(copy _5) Call(_7 = dump_var(_4), ReturnTo(bb1), UnwindUnreachable()) } bb1 = { Return() } diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir index 97036745009..cbdd194afd3 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir @@ -10,18 +10,18 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 let mut _8: &&usize; let _9: &usize; let mut _10: &&usize; - let mut _15: bool; + let mut _13: bool; + let mut _14: &&usize; + let _15: &usize; let mut _16: &&usize; - let _17: &usize; - let mut _18: &&usize; + let mut _19: bool; + let mut _20: &&usize; + let _21: &usize; + let mut _22: &&usize; let mut _23: bool; let mut _24: &&usize; let _25: &usize; let mut _26: &&usize; - let mut _29: bool; - let mut _30: &&usize; - let _31: &usize; - let mut _32: &&usize; scope 1 { debug a => _4; debug b => _5; @@ -30,47 +30,39 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 scope 2 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) { debug self => _8; debug other => _10; - let mut _11: &usize; - let mut _12: &usize; scope 3 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _11; - debug other => _12; - let mut _13: usize; - let mut _14: usize; + debug self => _4; + debug other => _6; + let mut _11: usize; + let mut _12: usize; } } scope 4 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) { - debug self => _16; - debug other => _18; - let mut _19: &usize; - let mut _20: &usize; + debug self => _14; + debug other => _16; scope 5 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _19; - debug other => _20; - let mut _21: usize; - let mut _22: usize; + debug self => _7; + debug other => _5; + let mut _17: usize; + let mut _18: usize; } } scope 6 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) { - debug self => _24; - debug other => _26; - let mut _27: &usize; - let mut _28: &usize; + debug self => _20; + debug other => _22; scope 7 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _27; - debug other => _28; + debug self => _6; + debug other => _4; } } scope 8 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) { - debug self => _30; - debug other => _32; - let mut _33: &usize; - let mut _34: &usize; + debug self => _24; + debug other => _26; scope 9 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _33; - debug other => _34; - let mut _35: usize; - let mut _36: usize; + debug self => _5; + debug other => _7; + let mut _27: usize; + let mut _28: usize; } } } @@ -81,23 +73,17 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 _5 = &((*_3).1: usize); _6 = &((*_3).2: usize); _7 = &((*_3).3: usize); - StorageLive(_15); + StorageLive(_13); StorageLive(_8); _8 = &_4; StorageLive(_10); StorageLive(_9); _9 = copy _6; _10 = &_9; - StorageLive(_11); - StorageLive(_12); - _11 = copy _4; - _12 = copy _6; - _13 = copy ((*_3).0: usize); - _14 = copy ((*_3).2: usize); - _15 = Le(copy _13, copy _14); - StorageDead(_12); - StorageDead(_11); - switchInt(move _15) -> [0: bb1, otherwise: bb2]; + _11 = copy ((*_3).0: usize); + _12 = copy ((*_3).2: usize); + _13 = Le(copy _11, copy _12); + switchInt(move _13) -> [0: bb1, otherwise: bb2]; } bb1: { @@ -111,107 +97,89 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 StorageDead(_9); StorageDead(_10); StorageDead(_8); - StorageLive(_23); + StorageLive(_19); + StorageLive(_14); + _14 = &_7; StorageLive(_16); - _16 = &_7; - StorageLive(_18); + StorageLive(_15); + _15 = copy _5; + _16 = &_15; StorageLive(_17); - _17 = copy _5; - _18 = &_17; - StorageLive(_19); - StorageLive(_20); - _19 = copy _7; - _20 = copy _5; - StorageLive(_21); - _21 = copy ((*_3).3: usize); - StorageLive(_22); - _22 = copy ((*_3).1: usize); - _23 = Le(move _21, move _22); - StorageDead(_22); - StorageDead(_21); - StorageDead(_20); - StorageDead(_19); - switchInt(move _23) -> [0: bb3, otherwise: bb8]; + _17 = copy ((*_3).3: usize); + StorageLive(_18); + _18 = copy ((*_3).1: usize); + _19 = Le(move _17, move _18); + StorageDead(_18); + StorageDead(_17); + switchInt(move _19) -> [0: bb3, otherwise: bb8]; } bb3: { - StorageDead(_17); - StorageDead(_18); + StorageDead(_15); StorageDead(_16); + StorageDead(_14); goto -> bb4; } bb4: { - StorageLive(_29); - StorageLive(_24); - _24 = &_6; - StorageLive(_26); - StorageLive(_25); - _25 = copy _4; - _26 = &_25; - StorageLive(_27); - StorageLive(_28); - _27 = copy _6; - _28 = copy _4; - _29 = Le(copy _14, copy _13); - StorageDead(_28); - StorageDead(_27); - switchInt(move _29) -> [0: bb5, otherwise: bb6]; + StorageLive(_23); + StorageLive(_20); + _20 = &_6; + StorageLive(_22); + StorageLive(_21); + _21 = copy _4; + _22 = &_21; + _23 = Le(copy _12, copy _11); + switchInt(move _23) -> [0: bb5, otherwise: bb6]; } bb5: { - StorageDead(_25); - StorageDead(_26); - StorageDead(_24); + StorageDead(_21); + StorageDead(_22); + StorageDead(_20); _0 = const false; goto -> bb7; } bb6: { + StorageDead(_21); + StorageDead(_22); + StorageDead(_20); + StorageLive(_24); + _24 = &_5; + StorageLive(_26); + StorageLive(_25); + _25 = copy _7; + _26 = &_25; + StorageLive(_27); + _27 = copy ((*_3).1: usize); + StorageLive(_28); + _28 = copy ((*_3).3: usize); + _0 = Le(move _27, move _28); + StorageDead(_28); + StorageDead(_27); StorageDead(_25); StorageDead(_26); StorageDead(_24); - StorageLive(_30); - _30 = &_5; - StorageLive(_32); - StorageLive(_31); - _31 = copy _7; - _32 = &_31; - StorageLive(_33); - StorageLive(_34); - _33 = copy _5; - _34 = copy _7; - StorageLive(_35); - _35 = copy ((*_3).1: usize); - StorageLive(_36); - _36 = copy ((*_3).3: usize); - _0 = Le(move _35, move _36); - StorageDead(_36); - StorageDead(_35); - StorageDead(_34); - StorageDead(_33); - StorageDead(_31); - StorageDead(_32); - StorageDead(_30); goto -> bb7; } bb7: { - StorageDead(_29); + StorageDead(_23); goto -> bb9; } bb8: { - StorageDead(_17); - StorageDead(_18); + StorageDead(_15); StorageDead(_16); + StorageDead(_14); _0 = const true; goto -> bb9; } bb9: { - StorageDead(_23); - StorageDead(_15); + StorageDead(_19); + StorageDead(_13); return; } } diff --git a/tests/run-make/fmt-write-bloat/rmake.rs b/tests/run-make/fmt-write-bloat/rmake.rs index 3348651d501..af6ff6c2983 100644 --- a/tests/run-make/fmt-write-bloat/rmake.rs +++ b/tests/run-make/fmt-write-bloat/rmake.rs @@ -18,7 +18,7 @@ //@ ignore-cross-compile use run_make_support::artifact_names::bin_name; -use run_make_support::env::no_debug_assertions; +use run_make_support::env::std_debug_assertions_enabled; use run_make_support::rustc; use run_make_support::symbols::any_symbol_contains; @@ -26,7 +26,7 @@ fn main() { rustc().input("main.rs").opt().run(); // panic machinery identifiers, these should not appear in the final binary let mut panic_syms = vec!["panic_bounds_check", "Debug"]; - if no_debug_assertions() { + if std_debug_assertions_enabled() { // if debug assertions are allowed, we need to allow these, // otherwise, add them to the list of symbols to deny. panic_syms.extend_from_slice(&["panicking", "panic_fmt", "pad_integral", "Display"]); diff --git a/tests/rustdoc-json/attrs/target_feature.rs b/tests/rustdoc-json/attrs/target_feature.rs index 80262d8e332..01bc4f54d32 100644 --- a/tests/rustdoc-json/attrs/target_feature.rs +++ b/tests/rustdoc-json/attrs/target_feature.rs @@ -1,22 +1,20 @@ -//@ only-x86_64 - //@ is "$.index[?(@.name=='test1')].attrs" '["#[target_feature(enable=\"avx\")]"]' //@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false #[target_feature(enable = "avx")] pub fn test1() {} //@ is "$.index[?(@.name=='test2')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]' -//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='test2')].inner.function.header.is_unsafe" false #[target_feature(enable = "avx,avx2")] pub fn test2() {} //@ is "$.index[?(@.name=='test3')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]' -//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='test3')].inner.function.header.is_unsafe" false #[target_feature(enable = "avx", enable = "avx2")] pub fn test3() {} //@ is "$.index[?(@.name=='test4')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\", enable=\"avx512f\")]"]' -//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='test4')].inner.function.header.is_unsafe" false #[target_feature(enable = "avx", enable = "avx2,avx512f")] pub fn test4() {} diff --git a/tests/rustdoc-json/visibility/doc_hidden_default.rs b/tests/rustdoc-json/visibility/doc_hidden_default.rs new file mode 100644 index 00000000000..3fa91b3c4ad --- /dev/null +++ b/tests/rustdoc-json/visibility/doc_hidden_default.rs @@ -0,0 +1,19 @@ +#![no_std] + +// Without `--document-hidden-items`, +// none of these items are present in rustdoc JSON. + +//@ !has "$.index[?(@.name=='func')]" +#[doc(hidden)] +pub fn func() {} + +//@ !has "$.index[?(@.name=='Unit')]" +#[doc(hidden)] +pub struct Unit; + +//@ !has "$.index[?(@.name=='hidden')]" +#[doc(hidden)] +pub mod hidden { + //@ !has "$.index[?(@.name=='Inner')]" + pub struct Inner; +} diff --git a/tests/rustdoc-json/visibility/doc_hidden_documented.rs b/tests/rustdoc-json/visibility/doc_hidden_documented.rs new file mode 100644 index 00000000000..6e9ef48680b --- /dev/null +++ b/tests/rustdoc-json/visibility/doc_hidden_documented.rs @@ -0,0 +1,17 @@ +//@ compile-flags: --document-hidden-items +#![no_std] + +//@ is "$.index[?(@.name=='func')].attrs" '["#[doc(hidden)]"]' +#[doc(hidden)] +pub fn func() {} + +//@ is "$.index[?(@.name=='Unit')].attrs" '["#[doc(hidden)]"]' +#[doc(hidden)] +pub struct Unit; + +//@ is "$.index[?(@.name=='hidden')].attrs" '["#[doc(hidden)]"]' +#[doc(hidden)] +pub mod hidden { + //@ is "$.index[?(@.name=='Inner')].attrs" '[]' + pub struct Inner; +} diff --git a/tests/rustdoc/reexport/merge-glob-and-non-glob.rs b/tests/rustdoc/reexport/merge-glob-and-non-glob.rs new file mode 100644 index 00000000000..ff67859cb39 --- /dev/null +++ b/tests/rustdoc/reexport/merge-glob-and-non-glob.rs @@ -0,0 +1,41 @@ +// This test ensures that if an item is inlined from two different `use`, +// then it will use attributes from both of them. +// This is a regression test for <https://github.com/rust-lang/rust/issues/143107>. + +#![feature(no_core)] +#![no_core] +#![no_std] +#![crate_name = "foo"] + +// First we ensure we only have two items. +//@ has 'foo/index.html' +//@ count - '//dl[@class="item-table"]/dt' 2 +// We should also only have one section (Structs). +//@ count - '//h2[@class="section-header"]' 1 +// We now check the short docs. +//@ has - '//dl[@class="item-table"]/dd' 'Foobar Blob' +//@ has - '//dl[@class="item-table"]/dd' 'Tarte Tatin' + +//@ has 'foo/struct.Foo.html' +//@ has - '//*[@class="docblock"]' 'Foobar Blob' + +//@ has 'foo/struct.Another.html' +//@ has - '//*[@class="docblock"]' 'Tarte Tatin' + +mod raw { + /// Blob + pub struct Foo; + + /// Tatin + pub struct Another; +} + +/// Foobar +pub use raw::Foo; + +// Glob reexport attributes are ignored. +/// Baz +pub use raw::*; + +/// Tarte +pub use raw::Another as Another; diff --git a/tests/ui/allocator/weak-uninhabited-type.rs b/tests/ui/allocator/weak-uninhabited-type.rs new file mode 100644 index 00000000000..74258eedc6a --- /dev/null +++ b/tests/ui/allocator/weak-uninhabited-type.rs @@ -0,0 +1,13 @@ +//! Checks that `Weak` pointers can be created with an empty enum type parameter. +//! And generic `Weak` handles zero-variant enums without error. +//! +//! Regression test for <https://github.com/rust-lang/rust/issues/48493> + +//@ run-pass + +enum Void {} + +fn main() { + let _ = std::rc::Weak::<Void>::new(); + let _ = std::sync::Weak::<Void>::new(); +} diff --git a/tests/ui/associated-consts/equality-unused-issue-126729.rs b/tests/ui/associated-consts/equality-unused-issue-126729.rs new file mode 100644 index 00000000000..1482b874b9d --- /dev/null +++ b/tests/ui/associated-consts/equality-unused-issue-126729.rs @@ -0,0 +1,44 @@ +//@ check-pass + +#![feature(associated_const_equality)] +#![deny(dead_code)] + +trait Tr { + const I: i32; +} + +impl Tr for () { + const I: i32 = 1; +} + +fn foo() -> impl Tr<I = 1> {} + +trait Tr2 { + const J: i32; + const K: i32; +} + +impl Tr2 for () { + const J: i32 = 1; + const K: i32 = 1; +} + +fn foo2() -> impl Tr2<J = 1, K = 1> {} + +mod t { + pub trait Tr3 { + const L: i32; + } + + impl Tr3 for () { + const L: i32 = 1; + } +} + +fn foo3() -> impl t::Tr3<L = 1> {} + +fn main() { + foo(); + foo2(); + foo3(); +} diff --git a/tests/ui/associated-consts/issue-58022.stderr b/tests/ui/associated-consts/issue-58022.stderr index 37cb162b2b2..5d57e01d6f5 100644 --- a/tests/ui/associated-consts/issue-58022.stderr +++ b/tests/ui/associated-consts/issue-58022.stderr @@ -16,7 +16,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin --> $DIR/issue-58022.rs:4:25 | LL | const SIZE: usize; - | ------------------ `Foo::SIZE` defined here + | ----------------- `Foo::SIZE` defined here LL | LL | fn new(slice: &[u8; Foo::SIZE]) -> Self; | ^^^^^^^^^ cannot refer to the associated constant of trait diff --git a/tests/ui/associated-consts/issue-63496.stderr b/tests/ui/associated-consts/issue-63496.stderr index f2a4e01adea..bdd2769afc8 100644 --- a/tests/ui/associated-consts/issue-63496.stderr +++ b/tests/ui/associated-consts/issue-63496.stderr @@ -2,7 +2,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin --> $DIR/issue-63496.rs:4:21 | LL | const C: usize; - | --------------- `A::C` defined here + | -------------- `A::C` defined here LL | LL | fn f() -> ([u8; A::C], [u8; A::C]); | ^^^^ cannot refer to the associated constant of trait @@ -11,7 +11,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin --> $DIR/issue-63496.rs:4:33 | LL | const C: usize; - | --------------- `A::C` defined here + | -------------- `A::C` defined here LL | LL | fn f() -> ([u8; A::C], [u8; A::C]); | ^^^^ cannot refer to the associated constant of trait diff --git a/tests/ui/associated-item/issue-48027.stderr b/tests/ui/associated-item/issue-48027.stderr index 513961e2bd0..e5c1ced9341 100644 --- a/tests/ui/associated-item/issue-48027.stderr +++ b/tests/ui/associated-item/issue-48027.stderr @@ -18,7 +18,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin --> $DIR/issue-48027.rs:3:32 | LL | const X: usize; - | --------------- `Bar::X` defined here + | -------------- `Bar::X` defined here LL | fn return_n(&self) -> [u8; Bar::X]; | ^^^^^^ cannot refer to the associated constant of trait diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr index a7647cf26aa..71a1360cb5a 100644 --- a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr +++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr @@ -42,7 +42,7 @@ LL + type X = <CString as Deref>::Target; LL - type X = std::ops::Deref::Target; LL + type X = <IoSlice<'_> as Deref>::Target; | - and N other candidates + = and N other candidates error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:13:23 diff --git a/tests/ui/associated-types/defaults-in-other-trait-items.stderr b/tests/ui/associated-types/defaults-in-other-trait-items.stderr index bdcfadd3955..56abd6ebf73 100644 --- a/tests/ui/associated-types/defaults-in-other-trait-items.stderr +++ b/tests/ui/associated-types/defaults-in-other-trait-items.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/defaults-in-other-trait-items.rs:9:13 | LL | type A = (); - | ------------ associated type defaults can't be assumed inside the trait defining them + | ------ associated type defaults can't be assumed inside the trait defining them ... LL | let () = p; | ^^ - this expression has type `<Self as Tr>::A` @@ -16,7 +16,7 @@ error[E0308]: mismatched types --> $DIR/defaults-in-other-trait-items.rs:36:25 | LL | type Ty = u8; - | ------------- associated type defaults can't be assumed inside the trait defining them + | ------- associated type defaults can't be assumed inside the trait defining them ... LL | const C: Self::Ty = 0u8; | ^^^ expected associated type, found `u8` @@ -28,7 +28,7 @@ error[E0308]: mismatched types --> $DIR/defaults-in-other-trait-items.rs:54:9 | LL | type Res = isize; - | ----------------- associated type defaults can't be assumed inside the trait defining them + | -------- associated type defaults can't be assumed inside the trait defining them LL | LL | fn infer_me_correctly() -> Self::Res { | --------- expected `<Self as Trait>::Res` because of return type diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr index fd2a1a0c2d1..7d19ac85982 100644 --- a/tests/ui/associated-types/defaults-specialization.stderr +++ b/tests/ui/associated-types/defaults-specialization.stderr @@ -31,7 +31,7 @@ error[E0053]: method `make` has an incompatible type for trait --> $DIR/defaults-specialization.rs:35:18 | LL | default type Ty = bool; - | ----------------------- associated type is `default` and may be overridden + | --------------- associated type is `default` and may be overridden LL | LL | fn make() -> bool { true } | ^^^^ expected associated type, found `bool` @@ -53,7 +53,7 @@ error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:10:9 | LL | type Ty = u8; - | ------------- associated type defaults can't be assumed inside the trait defining them + | ------- associated type defaults can't be assumed inside the trait defining them LL | LL | fn make() -> Self::Ty { | -------- expected `<Self as Tr>::Ty` because of return type @@ -80,7 +80,7 @@ error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:44:29 | LL | default type Ty = bool; - | ----------------------- associated type is `default` and may be overridden + | --------------- associated type is `default` and may be overridden LL | LL | fn make() -> Self::Ty { true } | -------- ^^^^ expected associated type, found `bool` diff --git a/tests/ui/associated-types/issue-26681.stderr b/tests/ui/associated-types/issue-26681.stderr index b64bcee07f0..5fb1a4ef3f5 100644 --- a/tests/ui/associated-types/issue-26681.stderr +++ b/tests/ui/associated-types/issue-26681.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-26681.rs:17:39 | LL | type Fv: Foo = u8; - | ------------------ associated type defaults can't be assumed inside the trait defining them + | ------------ associated type defaults can't be assumed inside the trait defining them LL | const C: <Self::Fv as Foo>::Bar = 6665; | ^^^^ expected associated type, found integer | diff --git a/tests/ui/attributes/builtin-attribute-prefix.rs b/tests/ui/attributes/builtin-attribute-prefix.rs new file mode 100644 index 00000000000..d184c6d008d --- /dev/null +++ b/tests/ui/attributes/builtin-attribute-prefix.rs @@ -0,0 +1,8 @@ +// Regression test for https://github.com/rust-lang/rust/issues/143789 +#[must_use::skip] +//~^ ERROR failed to resolve: use of unresolved module or unlinked crate `must_use` +fn main() { } + +// Regression test for https://github.com/rust-lang/rust/issues/137590 +struct S(#[stable::skip] u8, u16, u32); +//~^ ERROR failed to resolve: use of unresolved module or unlinked crate `stable` diff --git a/tests/ui/attributes/builtin-attribute-prefix.stderr b/tests/ui/attributes/builtin-attribute-prefix.stderr new file mode 100644 index 00000000000..a16080c003f --- /dev/null +++ b/tests/ui/attributes/builtin-attribute-prefix.stderr @@ -0,0 +1,15 @@ +error[E0433]: failed to resolve: use of unresolved module or unlinked crate `stable` + --> $DIR/builtin-attribute-prefix.rs:7:12 + | +LL | struct S(#[stable::skip] u8, u16, u32); + | ^^^^^^ use of unresolved module or unlinked crate `stable` + +error[E0433]: failed to resolve: use of unresolved module or unlinked crate `must_use` + --> $DIR/builtin-attribute-prefix.rs:2:3 + | +LL | #[must_use::skip] + | ^^^^^^^^ use of unresolved module or unlinked crate `must_use` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 5bcb0c4dc0a..f16ba706485 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -116,24 +116,6 @@ error: malformed `cfi_encoding` attribute input LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` -error: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:143:5 - | -LL | #[type_const = 1] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` - -error: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:155:1 - | -LL | #[marker = 3] - | ^^^^^^^^^^^^^ help: must be of the form: `#[marker]` - -error: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:157:1 - | -LL | #[fundamental()] - | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]` - error: malformed `link_ordinal` attribute input --> $DIR/malformed-attrs.rs:167:5 | @@ -528,6 +510,24 @@ LL | #[rustc_layout_scalar_valid_range_end] | expected this to be a list | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` +error[E0565]: malformed `marker` attribute input + --> $DIR/malformed-attrs.rs:155:1 + | +LL | #[marker = 3] + | ^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` + +error[E0565]: malformed `fundamental` attribute input + --> $DIR/malformed-attrs.rs:157:1 + | +LL | #[fundamental()] + | ^^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[fundamental]` + error[E0565]: malformed `ffi_pure` attribute input --> $DIR/malformed-attrs.rs:165:5 | @@ -555,6 +555,15 @@ LL | #[non_exhaustive = 1] | | didn't expect any arguments here | help: must be of the form: `#[non_exhaustive]` +error[E0565]: malformed `type_const` attribute input + --> $DIR/malformed-attrs.rs:143:5 + | +LL | #[type_const = 1] + | ^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[type_const]` + error: attribute should be applied to `const fn` --> $DIR/malformed-attrs.rs:34:1 | @@ -585,7 +594,7 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(malformed_diagnostic_attributes)]` on by default warning: missing options for `on_unimplemented` attribute --> $DIR/malformed-attrs.rs:138:1 diff --git a/tests/ui/type-param-constraints.rs b/tests/ui/auto-traits/auto-traits-type-parameter.rs index 83d81c0d833..0c448f58996 100644 --- a/tests/ui/type-param-constraints.rs +++ b/tests/ui/auto-traits/auto-traits-type-parameter.rs @@ -1,24 +1,25 @@ +//! Checks how type parameters interact with auto-traits like `Send` and `Sync` with implicit +//! bounds + //@ run-pass #![allow(non_camel_case_types)] #![allow(dead_code)] -fn p_foo<T>(_pinned: T) { } -fn s_foo<T>(_shared: T) { } -fn u_foo<T:Send>(_unique: T) { } +fn p_foo<T>(_pinned: T) {} +fn s_foo<T>(_shared: T) {} +fn u_foo<T: Send>(_unique: T) {} struct r { - i: isize, + i: isize, } impl Drop for r { fn drop(&mut self) {} } -fn r(i:isize) -> r { - r { - i: i - } +fn r(i: isize) -> r { + r { i } } pub fn main() { diff --git a/tests/ui/auxiliary/svh-a-base.rs b/tests/ui/auxiliary/svh-a-base.rs deleted file mode 100644 index 36b41fc818f..00000000000 --- a/tests/ui/auxiliary/svh-a-base.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! The `svh-a-*.rs` files are all deviations from the base file -//! svh-a-base.rs with some difference (usually in `fn foo`) that -//! should not affect the strict version hash (SVH) computation -//! (#14132). - -#![crate_name = "a"] - -macro_rules! three { - () => { 3 } -} - -pub trait U {} -pub trait V {} -impl U for () {} -impl V for () {} - -static A_CONSTANT : isize = 2; - -pub fn foo<T:U>(_: isize) -> isize { - 3 -} - -pub fn an_unused_name() -> isize { - 4 -} diff --git a/tests/ui/auxiliary/svh-b.rs b/tests/ui/auxiliary/svh-b.rs deleted file mode 100644 index 57029f70888..00000000000 --- a/tests/ui/auxiliary/svh-b.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! This is a client of the `a` crate defined in `svn-a-base.rs`. The -//! rpass and cfail tests (such as `run-pass/svh-add-comment.rs`) use -//! it by swapping in a different object code library crate built from -//! some variant of `svn-a-base.rs`, and then we are checking if the -//! compiler properly ignores or accepts the change, based on whether -//! the change could affect the downstream crate content or not -//! (#14132). - -#![crate_name = "b"] - -extern crate a; - -pub fn foo() { assert_eq!(a::foo::<()>(0), 3); } diff --git a/tests/ui/binding/underscore-prefixed-function-argument.rs b/tests/ui/binding/underscore-prefixed-function-argument.rs new file mode 100644 index 00000000000..e5b2ec1b5f0 --- /dev/null +++ b/tests/ui/binding/underscore-prefixed-function-argument.rs @@ -0,0 +1,15 @@ +//! Test that argument names starting with `_` are usable. + +//@ run-pass + +fn good(_a: &isize) {} + +fn called<F>(_f: F) +where + F: FnOnce(&isize), +{ +} + +pub fn main() { + called(good); +} diff --git a/tests/ui/borrowck/ownership-struct-update-moved-error.rs b/tests/ui/borrowck/ownership-struct-update-moved-error.rs new file mode 100644 index 00000000000..62fc1f42969 --- /dev/null +++ b/tests/ui/borrowck/ownership-struct-update-moved-error.rs @@ -0,0 +1,19 @@ +//! Checks borrow after move error when using `self` consuming method with struct update syntax. + +struct Mine { + test: String, + other_val: isize, +} + +impl Mine { + fn make_string_bar(mut self) -> Mine { + self.test = "Bar".to_string(); + self + } +} + +fn main() { + let start = Mine { test: "Foo".to_string(), other_val: 0 }; + let end = Mine { other_val: 1, ..start.make_string_bar() }; + println!("{}", start.test); //~ ERROR borrow of moved value: `start` +} diff --git a/tests/ui/walk-struct-literal-with.stderr b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr index 34b501f8ec8..83cfc7bb412 100644 --- a/tests/ui/walk-struct-literal-with.stderr +++ b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr @@ -1,17 +1,17 @@ error[E0382]: borrow of moved value: `start` - --> $DIR/walk-struct-literal-with.rs:16:20 + --> $DIR/ownership-struct-update-moved-error.rs:18:20 | -LL | let start = Mine{test:"Foo".to_string(), other_val:0}; +LL | let start = Mine { test: "Foo".to_string(), other_val: 0 }; | ----- move occurs because `start` has type `Mine`, which does not implement the `Copy` trait -LL | let end = Mine{other_val:1, ..start.make_string_bar()}; - | ----------------- `start` moved due to this method call +LL | let end = Mine { other_val: 1, ..start.make_string_bar() }; + | ----------------- `start` moved due to this method call LL | println!("{}", start.test); | ^^^^^^^^^^ value borrowed here after move | note: `Mine::make_string_bar` takes ownership of the receiver `self`, which moves `start` - --> $DIR/walk-struct-literal-with.rs:7:28 + --> $DIR/ownership-struct-update-moved-error.rs:9:28 | -LL | fn make_string_bar(mut self) -> Mine{ +LL | fn make_string_bar(mut self) -> Mine { | ^^^^ = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/super-let.borrowck.stderr b/tests/ui/borrowck/super-let-lifetime-and-drop.borrowck.stderr index 01ef29d8758..7fe0b47ed57 100644 --- a/tests/ui/super-let.borrowck.stderr +++ b/tests/ui/borrowck/super-let-lifetime-and-drop.borrowck.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:30:28 + --> $DIR/super-let-lifetime-and-drop.rs:30:28 | LL | super let b = DropMe(&mut x); | ------ `x` is borrowed here @@ -11,7 +11,7 @@ LL | } | - borrow might be used here, when `b` is dropped and runs the `Drop` code for type `DropMe` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:46:28 + --> $DIR/super-let-lifetime-and-drop.rs:46:28 | LL | super let b = &DropMe(&mut x); | -------------- @@ -26,7 +26,7 @@ LL | } | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DropMe` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:64:32 + --> $DIR/super-let-lifetime-and-drop.rs:64:32 | LL | super let b = identity(&DropMe(&mut x)); | -------------- @@ -40,7 +40,7 @@ LL | }; | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DropMe` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:87:36 + --> $DIR/super-let-lifetime-and-drop.rs:87:36 | LL | super let b = identity(&DropMe(&mut x)); | -------------- @@ -55,7 +55,7 @@ LL | )); | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DropMe` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:107:28 + --> $DIR/super-let-lifetime-and-drop.rs:107:28 | LL | super let b = DropMe(&mut x); | ------ `x` is borrowed here @@ -67,7 +67,7 @@ LL | } | - borrow might be used here, when `b` is dropped and runs the `Drop` code for type `DropMe` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:125:28 + --> $DIR/super-let-lifetime-and-drop.rs:125:28 | LL | super let b = DropMe(&mut x); | ------ `x` is borrowed here @@ -79,7 +79,7 @@ LL | } | - borrow might be used here, when `b` is dropped and runs the `Drop` code for type `DropMe` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:143:28 + --> $DIR/super-let-lifetime-and-drop.rs:143:28 | LL | super let b = DropMe(&mut x); | ------ `x` is borrowed here @@ -91,7 +91,7 @@ LL | } | - borrow might be used here, when `b` is dropped and runs the `Drop` code for type `DropMe` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:159:28 + --> $DIR/super-let-lifetime-and-drop.rs:159:28 | LL | b = DropMe(&mut x); | ------ `x` is borrowed here @@ -102,7 +102,7 @@ LL | drop(a); | - borrow later used here error[E0716]: temporary value dropped while borrowed - --> $DIR/super-let.rs:172:33 + --> $DIR/super-let-lifetime-and-drop.rs:172:33 | LL | #[cfg(borrowck)] { a = &String::from("asdf"); }; | ^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement @@ -115,7 +115,7 @@ LL | let _ = a; = note: consider using a `let` binding to create a longer lived value error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:206:28 + --> $DIR/super-let-lifetime-and-drop.rs:206:28 | LL | super let d = &DropMe(&mut x); | -------------- @@ -130,7 +130,7 @@ LL | } | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DropMe` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:227:32 + --> $DIR/super-let-lifetime-and-drop.rs:227:32 | LL | super let d = identity(&DropMe(&mut x)); | -------------- @@ -145,7 +145,7 @@ LL | }; | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DropMe` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:246:28 + --> $DIR/super-let-lifetime-and-drop.rs:246:28 | LL | super let b = DropMe(&mut x); | ------ `x` is borrowed here @@ -157,7 +157,7 @@ LL | } | - borrow might be used here, when `b` is dropped and runs the `Drop` code for type `DropMe` error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/super-let.rs:263:28 + --> $DIR/super-let-lifetime-and-drop.rs:263:28 | LL | let dropme = Some(DropMe(&mut x)); | ------ `x` is borrowed here diff --git a/tests/ui/super-let.rs b/tests/ui/borrowck/super-let-lifetime-and-drop.rs index 380470f792f..380470f792f 100644 --- a/tests/ui/super-let.rs +++ b/tests/ui/borrowck/super-let-lifetime-and-drop.rs diff --git a/tests/ui/tag-variant-cast-non-nullary.rs b/tests/ui/cast/cast-enum-to-primitive-error.fixed index 1a64cf1933d..4d447c81ac9 100644 --- a/tests/ui/tag-variant-cast-non-nullary.rs +++ b/tests/ui/cast/cast-enum-to-primitive-error.fixed @@ -1,5 +1,10 @@ +//! This test verifies that a direct non-primitive cast from an enum to an integer type +//! is correctly disallowed, even when a `From` implementation exists for that enum. + //@ run-rustfix + #![allow(dead_code, unused_variables)] + enum NonNullary { Nullary, Other(isize), @@ -16,5 +21,7 @@ impl From<NonNullary> for isize { fn main() { let v = NonNullary::Nullary; - let val = v as isize; //~ ERROR non-primitive cast: `NonNullary` as `isize` [E0605] + let val = isize::from(v); + //~^ ERROR non-primitive cast: `NonNullary` as `isize` [E0605] + //~| HELP consider using the `From` trait instead } diff --git a/tests/ui/tag-variant-cast-non-nullary.fixed b/tests/ui/cast/cast-enum-to-primitive-error.rs index 7e22116b955..fdbe63b9bc7 100644 --- a/tests/ui/tag-variant-cast-non-nullary.fixed +++ b/tests/ui/cast/cast-enum-to-primitive-error.rs @@ -1,5 +1,10 @@ +//! This test verifies that a direct non-primitive cast from an enum to an integer type +//! is correctly disallowed, even when a `From` implementation exists for that enum. + //@ run-rustfix + #![allow(dead_code, unused_variables)] + enum NonNullary { Nullary, Other(isize), @@ -16,5 +21,7 @@ impl From<NonNullary> for isize { fn main() { let v = NonNullary::Nullary; - let val = isize::from(v); //~ ERROR non-primitive cast: `NonNullary` as `isize` [E0605] + let val = v as isize; + //~^ ERROR non-primitive cast: `NonNullary` as `isize` [E0605] + //~| HELP consider using the `From` trait instead } diff --git a/tests/ui/tag-variant-cast-non-nullary.stderr b/tests/ui/cast/cast-enum-to-primitive-error.stderr index 8ec1c5f11ec..692e5c19e06 100644 --- a/tests/ui/tag-variant-cast-non-nullary.stderr +++ b/tests/ui/cast/cast-enum-to-primitive-error.stderr @@ -1,5 +1,5 @@ error[E0605]: non-primitive cast: `NonNullary` as `isize` - --> $DIR/tag-variant-cast-non-nullary.rs:19:15 + --> $DIR/cast-enum-to-primitive-error.rs:24:15 | LL | let val = v as isize; | ^^^^^^^^^^ an `as` expression can be used to convert enum types to numeric types only if the enum type is unit-only or field-less diff --git a/tests/ui/trivial_casts-rpass.rs b/tests/ui/cast/coercion-as-explicit-cast.rs index 701e2f6166f..b99f5d93478 100644 --- a/tests/ui/trivial_casts-rpass.rs +++ b/tests/ui/cast/coercion-as-explicit-cast.rs @@ -1,5 +1,7 @@ +//! This test checks that various forms of "trivial" casts and coercions +//! can be explicitly performed using the `as` keyword without compilation errors. + //@ run-pass -// Test that all coercions can actually be done using casts (modulo the lints). #![allow(trivial_casts, trivial_numeric_casts)] diff --git a/tests/ui/trivial_casts-rpass.stderr b/tests/ui/cast/coercion-as-explicit-cast.stderr index 74698b61ab4..d66298c7d44 100644 --- a/tests/ui/trivial_casts-rpass.stderr +++ b/tests/ui/cast/coercion-as-explicit-cast.stderr @@ -1,5 +1,5 @@ warning: method `foo` is never used - --> $DIR/trivial_casts-rpass.rs:7:8 + --> $DIR/coercion-as-explicit-cast.rs:9:8 | LL | trait Foo { | --- method in this trait diff --git a/tests/ui/unused-move-capture.rs b/tests/ui/closures/no-capture-closure-call.rs index 5f42bcbe280..29e5ac635b4 100644 --- a/tests/ui/unused-move-capture.rs +++ b/tests/ui/closures/no-capture-closure-call.rs @@ -1,3 +1,5 @@ +//! Sanity check for no capture closures + //@ run-pass pub fn main() { diff --git a/tests/ui/unknown-llvm-arg.rs b/tests/ui/codegen/llvm-args-invalid-flag.rs index a8fa55a220a..a8fa55a220a 100644 --- a/tests/ui/unknown-llvm-arg.rs +++ b/tests/ui/codegen/llvm-args-invalid-flag.rs diff --git a/tests/ui/unknown-llvm-arg.stderr b/tests/ui/codegen/llvm-args-invalid-flag.stderr index e1d3cfea28f..e1d3cfea28f 100644 --- a/tests/ui/unknown-llvm-arg.stderr +++ b/tests/ui/codegen/llvm-args-invalid-flag.stderr diff --git a/tests/ui/const-generics/cross_crate_complex.rs b/tests/ui/const-generics/cross_crate_complex.rs index d13b69aa0cf..b44d889f5e9 100644 --- a/tests/ui/const-generics/cross_crate_complex.rs +++ b/tests/ui/const-generics/cross_crate_complex.rs @@ -11,6 +11,7 @@ async fn foo() { async_in_foo(async_out_foo::<4>().await).await; } +#[allow(dead_code)] struct Faz<const N: usize>; impl<const N: usize> Foo<N> for Faz<N> {} diff --git a/tests/ui/const-generics/issues/issue-82956.stderr b/tests/ui/const-generics/issues/issue-82956.stderr index 5e380eea81c..fd93e5122a5 100644 --- a/tests/ui/const-generics/issues/issue-82956.stderr +++ b/tests/ui/const-generics/issues/issue-82956.stderr @@ -14,7 +14,7 @@ LL + use std::collections::btree_map::IntoIter; | LL + use std::collections::btree_set::IntoIter; | - and 9 other candidates + = and 9 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-90318.rs b/tests/ui/const-generics/issues/issue-90318.rs index dfba90a5575..239171217eb 100644 --- a/tests/ui/const-generics/issues/issue-90318.rs +++ b/tests/ui/const-generics/issues/issue-90318.rs @@ -1,6 +1,6 @@ #![feature(const_type_id)] #![feature(generic_const_exprs)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_cmp)] #![feature(core_intrinsics)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr index 579aff849d6..125c778ef1c 100644 --- a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr @@ -1,9 +1,3 @@ -error: malformed `type_const` attribute input - --> $DIR/bad-type_const-syntax.rs:2:5 - | -LL | #[type_const()] - | ^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` - error[E0658]: the `#[type_const]` attribute is an experimental feature --> $DIR/bad-type_const-syntax.rs:2:5 | @@ -24,6 +18,15 @@ LL | #[type_const] = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0565]: malformed `type_const` attribute input + --> $DIR/bad-type_const-syntax.rs:2:5 + | +LL | #[type_const()] + | ^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[type_const]` + error: `#[type_const]` must only be applied to trait associated constants --> $DIR/bad-type_const-syntax.rs:11:5 | @@ -32,4 +35,5 @@ LL | #[type_const] error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0565, E0658. +For more information about an error, try `rustc --explain E0565`. diff --git a/tests/ui/consts/const-eval-array-len-in-impl.rs b/tests/ui/consts/const-eval-array-len-in-impl.rs new file mode 100644 index 00000000000..0373274770d --- /dev/null +++ b/tests/ui/consts/const-eval-array-len-in-impl.rs @@ -0,0 +1,15 @@ +//! This checks that compiler correctly evaluate constant array lengths within trait `impl` headers. +//! +//! Regression test for <https://github.com/rust-lang/rust/issues/49208>. + +trait Foo { + fn foo(); +} + +impl Foo for [(); 1] { + fn foo() {} +} + +fn main() { + <[(); 0] as Foo>::foo() //~ ERROR E0277 +} diff --git a/tests/ui/unevaluated_fixed_size_array_len.stderr b/tests/ui/consts/const-eval-array-len-in-impl.stderr index 43cc377006e..faff7aa3ff7 100644 --- a/tests/ui/unevaluated_fixed_size_array_len.stderr +++ b/tests/ui/consts/const-eval-array-len-in-impl.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied - --> $DIR/unevaluated_fixed_size_array_len.rs:12:6 + --> $DIR/const-eval-array-len-in-impl.rs:14:6 | LL | <[(); 0] as Foo>::foo() | ^^^^^^^ the trait `Foo` is not implemented for `[(); 0]` diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr index 6d6bc157771..825b9e94158 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr @@ -2,25 +2,37 @@ error[E0277]: the size for values of type `Opaque` cannot be known --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:43 | LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; - | ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque` | | | required by a bound introduced by this call | - = help: the trait `MetaSized` is not implemented for `Opaque` + = note: the trait bound `Opaque: MetaSized` is not satisfied note: required by a bound in `std::intrinsics::size_of_val` --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL +help: consider borrowing here + | +LL | const _SIZE: usize = unsafe { size_of_val(&(&4 as *const i32 as *const Opaque)) }; + | ++ + +LL | const _SIZE: usize = unsafe { size_of_val(&mut (&4 as *const i32 as *const Opaque)) }; + | ++++++ + error[E0277]: the size for values of type `Opaque` cannot be known --> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:45 | LL | const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) }; - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque` | | | required by a bound introduced by this call | - = help: the trait `MetaSized` is not implemented for `Opaque` + = note: the trait bound `Opaque: MetaSized` is not satisfied note: required by a bound in `std::intrinsics::align_of_val` --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL +help: consider borrowing here + | +LL | const _ALIGN: usize = unsafe { align_of_val(&(&4 as *const i32 as *const Opaque)) }; + | ++ + +LL | const _ALIGN: usize = unsafe { align_of_val(&mut (&4 as *const i32 as *const Opaque)) }; + | ++++++ + error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const_cmp_type_id.rs b/tests/ui/consts/const_cmp_type_id.rs index def615bd92b..db2d50f4d22 100644 --- a/tests/ui/consts/const_cmp_type_id.rs +++ b/tests/ui/consts/const_cmp_type_id.rs @@ -1,5 +1,5 @@ //@ compile-flags: -Znext-solver -#![feature(const_type_id, const_trait_impl)] +#![feature(const_type_id, const_trait_impl, const_cmp)] use std::any::TypeId; diff --git a/tests/ui/consts/const_transmute_type_id.rs b/tests/ui/consts/const_transmute_type_id.rs index 56ead6a622b..a2d4cf37830 100644 --- a/tests/ui/consts/const_transmute_type_id.rs +++ b/tests/ui/consts/const_transmute_type_id.rs @@ -1,4 +1,4 @@ -#![feature(const_type_id, const_trait_impl)] +#![feature(const_type_id, const_trait_impl, const_cmp)] use std::any::TypeId; diff --git a/tests/ui/consts/const_transmute_type_id2.rs b/tests/ui/consts/const_transmute_type_id2.rs index e29cf8171ac..3ceb2b942b0 100644 --- a/tests/ui/consts/const_transmute_type_id2.rs +++ b/tests/ui/consts/const_transmute_type_id2.rs @@ -1,6 +1,6 @@ //@ normalize-stderr: "0x(ff)+" -> "<u128::MAX>" -#![feature(const_type_id, const_trait_impl)] +#![feature(const_type_id, const_trait_impl, const_cmp)] use std::any::TypeId; diff --git a/tests/ui/consts/const_transmute_type_id3.rs b/tests/ui/consts/const_transmute_type_id3.rs index a870d6e7e80..ed5ff769701 100644 --- a/tests/ui/consts/const_transmute_type_id3.rs +++ b/tests/ui/consts/const_transmute_type_id3.rs @@ -1,4 +1,4 @@ -#![feature(const_type_id, const_trait_impl)] +#![feature(const_type_id, const_trait_impl, const_cmp)] use std::any::TypeId; diff --git a/tests/ui/consts/const_transmute_type_id4.rs b/tests/ui/consts/const_transmute_type_id4.rs index bc71f961a51..22a607e9e0e 100644 --- a/tests/ui/consts/const_transmute_type_id4.rs +++ b/tests/ui/consts/const_transmute_type_id4.rs @@ -1,4 +1,4 @@ -#![feature(const_type_id, const_trait_impl)] +#![feature(const_type_id, const_trait_impl, const_cmp)] use std::any::TypeId; diff --git a/tests/ui/consts/issue-54954.stderr b/tests/ui/consts/issue-54954.stderr index b8c983eb7b8..2ef3abcf760 100644 --- a/tests/ui/consts/issue-54954.stderr +++ b/tests/ui/consts/issue-54954.stderr @@ -10,14 +10,11 @@ LL | const fn const_val<T: Sized>() -> usize { error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> $DIR/issue-54954.rs:1:24 | -LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait +LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait ... -LL | / const fn const_val<T: Sized>() -> usize { -LL | | -LL | | core::mem::size_of::<T>() -LL | | } - | |_____- `Tt::const_val` defined here +LL | const fn const_val<T: Sized>() -> usize { + | --------------------------------------- `Tt::const_val` defined here error: aborting due to 2 previous errors diff --git a/tests/ui/consts/issue-73976-monomorphic.rs b/tests/ui/consts/issue-73976-monomorphic.rs index 3bfdb397afb..5f364cd995e 100644 --- a/tests/ui/consts/issue-73976-monomorphic.rs +++ b/tests/ui/consts/issue-73976-monomorphic.rs @@ -8,6 +8,7 @@ #![feature(const_type_id)] #![feature(const_type_name)] #![feature(const_trait_impl)] +#![feature(const_cmp)] use std::any::{self, TypeId}; diff --git a/tests/ui/consts/issue-90870.rs b/tests/ui/consts/issue-90870.rs index f807ae75ee5..053763b9f89 100644 --- a/tests/ui/consts/issue-90870.rs +++ b/tests/ui/consts/issue-90870.rs @@ -3,9 +3,9 @@ #![allow(dead_code)] const fn f(a: &u8, b: &u8) -> bool { - //~^ HELP: add `#![feature(const_trait_impl)]` to the crate attributes to enable - //~| HELP: add `#![feature(const_trait_impl)]` to the crate attributes to enable - //~| HELP: add `#![feature(const_trait_impl)]` to the crate attributes to enable + //~^ HELP: add `#![feature(const_cmp)]` to the crate attributes to enable + //~| HELP: add `#![feature(const_cmp)]` to the crate attributes to enable + //~| HELP: add `#![feature(const_cmp)]` to the crate attributes to enable a == b //~^ ERROR: cannot call conditionally-const operator in constant functions //~| ERROR: `PartialEq` is not yet stable as a const trait diff --git a/tests/ui/consts/issue-90870.stderr b/tests/ui/consts/issue-90870.stderr index 8d6f21fd82f..60993f25864 100644 --- a/tests/ui/consts/issue-90870.stderr +++ b/tests/ui/consts/issue-90870.stderr @@ -19,9 +19,9 @@ error: `PartialEq` is not yet stable as a const trait LL | a == b | ^^^^^^ | -help: add `#![feature(const_trait_impl)]` to the crate attributes to enable +help: add `#![feature(const_cmp)]` to the crate attributes to enable | -LL + #![feature(const_trait_impl)] +LL + #![feature(const_cmp)] | error[E0658]: cannot call conditionally-const operator in constant functions @@ -45,9 +45,9 @@ error: `PartialEq` is not yet stable as a const trait LL | a == b | ^^^^^^ | -help: add `#![feature(const_trait_impl)]` to the crate attributes to enable +help: add `#![feature(const_cmp)]` to the crate attributes to enable | -LL + #![feature(const_trait_impl)] +LL + #![feature(const_cmp)] | error[E0658]: cannot call conditionally-const operator in constant functions @@ -71,9 +71,9 @@ error: `PartialEq` is not yet stable as a const trait LL | if l == r { | ^^^^^^ | -help: add `#![feature(const_trait_impl)]` to the crate attributes to enable +help: add `#![feature(const_cmp)]` to the crate attributes to enable | -LL + #![feature(const_trait_impl)] +LL + #![feature(const_cmp)] | error: aborting due to 6 previous errors diff --git a/tests/ui/typestate-multi-decl.rs b/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs index 3d0e79632bb..f62fae86219 100644 --- a/tests/ui/typestate-multi-decl.rs +++ b/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs @@ -1,3 +1,5 @@ +//! Checks basic multiple variable declaration using tuple destructuring in a `let` binding. + //@ run-pass pub fn main() { diff --git a/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr b/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr index 32be9db5317..5c0a437aad8 100644 --- a/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr +++ b/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr @@ -9,6 +9,7 @@ note: the lint level is defined here | LL | #![deny(unknown_or_malformed_diagnostic_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(unknown_diagnostic_attributes)]` implied by `#[deny(unknown_or_malformed_diagnostic_attributes)]` error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr index 8a478a5c733..9d1556ee0c1 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr @@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments LL | #[diagnostic::do_not_recommend(not_accepted)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` does not expect any arguments --> $DIR/does_not_acccept_args.rs:15:1 diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr index 8a478a5c733..9d1556ee0c1 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr @@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments LL | #[diagnostic::do_not_recommend(not_accepted)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` does not expect any arguments --> $DIR/does_not_acccept_args.rs:15:1 diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr index e348f0c8902..29ffbb5bf18 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr @@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(misplaced_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations --> $DIR/incorrect-locations.rs:11:1 diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr index e348f0c8902..29ffbb5bf18 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr @@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(misplaced_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations --> $DIR/incorrect-locations.rs:11:1 diff --git a/tests/ui/diagnostic_namespace/multiline_spans.rs b/tests/ui/diagnostic_namespace/multiline_spans.rs index 994dd9fd011..e0876b19df0 100644 --- a/tests/ui/diagnostic_namespace/multiline_spans.rs +++ b/tests/ui/diagnostic_namespace/multiline_spans.rs @@ -5,17 +5,17 @@ #[diagnostic::on_unimplemented(message = "here is a big \ multiline string \ {unknown}")] -//~^ ERROR there is no parameter `unknown` on trait `MultiLine` [unknown_or_malformed_diagnostic_attributes] +//~^ ERROR there is no parameter `unknown` on trait `MultiLine` [malformed_diagnostic_format_literals] pub trait MultiLine {} #[diagnostic::on_unimplemented(message = "here is a big \ multiline string {unknown}")] -//~^ ERROR there is no parameter `unknown` on trait `MultiLine2` [unknown_or_malformed_diagnostic_attributes] +//~^ ERROR there is no parameter `unknown` on trait `MultiLine2` [malformed_diagnostic_format_literals] pub trait MultiLine2 {} #[diagnostic::on_unimplemented(message = "here is a big \ multiline string {unknown}")] -//~^ ERROR there is no parameter `unknown` on trait `MultiLine3` [unknown_or_malformed_diagnostic_attributes] +//~^ ERROR there is no parameter `unknown` on trait `MultiLine3` [malformed_diagnostic_format_literals] pub trait MultiLine3 {} @@ -25,23 +25,23 @@ pub trait MultiLine3 {} \ \ multiline string {unknown}")] -//~^ ERROR there is no parameter `unknown` on trait `MultiLine4` [unknown_or_malformed_diagnostic_attributes] +//~^ ERROR there is no parameter `unknown` on trait `MultiLine4` [malformed_diagnostic_format_literals] pub trait MultiLine4 {} #[diagnostic::on_unimplemented(message = "here is a big \ multiline string \ {Self:+}")] -//~^ ERROR invalid format specifier [unknown_or_malformed_diagnostic_attributes] +//~^ ERROR invalid format specifier [malformed_diagnostic_format_literals] pub trait MultiLineFmt {} #[diagnostic::on_unimplemented(message = "here is a big \ multiline string {Self:X}")] -//~^ ERROR invalid format specifier [unknown_or_malformed_diagnostic_attributes] +//~^ ERROR invalid format specifier [malformed_diagnostic_format_literals] pub trait MultiLineFmt2 {} #[diagnostic::on_unimplemented(message = "here is a big \ multiline string {Self:#}")] -//~^ ERROR invalid format specifier [unknown_or_malformed_diagnostic_attributes] +//~^ ERROR invalid format specifier [malformed_diagnostic_format_literals] pub trait MultiLineFmt3 {} @@ -51,5 +51,5 @@ pub trait MultiLineFmt3 {} \ \ multiline string {Self:?}")] -//~^ ERROR invalid format specifier [unknown_or_malformed_diagnostic_attributes] +//~^ ERROR invalid format specifier [malformed_diagnostic_format_literals] pub trait MultiLineFmt4 {} diff --git a/tests/ui/diagnostic_namespace/multiline_spans.stderr b/tests/ui/diagnostic_namespace/multiline_spans.stderr index 894bfe3d90a..0e4bb864b96 100644 --- a/tests/ui/diagnostic_namespace/multiline_spans.stderr +++ b/tests/ui/diagnostic_namespace/multiline_spans.stderr @@ -10,6 +10,7 @@ note: the lint level is defined here | LL | #![deny(unknown_or_malformed_diagnostic_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(malformed_diagnostic_format_literals)]` implied by `#[deny(unknown_or_malformed_diagnostic_attributes)]` error: there is no parameter `unknown` on trait `MultiLine2` --> $DIR/multiline_spans.rs:12:60 diff --git a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr index 753077b365e..4f9b7ba2bcf 100644 --- a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr +++ b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr @@ -4,7 +4,7 @@ warning: unknown diagnostic attribute LL | #[diagnostic::non_existing_attribute] | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(unknown_diagnostic_attributes)]` on by default warning: unknown diagnostic attribute --> $DIR/non_existing_attributes_accepted.rs:8:15 diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs index 4762d9e793f..82c2db7e26d 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs +++ b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs @@ -12,8 +12,8 @@ trait ImportantTrait2 {} #[diagnostic::on_unimplemented(message = "Test {1:}")] //~^WARN positional format arguments are not allowed here //~|WARN positional format arguments are not allowed here -//~|WARN invalid format specifier [unknown_or_malformed_diagnostic_attributes] -//~|WARN invalid format specifier [unknown_or_malformed_diagnostic_attributes] +//~|WARN invalid format specifier [malformed_diagnostic_format_literals] +//~|WARN invalid format specifier [malformed_diagnostic_format_literals] trait ImportantTrait3 {} #[diagnostic::on_unimplemented(message = "Test {Self:123}")] @@ -22,13 +22,13 @@ trait ImportantTrait3 {} trait ImportantTrait4 {} #[diagnostic::on_unimplemented(message = "Test {Self:!}")] -//~^WARN invalid format specifier [unknown_or_malformed_diagnostic_attributes] -//~|WARN invalid format specifier [unknown_or_malformed_diagnostic_attributes] +//~^WARN invalid format specifier [malformed_diagnostic_format_literals] +//~|WARN invalid format specifier [malformed_diagnostic_format_literals] trait ImportantTrait5 {} #[diagnostic::on_unimplemented(message = "Test {Self:}")] -//~^WARN invalid format specifier [unknown_or_malformed_diagnostic_attributes] -//~|WARN invalid format specifier [unknown_or_malformed_diagnostic_attributes] +//~^WARN invalid format specifier [malformed_diagnostic_format_literals] +//~|WARN invalid format specifier [malformed_diagnostic_format_literals] trait ImportantTrait6 {} diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr index 2670d0630f7..5002122f8b7 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr @@ -4,7 +4,7 @@ warning: unmatched `}` found LL | #[diagnostic::on_unimplemented(message = "{{Test } thing")] | ^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(malformed_diagnostic_format_literals)]` on by default warning: positional format arguments are not allowed here --> $DIR/broken_format.rs:7:49 diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr index 8dace7d9052..42f4bc0d8b0 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr @@ -4,7 +4,7 @@ warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definiti LL | #[diagnostic::on_unimplemented(message = "Not allowed to apply it on a impl")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(misplaced_diagnostic_attributes)]` on by default warning: malformed `on_unimplemented` attribute --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:6:5 @@ -13,6 +13,7 @@ LL | on(Self = "&str"), | ^^^^^^^^^^^^^^^^^ invalid option found here | = help: only `message`, `note` and `label` are allowed as options + = note: `#[warn(malformed_diagnostic_attributes)]` on by default warning: malformed `on_unimplemented` attribute --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:12:5 @@ -45,6 +46,7 @@ LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}", | ^^^^^^^^^^^^^^^ | = help: expect either a generic argument name or `{Self}` as format argument + = note: `#[warn(malformed_diagnostic_format_literals)]` on by default warning: there is no parameter `direct` on trait `Baz` --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:34 diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr index 80790dc3f79..85d74fb8955 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr @@ -4,7 +4,7 @@ warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definiti LL | #[diagnostic::on_unimplemented(message = "Baz")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(misplaced_diagnostic_attributes)]` on by default warning: malformed `on_unimplemented` attribute --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:3:32 @@ -13,6 +13,7 @@ LL | #[diagnostic::on_unimplemented(unsupported = "foo")] | ^^^^^^^^^^^^^^^^^^^ invalid option found here | = help: only `message`, `note` and `label` are allowed as options + = note: `#[warn(malformed_diagnostic_attributes)]` on by default warning: malformed `on_unimplemented` attribute --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:12:50 @@ -61,6 +62,7 @@ LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")] | ^^^^^^^^^^^^ | = help: expect either a generic argument name or `{Self}` as format argument + = note: `#[warn(malformed_diagnostic_format_literals)]` on by default warning: malformed `on_unimplemented` attribute --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:3:32 diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr index e00846da77b..86fe75a62de 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr @@ -5,7 +5,7 @@ LL | if(Self = "()"), | ^^^^^^^^^^^^^^^ invalid option found here | = help: only `message`, `note` and `label` are allowed as options - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(malformed_diagnostic_attributes)]` on by default warning: `message` is ignored due to previous definition of `message` --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:10:32 diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/on_impl_trait.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/on_impl_trait.stderr index 5eee6478922..69433f91543 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/on_impl_trait.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/on_impl_trait.stderr @@ -4,7 +4,7 @@ warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definiti LL | #[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "blah")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(misplaced_diagnostic_attributes)]` on by default error[E0277]: the trait bound `{integer}: Alias` is not satisfied --> $DIR/on_impl_trait.rs:16:9 diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr index feafe2cee76..d2e121b61a6 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr @@ -7,7 +7,7 @@ LL | message = "first message", LL | message = "second message", | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `message` is already declared here | - = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + = note: `#[warn(malformed_diagnostic_attributes)]` on by default warning: `label` is ignored due to previous definition of `label` --> $DIR/report_warning_on_duplicated_options.rs:11:5 diff --git a/tests/ui/diagnostic_namespace/suggest_typos.rs b/tests/ui/diagnostic_namespace/suggest_typos.rs index 8d1dc6f59da..37a1c79bb08 100644 --- a/tests/ui/diagnostic_namespace/suggest_typos.rs +++ b/tests/ui/diagnostic_namespace/suggest_typos.rs @@ -1,5 +1,5 @@ //@ reference: attributes.diagnostic.namespace.unknown-invalid-syntax -#![deny(unknown_or_malformed_diagnostic_attributes)] +#![deny(unknown_diagnostic_attributes)] #[diagnostic::onunimplemented] //~^ERROR unknown diagnostic attribute diff --git a/tests/ui/diagnostic_namespace/suggest_typos.stderr b/tests/ui/diagnostic_namespace/suggest_typos.stderr index 1f19fd4bbcf..c1177945ea6 100644 --- a/tests/ui/diagnostic_namespace/suggest_typos.stderr +++ b/tests/ui/diagnostic_namespace/suggest_typos.stderr @@ -7,8 +7,8 @@ LL | #[diagnostic::onunimplemented] note: the lint level is defined here --> $DIR/suggest_typos.rs:2:9 | -LL | #![deny(unknown_or_malformed_diagnostic_attributes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(unknown_diagnostic_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: an attribute with a similar name exists | LL | #[diagnostic::on_unimplemented] diff --git a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr index 927f9e842e6..12965800a02 100644 --- a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr +++ b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr @@ -18,7 +18,7 @@ LL + fn setup() -> Determine { Set } LL - fn setup() -> Set { Set } LL + fn setup() -> PutDown { Set } | - and 3 other candidates + = and 3 other candidates error[E0425]: cannot find value `Set` in this scope --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:21 @@ -36,7 +36,7 @@ LL + use Determine::Set; | LL + use PutDown::Set; | - and 3 other candidates + = and 3 other candidates error: aborting due to 2 previous errors diff --git a/tests/ui/drop/box-drop-unused-value-statement-regression.rs b/tests/ui/drop/box-drop-unused-value-statement-regression.rs new file mode 100644 index 00000000000..43865e08444 --- /dev/null +++ b/tests/ui/drop/box-drop-unused-value-statement-regression.rs @@ -0,0 +1,12 @@ +//! Regression test for a crash caused by an "unsused move" +//! (specifically, a variable bound to a `Box` used as a statement) +//! leading to incorrect memory zero-filling after drop. +//! +//! Regression test for <https://github.com/rust-lang/rust/issues/3878>. + +//@ run-pass + +pub fn main() { + let y: Box<_> = Box::new(1); + drop(y); +} diff --git a/tests/ui/error-codes/E0790.stderr b/tests/ui/error-codes/E0790.stderr index 106554b2425..93c43020768 100644 --- a/tests/ui/error-codes/E0790.stderr +++ b/tests/ui/error-codes/E0790.stderr @@ -16,7 +16,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin --> $DIR/E0790.rs:21:17 | LL | const MY_ASSOC_CONST: (); - | ------------------------- `MyTrait::MY_ASSOC_CONST` defined here + | ------------------------ `MyTrait::MY_ASSOC_CONST` defined here ... LL | let _ = MyTrait::MY_ASSOC_CONST; | ^^^^^^^^^^^^^^^^^^^^^^^ cannot refer to the associated constant of trait @@ -44,7 +44,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin --> $DIR/E0790.rs:30:13 | LL | const MY_ASSOC_CONST: (); - | ------------------------- `MyTrait::MY_ASSOC_CONST` defined here + | ------------------------ `MyTrait::MY_ASSOC_CONST` defined here ... LL | let _ = inner::MyTrait::MY_ASSOC_CONST; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot refer to the associated constant of trait diff --git a/tests/ui/weird-exprs.rs b/tests/ui/expr/syntax-edge-cases-lint-clean.rs index 7db92d46067..7db92d46067 100644 --- a/tests/ui/weird-exprs.rs +++ b/tests/ui/expr/syntax-edge-cases-lint-clean.rs diff --git a/tests/ui/extern/unsized-extern-derefmove.stderr b/tests/ui/extern/unsized-extern-derefmove.stderr index d6be76a9d62..a9efc2e66e3 100644 --- a/tests/ui/extern/unsized-extern-derefmove.stderr +++ b/tests/ui/extern/unsized-extern-derefmove.stderr @@ -21,10 +21,10 @@ note: required by a bound in `Box::<T>::from_raw` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL help: consider borrowing here | -LL | Box::from_raw(&0 as *mut _) - | + -LL | Box::from_raw(&mut 0 as *mut _) - | ++++ +LL | Box::from_raw(&(0 as *mut _)) + | ++ + +LL | Box::from_raw(&mut (0 as *mut _)) + | ++++++ + error[E0277]: the size for values of type `Device` cannot be known --> $DIR/unsized-extern-derefmove.rs:11:5 diff --git a/tests/ui/feature-gates/feature-gate-async-drop.stderr b/tests/ui/feature-gates/feature-gate-async-drop.stderr index e795c3a3422..80f6228a16f 100644 --- a/tests/ui/feature-gates/feature-gate-async-drop.stderr +++ b/tests/ui/feature-gates/feature-gate-async-drop.stderr @@ -12,7 +12,7 @@ error[E0658]: use of unstable library feature `async_drop` --> $DIR/feature-gate-async-drop.rs:13:5 | LL | async fn drop(self: Pin<&mut Self>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #126482 <https://github.com/rust-lang/rust/issues/126482> for more information = help: add `#![feature(async_drop)]` to the crate attributes to enable diff --git a/tests/ui/generic-associated-types/missing-bounds.fixed b/tests/ui/generic-associated-types/missing-bounds.fixed index 703d3c1e0fb..15cdd44d7f1 100644 --- a/tests/ui/generic-associated-types/missing-bounds.fixed +++ b/tests/ui/generic-associated-types/missing-bounds.fixed @@ -1,5 +1,7 @@ //@ run-rustfix +#![allow(dead_code)] + use std::ops::Add; struct A<B>(B); diff --git a/tests/ui/generic-associated-types/missing-bounds.rs b/tests/ui/generic-associated-types/missing-bounds.rs index f40b4228873..dad111c8c15 100644 --- a/tests/ui/generic-associated-types/missing-bounds.rs +++ b/tests/ui/generic-associated-types/missing-bounds.rs @@ -1,5 +1,7 @@ //@ run-rustfix +#![allow(dead_code)] + use std::ops::Add; struct A<B>(B); diff --git a/tests/ui/generic-associated-types/missing-bounds.stderr b/tests/ui/generic-associated-types/missing-bounds.stderr index 13e4d249876..97b88c26e3b 100644 --- a/tests/ui/generic-associated-types/missing-bounds.stderr +++ b/tests/ui/generic-associated-types/missing-bounds.stderr @@ -1,5 +1,5 @@ error: equality constraints are not yet supported in `where` clauses - --> $DIR/missing-bounds.rs:37:33 + --> $DIR/missing-bounds.rs:39:33 | LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B { | ^^^^^^^^^^^^^^^^^^^^^^ not supported @@ -12,7 +12,7 @@ LL + impl<B: Add> Add for E<B> where B: Add<Output = B> { | error[E0308]: mismatched types - --> $DIR/missing-bounds.rs:11:11 + --> $DIR/missing-bounds.rs:13:11 | LL | impl<B> Add for A<B> where B: Add { | - expected this type parameter @@ -25,14 +25,14 @@ LL | A(self.0 + rhs.0) = note: expected type parameter `B` found associated type `<B as Add>::Output` help: the type constructed contains `<B as Add>::Output` due to the type of the argument passed - --> $DIR/missing-bounds.rs:11:9 + --> $DIR/missing-bounds.rs:13:9 | LL | A(self.0 + rhs.0) | ^^--------------^ | | | this argument influences the type of `A` note: tuple struct defined here - --> $DIR/missing-bounds.rs:5:8 + --> $DIR/missing-bounds.rs:7:8 | LL | struct A<B>(B); | ^ @@ -42,7 +42,7 @@ LL | impl<B> Add for A<B> where B: Add<Output = B> { | ++++++++++++ error[E0308]: mismatched types - --> $DIR/missing-bounds.rs:21:14 + --> $DIR/missing-bounds.rs:23:14 | LL | impl<B: Add> Add for C<B> { | - expected this type parameter @@ -55,7 +55,7 @@ LL | Self(self.0 + rhs.0) = note: expected type parameter `B` found associated type `<B as Add>::Output` note: tuple struct defined here - --> $DIR/missing-bounds.rs:15:8 + --> $DIR/missing-bounds.rs:17:8 | LL | struct C<B>(B); | ^ @@ -65,7 +65,7 @@ LL | impl<B: Add<Output = B>> Add for C<B> { | ++++++++++++ error[E0369]: cannot add `B` to `B` - --> $DIR/missing-bounds.rs:31:21 + --> $DIR/missing-bounds.rs:33:21 | LL | Self(self.0 + rhs.0) | ------ ^ ----- B @@ -78,7 +78,7 @@ LL | impl<B: std::ops::Add<Output = B>> Add for D<B> { | +++++++++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/missing-bounds.rs:42:14 + --> $DIR/missing-bounds.rs:44:14 | LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B { | - expected this type parameter @@ -91,7 +91,7 @@ LL | Self(self.0 + rhs.0) = note: expected type parameter `B` found associated type `<B as Add>::Output` note: tuple struct defined here - --> $DIR/missing-bounds.rs:35:8 + --> $DIR/missing-bounds.rs:37:8 | LL | struct E<B>(B); | ^ diff --git a/tests/ui/generics/export-name-on-generics.stderr b/tests/ui/generics/export-name-on-generics.stderr index 7bc7b8ca559..e08b2b1c8f3 100644 --- a/tests/ui/generics/export-name-on-generics.stderr +++ b/tests/ui/generics/export-name-on-generics.stderr @@ -4,7 +4,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "foo"] | ---------------------- help: remove this attribute LL | pub fn foo<T>() {} - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/export-name-on-generics.rs:3:9 @@ -18,7 +18,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "bar"] | ---------------------- help: remove this attribute LL | pub extern "C" fn bar<T>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:21:5 @@ -26,7 +26,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "foo"] | ---------------------- help: remove this attribute LL | pub fn foo<T>() {} - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:24:5 @@ -34,7 +34,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "bar"] | ---------------------- help: remove this attribute LL | pub extern "C" fn bar<T>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:42:5 @@ -42,7 +42,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "foo"] | ---------------------- help: remove this attribute LL | fn foo<T>() {} - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:45:5 @@ -50,7 +50,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "bar"] | ---------------------- help: remove this attribute LL | extern "C" fn bar<T>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:64:5 @@ -58,7 +58,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "foo"] | ---------------------- help: remove this attribute LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:67:5 @@ -66,7 +66,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "foo2"] | ----------------------- help: remove this attribute LL | fn foo2<U>() {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:70:5 @@ -74,7 +74,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "baz"] | ---------------------- help: remove this attribute LL | extern "C" fn bar() {} - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:73:5 @@ -82,7 +82,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "baz"] | ---------------------- help: remove this attribute LL | fn baz(x: &i32) -> &i32 { x } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:76:5 @@ -90,7 +90,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "qux"] | ---------------------- help: remove this attribute LL | fn qux<'a>(x: &'a i32) -> &i32 { x } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:83:5 @@ -98,7 +98,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "foo"] | ---------------------- help: remove this attribute LL | pub fn foo() {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:86:5 @@ -106,7 +106,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "bar"] | ---------------------- help: remove this attribute LL | pub extern "C" fn bar() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:89:5 @@ -114,7 +114,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "baz"] | ---------------------- help: remove this attribute LL | pub fn baz<U>() {} - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:105:5 @@ -122,7 +122,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "foo"] | ---------------------- help: remove this attribute LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:108:5 @@ -130,7 +130,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "bar"] | ---------------------- help: remove this attribute LL | extern "C" fn bar() {} - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/export-name-on-generics.rs:111:5 @@ -138,7 +138,7 @@ error: functions generic over types or consts must be mangled LL | #[export_name = "baz"] | ---------------------- help: remove this attribute LL | fn baz<U>() {} - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ error: aborting due to 17 previous errors diff --git a/tests/ui/generics/generic-enum-errors.rs b/tests/ui/generics/generic-enum-errors.rs new file mode 100644 index 00000000000..111f5635168 --- /dev/null +++ b/tests/ui/generics/generic-enum-errors.rs @@ -0,0 +1,15 @@ +//! This test checks that unused generics are rejected by compiler + +enum Quux<T> { + //~^ ERROR: parameter `T` is never used + Bar, +} + +fn foo(c: Quux) { + //~^ ERROR missing generics for enum `Quux` + assert!((false)); +} + +fn main() { + panic!(); +} diff --git a/tests/ui/tag-type-args.stderr b/tests/ui/generics/generic-enum-errors.stderr index def13832e1a..47a8badbd5d 100644 --- a/tests/ui/tag-type-args.stderr +++ b/tests/ui/generics/generic-enum-errors.stderr @@ -1,26 +1,26 @@ error[E0392]: type parameter `T` is never used - --> $DIR/tag-type-args.rs:1:11 + --> $DIR/generic-enum-errors.rs:3:11 | -LL | enum Quux<T> { Bar } +LL | enum Quux<T> { | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error[E0107]: missing generics for enum `Quux` - --> $DIR/tag-type-args.rs:4:11 + --> $DIR/generic-enum-errors.rs:8:11 | -LL | fn foo(c: Quux) { assert!((false)); } +LL | fn foo(c: Quux) { | ^^^^ expected 1 generic argument | note: enum defined here, with 1 generic parameter: `T` - --> $DIR/tag-type-args.rs:1:6 + --> $DIR/generic-enum-errors.rs:3:6 | -LL | enum Quux<T> { Bar } +LL | enum Quux<T> { | ^^^^ - help: add missing generic argument | -LL | fn foo(c: Quux<T>) { assert!((false)); } +LL | fn foo(c: Quux<T>) { | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/generics/generic-no-mangle.stderr b/tests/ui/generics/generic-no-mangle.stderr index adfddbe9ca7..39fbe4dd76d 100644 --- a/tests/ui/generics/generic-no-mangle.stderr +++ b/tests/ui/generics/generic-no-mangle.stderr @@ -4,7 +4,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | pub fn foo<T>() {} - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/generic-no-mangle.rs:3:9 @@ -18,7 +18,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | pub extern "C" fn bar<T>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:21:5 @@ -26,7 +26,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | pub fn foo<T>() {} - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:24:5 @@ -34,7 +34,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | pub extern "C" fn bar<T>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:42:5 @@ -42,7 +42,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | fn foo<T>() {} - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:45:5 @@ -50,7 +50,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | extern "C" fn bar<T>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:64:5 @@ -58,7 +58,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:67:5 @@ -66,7 +66,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | fn foo2<U>() {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:70:5 @@ -74,7 +74,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | extern "C" fn bar() {} - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:73:5 @@ -82,7 +82,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | fn baz(x: &i32) -> &i32 { x } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:76:5 @@ -90,7 +90,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | fn qux<'a>(x: &'a i32) -> &i32 { x } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:83:5 @@ -98,7 +98,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | pub fn foo() {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:86:5 @@ -106,7 +106,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | pub extern "C" fn bar() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:89:5 @@ -114,7 +114,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | pub fn baz<U>() {} - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:105:5 @@ -122,7 +122,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:108:5 @@ -130,7 +130,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | extern "C" fn bar() {} - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled --> $DIR/generic-no-mangle.rs:111:5 @@ -138,7 +138,7 @@ error: functions generic over types or consts must be mangled LL | #[no_mangle] | ------------ help: remove this attribute LL | fn baz<U>() {} - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ error: aborting due to 17 previous errors diff --git a/tests/ui/wrong-hashset-issue-42918.rs b/tests/ui/hashmap/hashset-enum-variant.rs index 5795cc527cf..39a59d3a39b 100644 --- a/tests/ui/wrong-hashset-issue-42918.rs +++ b/tests/ui/hashmap/hashset-enum-variant.rs @@ -1,26 +1,27 @@ +//! Check for correct initialization of `HashSet` with enums. This is a regression test for a +//! codegen bug that caused the `HashSet` to appear as if it contained one of each enum variant. +//! +//! Regression test for <https://github.com/rust-lang/rust/issues/42918> + //@ run-pass -// -#![allow(dead_code)] //@ compile-flags: -O +#![allow(dead_code)] + use std::collections::HashSet; #[derive(PartialEq, Debug, Hash, Eq, Clone, PartialOrd, Ord)] enum MyEnum { E0, - E1, - E2, E3, E4, - E5, E6, E7, } - fn main() { use MyEnum::*; let s: HashSet<_> = [E4, E1].iter().cloned().collect(); diff --git a/tests/ui/impl-trait/call_method_without_import.no_import.stderr b/tests/ui/impl-trait/call_method_without_import.no_import.stderr index 72982b695bb..e59409ea27e 100644 --- a/tests/ui/impl-trait/call_method_without_import.no_import.stderr +++ b/tests/ui/impl-trait/call_method_without_import.no_import.stderr @@ -30,7 +30,7 @@ LL + use std::fmt::Display; | LL + use std::fmt::LowerExp; | - and 5 other candidates + = and 5 other candidates error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr index 856c92217b9..4c429624e0b 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr +++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr @@ -4,9 +4,12 @@ error[E0308]: mismatched types LL | async fn woopsie_async(&self) -> String { | ------ expected `String` because of return type LL | 42 - | ^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found integer + | ^^ expected `String`, found integer + | +help: try using a conversion method + | +LL | 42.to_string() + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs index e3dc22c1992..9c9cef24a96 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs +++ b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs @@ -43,4 +43,17 @@ trait Qux { //~^^^^ ERROR: the name `foo` is defined multiple times } +trait T0<T> { + type Target; +} +trait T1<T> {} + +trait X { + fn a() -> impl T0<(), Target = impl T1<()>>; + fn a() -> impl T0<(), Target = impl T1<()>>; + //~^ ERROR the name `a` is defined multiple times + fn a() -> impl T0<(), Target = impl T1<()>>; + //~^ ERROR the name `a` is defined multiple times +} + fn main() {} diff --git a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr index f4e73dc1798..8356f94f2aa 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr +++ b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr @@ -44,6 +44,27 @@ LL | | >; | = note: `foo` must be defined only once in the value namespace of this trait -error: aborting due to 4 previous errors +error[E0428]: the name `a` is defined multiple times + --> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:53:5 + | +LL | fn a() -> impl T0<(), Target = impl T1<()>>; + | -------------------------------------------- previous definition of the value `a` here +LL | fn a() -> impl T0<(), Target = impl T1<()>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `a` redefined here + | + = note: `a` must be defined only once in the value namespace of this trait + +error[E0428]: the name `a` is defined multiple times + --> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:55:5 + | +LL | fn a() -> impl T0<(), Target = impl T1<()>>; + | -------------------------------------------- previous definition of the value `a` here +... +LL | fn a() -> impl T0<(), Target = impl T1<()>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `a` redefined here + | + = note: `a` must be defined only once in the value namespace of this trait + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0428`. diff --git a/tests/ui/imports/issue-56125.stderr b/tests/ui/imports/issue-56125.stderr index 81336d51df4..371130facf9 100644 --- a/tests/ui/imports/issue-56125.stderr +++ b/tests/ui/imports/issue-56125.stderr @@ -18,7 +18,7 @@ LL + use ::issue_56125::issue_56125; LL - use empty::issue_56125; LL + use ::issue_56125::last_segment::issue_56125; | - and 1 other candidate + = and 1 other candidate error[E0659]: `issue_56125` is ambiguous --> $DIR/issue-56125.rs:6:9 diff --git a/tests/ui/inference/deref-suggestion.stderr b/tests/ui/inference/deref-suggestion.stderr index 8ccd28198af..027902a9f31 100644 --- a/tests/ui/inference/deref-suggestion.stderr +++ b/tests/ui/inference/deref-suggestion.stderr @@ -2,9 +2,8 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:8:9 | LL | foo(s); - | --- ^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found `&String` + | --- ^ expected `String`, found `&String` + | | | arguments to this function are incorrect | note: function defined here @@ -12,6 +11,10 @@ note: function defined here | LL | fn foo(_: String) {} | ^^^ --------- +help: try using a conversion method + | +LL | foo(s.to_string()); + | ++++++++++++ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:14:10 diff --git a/tests/ui/write-fmt-errors.rs b/tests/ui/io-checks/write-macro-error.rs index b48fa3f11cc..857ea0024e1 100644 --- a/tests/ui/write-fmt-errors.rs +++ b/tests/ui/io-checks/write-macro-error.rs @@ -1,3 +1,6 @@ +//! Tests that errors from both the writer (`Write::write`) and formatter (`Display::fmt`) +//! are correctly propagated: writer errors return `Err`, formatter errors cause panics. + //@ run-pass //@ needs-unwind @@ -24,7 +27,9 @@ impl Write for ErrorWriter { Err(Error::new(WRITER_ERROR, "not connected")) } - fn flush(&mut self) -> io::Result<()> { Ok(()) } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } } fn main() { @@ -37,7 +42,8 @@ fn main() { let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); assert!( err.contains("formatting trait implementation returned an error"), - "unexpected panic: {}", err + "unexpected panic: {}", + err ); // Writer error when there's some string before the first `{}` @@ -50,6 +56,7 @@ fn main() { let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); assert!( err.contains("formatting trait implementation returned an error"), - "unexpected panic: {}", err + "unexpected panic: {}", + err ); } diff --git a/tests/ui/lang-items/lang-item-unknown-definition-error.rs b/tests/ui/lang-items/lang-item-unknown-definition-error.rs new file mode 100644 index 00000000000..22812128c2d --- /dev/null +++ b/tests/ui/lang-items/lang-item-unknown-definition-error.rs @@ -0,0 +1,12 @@ +//! Checks that compiler prevernt attempting to define an unrecognized or unknown lang item + +#![allow(unused)] +#![feature(lang_items)] + +#[lang = "foo"] +fn bar() -> ! { + //~^^ ERROR definition of an unknown lang item: `foo` + loop {} +} + +fn main() {} diff --git a/tests/ui/unknown-language-item.stderr b/tests/ui/lang-items/lang-item-unknown-definition-error.stderr index 832f1342418..3b939757ac2 100644 --- a/tests/ui/unknown-language-item.stderr +++ b/tests/ui/lang-items/lang-item-unknown-definition-error.stderr @@ -1,5 +1,5 @@ error[E0522]: definition of an unknown lang item: `foo` - --> $DIR/unknown-language-item.rs:4:1 + --> $DIR/lang-item-unknown-definition-error.rs:6:1 | LL | #[lang = "foo"] | ^^^^^^^^^^^^^^^ definition of unknown lang item `foo` diff --git a/tests/ui/lazy-type-alias/deep-expansion.rs b/tests/ui/lazy-type-alias/deep-expansion.rs new file mode 100644 index 00000000000..c4461abdb81 --- /dev/null +++ b/tests/ui/lazy-type-alias/deep-expansion.rs @@ -0,0 +1,20 @@ +// In several type analysis passes we employ a specialized expansion procedure. +// This procedure used to incorrectly track expansion depth (growing much faster +// than normalization depth) resulting in its internal assertion triggering. +// +// issue: <https://github.com/rust-lang/rust/issues/142419> +//@ check-pass +#![feature(lazy_type_alias)] +#![expect(incomplete_features)] + +type T0 = (T1, T1, T1, T1); +type T1 = (T2, T2, T2, T2); +type T2 = (T3, T3, T3, T3); +type T3 = (T4, T4, T4, T4); +type T4 = (T5, T5, T5, T5); +type T5 = (T6, T6, T6, T6); +type T6 = (T7, T7, T7, T7); +type T7 = (); + +fn accept(_: T0) {} +fn main() {} diff --git a/tests/ui/type-id-higher-rank-2.rs b/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs index 7b0c7b53940..f9f38ee532d 100644 --- a/tests/ui/type-id-higher-rank-2.rs +++ b/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs @@ -1,11 +1,15 @@ +//! Checks that `std::any::Any` cannot be used to circumvent lifetime rules +//! with higher-rank types. + //@ run-pass -// Test that we can't ignore lifetimes by going through Any. use std::any::Any; struct Foo<'a>(&'a str); -fn good(s: &String) -> Foo<'_> { Foo(s) } +fn good(s: &String) -> Foo<'_> { + Foo(s) +} fn bad1(s: String) -> Option<&'static str> { let a: Box<dyn Any> = Box::new(good as fn(&String) -> Foo); @@ -17,7 +21,9 @@ trait AsStr<'a, 'b> { } impl<'a> AsStr<'a, 'a> for String { - fn get(&'a self) -> &'a str { self } + fn get(&'a self) -> &'a str { + self + } } fn bad2(s: String) -> Option<&'static str> { diff --git a/tests/ui/type_length_limit.rs b/tests/ui/limits/type-length-limit-enforcement.rs index 87f5ffd76d7..3b34d6eb5c8 100644 --- a/tests/ui/type_length_limit.rs +++ b/tests/ui/limits/type-length-limit-enforcement.rs @@ -1,17 +1,19 @@ -//@ build-fail +//~ ERROR reached the type-length limit + +//! Checks the enforcement of the type-length limit +//! and its configurability via `#![type_length_limit]`. + //@ compile-flags: -Copt-level=0 -Zenforce-type-length-limit -//~^^ ERROR reached the type-length limit -// Test that the type length limit can be changed. -// The exact type depends on optimizations, so disable them. +//@ build-fail #![allow(dead_code)] -#![type_length_limit="8"] +#![type_length_limit = "8"] macro_rules! link { ($id:ident, $t:ty) => { pub type $id = ($t, $t, $t); - } + }; } link! { A1, B1 } @@ -26,7 +28,7 @@ link! { D, E } link! { E, F } link! { F, G<Option<i32>, Option<i32>> } -pub struct G<T, K>(std::marker::PhantomData::<(T, K)>); +pub struct G<T, K>(std::marker::PhantomData<(T, K)>); fn main() { drop::<Option<A>>(None); diff --git a/tests/ui/type_length_limit.stderr b/tests/ui/limits/type-length-limit-enforcement.stderr index 198d133c08c..516230ae832 100644 --- a/tests/ui/type_length_limit.stderr +++ b/tests/ui/limits/type-length-limit-enforcement.stderr @@ -1,11 +1,11 @@ error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((..., ..., ...), ..., ...), ..., ...), ..., ...)>>` - --> $DIR/type_length_limit.rs:32:5 + --> $DIR/type-length-limit-enforcement.rs:34:5 | LL | drop::<Option<A>>(None); | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate - = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/type-length-limit-enforcement.long-type.txt' error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` | diff --git a/tests/ui/linking/export-executable-symbols.rs b/tests/ui/linking/export-executable-symbols.rs new file mode 100644 index 00000000000..aea5527b6a1 --- /dev/null +++ b/tests/ui/linking/export-executable-symbols.rs @@ -0,0 +1,30 @@ +//@ run-pass +//@ only-linux +//@ only-gnu +//@ compile-flags: -Zexport-executable-symbols +//@ edition: 2024 + +// Regression test for <https://github.com/rust-lang/rust/issues/101610>. + +#![feature(rustc_private)] + +extern crate libc; + +#[unsafe(no_mangle)] +fn hack() -> u64 { + 998244353 +} + +fn main() { + unsafe { + let handle = libc::dlopen(std::ptr::null(), libc::RTLD_NOW); + let ptr = libc::dlsym(handle, c"hack".as_ptr()); + let ptr: Option<unsafe fn() -> u64> = std::mem::transmute(ptr); + if let Some(f) = ptr { + assert!(f() == 998244353); + println!("symbol `hack` is found successfully"); + } else { + panic!("symbol `hack` is not found"); + } + } +} diff --git a/tests/ui/lint/dead-code/unused-trait-with-assoc-const.rs b/tests/ui/lint/dead-code/unused-trait-with-assoc-const.rs new file mode 100644 index 00000000000..8259e932c64 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-trait-with-assoc-const.rs @@ -0,0 +1,13 @@ +#![deny(dead_code)] + +trait Tr { //~ ERROR trait `Tr` is never used + const I: Self; +} + +struct Foo; //~ ERROR struct `Foo` is never constructed + +impl Tr for Foo { + const I: Self = Foo; +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/unused-trait-with-assoc-const.stderr b/tests/ui/lint/dead-code/unused-trait-with-assoc-const.stderr new file mode 100644 index 00000000000..ec894210f71 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-trait-with-assoc-const.stderr @@ -0,0 +1,20 @@ +error: trait `Tr` is never used + --> $DIR/unused-trait-with-assoc-const.rs:3:7 + | +LL | trait Tr { + | ^^ + | +note: the lint level is defined here + --> $DIR/unused-trait-with-assoc-const.rs:1:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: struct `Foo` is never constructed + --> $DIR/unused-trait-with-assoc-const.rs:7:8 + | +LL | struct Foo; + | ^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.rs b/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.rs new file mode 100644 index 00000000000..e8116d83ebf --- /dev/null +++ b/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.rs @@ -0,0 +1,11 @@ +#![deny(dead_code)] + +struct T1; //~ ERROR struct `T1` is never constructed + +trait Foo { type Unused; } //~ ERROR trait `Foo` is never used +impl Foo for T1 { type Unused = Self; } + +pub trait Bar { type Used; } +impl Bar for T1 { type Used = Self; } + +fn main() {} diff --git a/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.stderr b/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.stderr new file mode 100644 index 00000000000..ab73c640634 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-trait-with-assoc-ty.stderr @@ -0,0 +1,20 @@ +error: struct `T1` is never constructed + --> $DIR/unused-trait-with-assoc-ty.rs:3:8 + | +LL | struct T1; + | ^^ + | +note: the lint level is defined here + --> $DIR/unused-trait-with-assoc-ty.rs:1:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: trait `Foo` is never used + --> $DIR/unused-trait-with-assoc-ty.rs:5:7 + | +LL | trait Foo { type Unused; } + | ^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lint/lint-stability.stderr b/tests/ui/lint/lint-stability.stderr index a22fce70a4a..fd57908a77b 100644 --- a/tests/ui/lint/lint-stability.stderr +++ b/tests/ui/lint/lint-stability.stderr @@ -290,7 +290,7 @@ error[E0658]: use of unstable library feature `unstable_test_feature` --> $DIR/lint-stability.rs:179:9 | LL | fn trait_unstable(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/lint/suggestions.stderr b/tests/ui/lint/suggestions.stderr index a4871ead74b..c35e92f5980 100644 --- a/tests/ui/lint/suggestions.stderr +++ b/tests/ui/lint/suggestions.stderr @@ -65,7 +65,7 @@ LL | #[no_mangle] | ------------ help: remove this attribute LL | LL | pub fn defiant<T>(_t: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(no_mangle_generic_items)]` on by default @@ -89,7 +89,7 @@ warning: functions generic over types or consts must be mangled --> $DIR/suggestions.rs:26:18 | LL | #[no_mangle] pub fn val_jean<T>() {} - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ + | ------------ ^^^^^^^^^^^^^^^^^^^^ | | | help: remove this attribute @@ -105,7 +105,7 @@ warning: functions generic over types or consts must be mangled --> $DIR/suggestions.rs:35:18 | LL | #[no_mangle] pub(crate) fn crossfield<T>() {} - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | help: remove this attribute diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr index 0d4304e2e2e..558c2260fce 100644 --- a/tests/ui/lint/use_suggestion_json.stderr +++ b/tests/ui/lint/use_suggestion_json.stderr @@ -419,7 +419,7 @@ mod foo { \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m \u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::hash_map::Iter;\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0m and 9 other candidates\u001b[0m +\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0mand 9 other candidates\u001b[0m " } diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs new file mode 100644 index 00000000000..a4d94836a09 --- /dev/null +++ b/tests/ui/macros/cfg_select.rs @@ -0,0 +1,27 @@ +#![feature(cfg_select)] +#![crate_type = "lib"] + +fn print() { + println!(cfg_select! { + unix => { "unix" } + _ => { "not unix" } + }); +} + +fn arm_rhs_must_be_in_braces() -> i32 { + cfg_select! { + true => 1 + //~^ ERROR: expected `{`, found `1` + } +} + +cfg_select! { + _ => {} + true => {} + //~^ WARN unreachable rule +} + +cfg_select! { + //~^ ERROR none of the rules in this `cfg_select` evaluated to true + false => {} +} diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr new file mode 100644 index 00000000000..fef5e95a6bc --- /dev/null +++ b/tests/ui/macros/cfg_select.stderr @@ -0,0 +1,25 @@ +error: expected `{`, found `1` + --> $DIR/cfg_select.rs:13:17 + | +LL | true => 1 + | ^ expected `{` + +warning: unreachable rule + --> $DIR/cfg_select.rs:20:5 + | +LL | _ => {} + | - always matches +LL | true => {} + | ^^^^ this rules is never reached + +error: none of the rules in this `cfg_select` evaluated to true + --> $DIR/cfg_select.rs:24:1 + | +LL | / cfg_select! { +LL | | +LL | | false => {} +LL | | } + | |_^ + +error: aborting due to 2 previous errors; 1 warning emitted + diff --git a/tests/ui/macros/macro-fragment-ident-underscore-error.rs b/tests/ui/macros/macro-fragment-ident-underscore-error.rs new file mode 100644 index 00000000000..882dd167adc --- /dev/null +++ b/tests/ui/macros/macro-fragment-ident-underscore-error.rs @@ -0,0 +1,12 @@ +//! Verifies that the reserved underscore `_` cannot be used as an `ident` fragment specifier +//! within a macro pattern, as it leads to a compilation error. + +macro_rules! identity { + ($i: ident) => { + $i + }; +} + +fn main() { + let identity!(_) = 10; //~ ERROR no rules expected reserved identifier `_` +} diff --git a/tests/ui/underscore-ident-matcher.stderr b/tests/ui/macros/macro-fragment-ident-underscore-error.stderr index 0c3f980cf6c..929e4624e4b 100644 --- a/tests/ui/underscore-ident-matcher.stderr +++ b/tests/ui/macros/macro-fragment-ident-underscore-error.stderr @@ -1,5 +1,5 @@ error: no rules expected reserved identifier `_` - --> $DIR/underscore-ident-matcher.rs:8:19 + --> $DIR/macro-fragment-ident-underscore-error.rs:11:19 | LL | macro_rules! identity { | --------------------- when calling this macro @@ -8,9 +8,9 @@ LL | let identity!(_) = 10; | ^ no rules expected this token in macro call | note: while trying to match meta-variable `$i:ident` - --> $DIR/underscore-ident-matcher.rs:2:6 + --> $DIR/macro-fragment-ident-underscore-error.rs:5:6 | -LL | ($i: ident) => ( +LL | ($i: ident) => { | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr b/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr index 6f9c9508e7e..9a2e5add37b 100644 --- a/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr +++ b/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr @@ -1,20 +1,30 @@ -error: malformed `marker` attribute input +error[E0565]: malformed `marker` attribute input --> $DIR/marker-attribute-with-values.rs:3:1 | LL | #[marker(always)] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + | ^^^^^^^^--------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` -error: malformed `marker` attribute input +error[E0565]: malformed `marker` attribute input --> $DIR/marker-attribute-with-values.rs:6:1 | LL | #[marker("never")] - | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + | ^^^^^^^^---------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` -error: malformed `marker` attribute input +error[E0565]: malformed `marker` attribute input --> $DIR/marker-attribute-with-values.rs:9:1 | LL | #[marker(key = "value")] - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + | ^^^^^^^^---------------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0565`. diff --git a/tests/ui/modules/module-qualified-paths-basic.rs b/tests/ui/modules/module-qualified-paths-basic.rs new file mode 100644 index 00000000000..c02f6060caa --- /dev/null +++ b/tests/ui/modules/module-qualified-paths-basic.rs @@ -0,0 +1,20 @@ +//! Checks that functions from different modules are accessible via their fully-qualified paths. + +//@ run-pass + +mod foo { + pub fn x() -> isize { + return 1; + } +} + +mod bar { + pub fn y() -> isize { + return 1; + } +} + +pub fn main() { + foo::x(); + bar::y(); +} diff --git a/tests/ui/modules/module-super-access.rs b/tests/ui/modules/module-super-access.rs new file mode 100644 index 00000000000..8acba607f6c --- /dev/null +++ b/tests/ui/modules/module-super-access.rs @@ -0,0 +1,16 @@ +//! Check path resolution using `super` + +//@ run-pass + +#![allow(dead_code)] + +pub mod a { + pub fn f() {} + pub mod b { + fn g() { + super::f(); // Accessing `f` from module `a` (parent of `b`) + } + } +} + +pub fn main() {} diff --git a/tests/ui/use-nested-groups.rs b/tests/ui/modules/module-use-nested-groups.rs index c5d66a86935..84d1f9141a8 100644 --- a/tests/ui/use-nested-groups.rs +++ b/tests/ui/modules/module-use-nested-groups.rs @@ -1,3 +1,5 @@ +//! Checks complex `use` syntax and availability of types across nested modules. + //@ run-pass mod a { diff --git a/tests/ui/modules/primitive-type-module-deprecated-paths.rs b/tests/ui/modules/primitive-type-module-deprecated-paths.rs new file mode 100644 index 00000000000..5c9d2a616b3 --- /dev/null +++ b/tests/ui/modules/primitive-type-module-deprecated-paths.rs @@ -0,0 +1,13 @@ +//! Make sure the module level constants are still there and accessible even after +//! the corresponding associated constants have been added, and later stabilized. + +//@ run-pass + +#![allow(deprecated, deprecated_in_future)] +use std::{f32, u16}; + +fn main() { + let _ = u16::MAX; + let _ = f32::EPSILON; + let _ = std::f64::MANTISSA_DIGITS; +} diff --git a/tests/ui/modules/super-at-crate-root.rs b/tests/ui/modules/super-at-crate-root.rs new file mode 100644 index 00000000000..d605dc0cccb --- /dev/null +++ b/tests/ui/modules/super-at-crate-root.rs @@ -0,0 +1,6 @@ +//! Check that `super` keyword used at the crate root (top-level) results in a compilation error +//! as there is no parent module to resolve. + +use super::f; //~ ERROR there are too many leading `super` keywords + +fn main() {} diff --git a/tests/ui/super-at-top-level.stderr b/tests/ui/modules/super-at-crate-root.stderr index 4dce81fbef4..02798708864 100644 --- a/tests/ui/super-at-top-level.stderr +++ b/tests/ui/modules/super-at-crate-root.stderr @@ -1,5 +1,5 @@ error[E0433]: failed to resolve: there are too many leading `super` keywords - --> $DIR/super-at-top-level.rs:1:5 + --> $DIR/super-at-crate-root.rs:4:5 | LL | use super::f; | ^^^^^ there are too many leading `super` keywords diff --git a/tests/ui/use-keyword-2.rs b/tests/ui/modules/use-keyword-reexport-type-alias.rs index 4f3d1ee500d..c62bd9687ae 100644 --- a/tests/ui/use-keyword-2.rs +++ b/tests/ui/modules/use-keyword-reexport-type-alias.rs @@ -1,18 +1,20 @@ +//! Checks module re-exports, aliasing with `pub use`, +//! and calling private methods via `Self` in an impl block. + //@ run-pass #![allow(unused_variables)] pub struct A; mod test { - pub use super :: A; - - pub use self :: A as B; + pub use self::A as B; + pub use super::A; } impl A { fn f() {} fn g() { - Self :: f() + Self::f() } } diff --git a/tests/ui/namespace/struct-type-and-function-name-coexistence.rs b/tests/ui/namespace/struct-type-and-function-name-coexistence.rs new file mode 100644 index 00000000000..8d5ab3781b5 --- /dev/null +++ b/tests/ui/namespace/struct-type-and-function-name-coexistence.rs @@ -0,0 +1,14 @@ +//@ run-pass + +struct A { + a: isize, +} + +fn a(a: A) -> isize { + return a.a; +} + +pub fn main() { + let x: A = A { a: 1 }; + assert_eq!(a(x), 1); +} diff --git a/tests/ui/unsigned-literal-negation.rs b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs index 943c7f79742..4325c8b111b 100644 --- a/tests/ui/unsigned-literal-negation.rs +++ b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs @@ -1,3 +1,5 @@ +//! This test ensures that the unary negation operator (`-`) cannot be applied to unsigned ints + fn main() { let x = -1 as usize; //~ ERROR: cannot apply unary operator `-` let x = (-1) as usize; //~ ERROR: cannot apply unary operator `-` diff --git a/tests/ui/unsigned-literal-negation.stderr b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr index 0bedbc1accd..4ce870ded9f 100644 --- a/tests/ui/unsigned-literal-negation.stderr +++ b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr @@ -1,5 +1,5 @@ error[E0600]: cannot apply unary operator `-` to type `usize` - --> $DIR/unsigned-literal-negation.rs:2:13 + --> $DIR/unary-negation-unsigned-integer-error.rs:4:13 | LL | let x = -1 as usize; | ^^ cannot apply unary operator `-` @@ -12,7 +12,7 @@ LL + let x = usize::MAX; | error[E0600]: cannot apply unary operator `-` to type `usize` - --> $DIR/unsigned-literal-negation.rs:3:13 + --> $DIR/unary-negation-unsigned-integer-error.rs:5:13 | LL | let x = (-1) as usize; | ^^^^ cannot apply unary operator `-` @@ -25,7 +25,7 @@ LL + let x = usize::MAX; | error[E0600]: cannot apply unary operator `-` to type `u32` - --> $DIR/unsigned-literal-negation.rs:4:18 + --> $DIR/unary-negation-unsigned-integer-error.rs:6:18 | LL | let x: u32 = -1; | ^^ cannot apply unary operator `-` diff --git a/tests/ui/unwind-no-uwtable.rs b/tests/ui/panics/unwind-force-no-unwind-tables.rs index fb8082e3188..2226e4dd03e 100644 --- a/tests/ui/unwind-no-uwtable.rs +++ b/tests/ui/panics/unwind-force-no-unwind-tables.rs @@ -1,3 +1,7 @@ +//! This test checks that Rust's unwinding mechanism correctly executes `Drop` +//! implementations during stack unwinding, even when unwind tables (`uwtable`) +//! are explicitly disabled via `-C force-unwind-tables=n`. + //@ run-pass //@ needs-unwind //@ ignore-windows target requires uwtable @@ -26,9 +30,12 @@ fn increase(count: &mut u8) { fn main() { let mut count = 0; - assert!(panic::catch_unwind(AssertUnwindSafe( - #[inline(never)] - || increase(&mut count) - )).is_err()); + assert!( + panic::catch_unwind(AssertUnwindSafe( + #[inline(never)] + || increase(&mut count) + )) + .is_err() + ); assert_eq!(count, 1); } diff --git a/tests/ui/parser/integer-literal-method-call-underscore.rs b/tests/ui/parser/integer-literal-method-call-underscore.rs new file mode 100644 index 00000000000..9e4abf28cba --- /dev/null +++ b/tests/ui/parser/integer-literal-method-call-underscore.rs @@ -0,0 +1,15 @@ +//! Checks that methods with names starting with an underscore (`_`) can be +//! successfully called directly on integer literals, confirming the correct +//! parsing of such expressions where the underscore is part of the method identifier. + +//@ run-pass + +trait Tr: Sized { + fn _method_on_numbers(self) {} +} + +impl Tr for i32 {} + +fn main() { + 42._method_on_numbers(); +} diff --git a/tests/ui/trailing-comma.rs b/tests/ui/parser/syntactic-trailing-commas.rs index 53b76fb6037..ba688dffb3c 100644 --- a/tests/ui/trailing-comma.rs +++ b/tests/ui/parser/syntactic-trailing-commas.rs @@ -1,3 +1,11 @@ +//! Checks trailing commas are accepted in various places: +//! - Generic parameters in function and struct definitions. +//! - Function and method arguments. +//! - Tuple and array literal expressions. +//! - Tuple and array destructuring patterns, including those with `..`. +//! - Enum variant declarations. +//! - Attributes. + //@ run-pass fn f<T,>(_: T,) {} diff --git a/tests/ui/pattern/issue-22546.rs b/tests/ui/pattern/issue-22546.rs index 81908017b4e..cf128d185df 100644 --- a/tests/ui/pattern/issue-22546.rs +++ b/tests/ui/pattern/issue-22546.rs @@ -15,7 +15,7 @@ impl<T: std::fmt::Display> Foo<T> { } } -trait Tr { //~ WARN trait `Tr` is never used +trait Tr { type U; } diff --git a/tests/ui/pattern/issue-22546.stderr b/tests/ui/pattern/issue-22546.stderr deleted file mode 100644 index e067a95e422..00000000000 --- a/tests/ui/pattern/issue-22546.stderr +++ /dev/null @@ -1,10 +0,0 @@ -warning: trait `Tr` is never used - --> $DIR/issue-22546.rs:18:7 - | -LL | trait Tr { - | ^^ - | - = note: `#[warn(dead_code)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index b651348de29..6c47b52c9de 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -63,7 +63,7 @@ LL - x: (), LL - })), LL + wtf: Some(Box::new_in(_, _)), | - and 12 other candidates + = and 12 other candidates help: consider using the `Default` trait | LL - wtf: Some(Box(U { @@ -118,7 +118,7 @@ LL + let _ = Box::new_zeroed(); LL - let _ = Box {}; LL + let _ = Box::new_in(_, _); | - and 12 other candidates + = and 12 other candidates help: consider using the `Default` trait | LL - let _ = Box {}; diff --git a/tests/ui/wait-forked-but-failed-child.rs b/tests/ui/process/process-spawn-failure.rs index 4a7f2bee9d9..0950b044c97 100644 --- a/tests/ui/wait-forked-but-failed-child.rs +++ b/tests/ui/process/process-spawn-failure.rs @@ -1,3 +1,9 @@ +//! Tests that repeatedly spawning a failing command does not create zombie processes. +//! Spawns a deliberately invalid command multiple times, verifies each spawn fails, +//! then uses `ps` (on Unix) to detect any leftover zombie (defunct) child processes. +//! Checks Rust's process spawning cleans up resources properly. +//! Skipped on platforms without `ps` utility. + //@ run-pass //@ needs-subprocess //@ ignore-vxworks no 'ps' @@ -36,35 +42,42 @@ fn find_zombies() { // the PPID column contains a "-" for the respective process. // Filter out any lines that have a "-" as the PPID as the PPID is // expected to be an integer. - let filtered_ps: Vec<_> = ps_output - .lines() - .filter(|line| line.split_whitespace().nth(1) != Some("-")) - .collect(); + let filtered_ps: Vec<_> = + ps_output.lines().filter(|line| line.split_whitespace().nth(1) != Some("-")).collect(); for (line_no, line) in filtered_ps.into_iter().enumerate() { - if 0 < line_no && 0 < line.len() && - my_pid == line.split(' ').filter(|w| 0 < w.len()).nth(1) - .expect("1st column should be PPID") - .parse().ok() - .expect("PPID string into integer") && - line.contains("defunct") { + if 0 < line_no + && 0 < line.len() + && my_pid + == line + .split(' ') + .filter(|w| 0 < w.len()) + .nth(1) + .expect("1st column should be PPID") + .parse() + .ok() + .expect("PPID string into integer") + && line.contains("defunct") + { panic!("Zombie child {}", line); } } } #[cfg(windows)] -fn find_zombies() { } +fn find_zombies() {} fn main() { let too_long = format!("/NoSuchCommand{:0300}", 0u8); - let _failures = (0..100).map(|_| { - let mut cmd = Command::new(&too_long); - let failed = cmd.spawn(); - assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd); - failed - }).collect::<Vec<_>>(); + let _failures = (0..100) + .map(|_| { + let mut cmd = Command::new(&too_long); + let failed = cmd.spawn(); + assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd); + failed + }) + .collect::<Vec<_>>(); find_zombies(); // then _failures goes out of scope diff --git a/tests/ui/process/windows-exit-code-still-active.rs b/tests/ui/process/windows-exit-code-still-active.rs new file mode 100644 index 00000000000..e661a4f6adc --- /dev/null +++ b/tests/ui/process/windows-exit-code-still-active.rs @@ -0,0 +1,26 @@ +//! On Windows the GetExitCodeProcess API is used to get the exit code of a +//! process, but it's easy to mistake a process exiting with the code 259 as +//! "still running" because this is the value of the STILL_ACTIVE constant. Make +//! sure we handle this case in the standard library and correctly report the +//! status. +//! +//! Note that this is disabled on unix as processes exiting with 259 will have +//! their exit status truncated to 3 (only the lower 8 bits are used). + +//@ run-pass + +#[cfg(windows)] +fn main() { + use std::env; + use std::process::{self, Command}; + + if env::args().len() == 1 { + let status = Command::new(env::current_exe().unwrap()).arg("foo").status().unwrap(); + assert_eq!(status.code(), Some(259)); + } else { + process::exit(259); + } +} + +#[cfg(not(windows))] +fn main() {} diff --git a/tests/ui/ptr_ops/ptr-swap-basic.rs b/tests/ui/ptr_ops/ptr-swap-basic.rs new file mode 100644 index 00000000000..ce230feeb32 --- /dev/null +++ b/tests/ui/ptr_ops/ptr-swap-basic.rs @@ -0,0 +1,14 @@ +//! Check the basic functionality of `std::mem::swap` to ensure it correctly +//! exchanges the values of two mutable variables. + +//@ run-pass + +use std::mem::swap; + +pub fn main() { + let mut x = 3; + let mut y = 7; + swap(&mut x, &mut y); + assert_eq!(x, 7); + assert_eq!(y, 3); +} diff --git a/tests/ui/swap-overlapping.rs b/tests/ui/ptr_ops/ptr-swap-overlapping-regions.rs index 38d5a8109d1..8f05e937d59 100644 --- a/tests/ui/swap-overlapping.rs +++ b/tests/ui/ptr_ops/ptr-swap-overlapping-regions.rs @@ -1,17 +1,17 @@ +//! Check that `std::ptr::swap` behaves correctly when the source and destination +//! pointers refer to the same memory location, avoiding issues like overlapping `memcpy`. +//! +//! Regression test: <https://github.com/rust-lang/rust/issues/5041> + //@ run-pass #![allow(dead_code)] -// Issue #5041 - avoid overlapping memcpy when src and dest of a swap are the same - use std::ptr; pub fn main() { let mut test = TestDescAndFn { - desc: TestDesc { - name: TestName::DynTestName("test".to_string()), - should_fail: false - }, + desc: TestDesc { name: TestName::DynTestName("test".to_string()), should_fail: false }, testfn: TestFn::DynTestFn(22), }; do_swap(&mut test); @@ -24,7 +24,7 @@ fn do_swap(test: &mut TestDescAndFn) { } pub enum TestName { - DynTestName(String) + DynTestName(String), } pub enum TestFn { @@ -34,7 +34,7 @@ pub enum TestFn { pub struct TestDesc { name: TestName, - should_fail: bool + should_fail: bool, } pub struct TestDescAndFn { diff --git a/tests/ui/ptr_ops/ptr-write-bool-representation.rs b/tests/ui/ptr_ops/ptr-write-bool-representation.rs new file mode 100644 index 00000000000..3dfc3e51ab2 --- /dev/null +++ b/tests/ui/ptr_ops/ptr-write-bool-representation.rs @@ -0,0 +1,18 @@ +//! Validates the correct behavior of writing a `bool` value using `std::ptr::write`. +//! +//! This test addresses historical concerns regarding the internal representation of `bool` +//! (e.g., as `i1` in LLVM versus its byte-aligned memory layout) and checks that +//! `ptr::write` correctly handles this type without issues, confirming its memory +//! behavior is as expected. + +//@ run-pass + +use std::ptr; + +pub fn main() { + unsafe { + let mut x: bool = false; + // this line breaks it + ptr::write(&mut x, false); + } +} diff --git a/tests/ui/ptr_ops/raw-pointer-type-basic.rs b/tests/ui/ptr_ops/raw-pointer-type-basic.rs new file mode 100644 index 00000000000..349e8e67909 --- /dev/null +++ b/tests/ui/ptr_ops/raw-pointer-type-basic.rs @@ -0,0 +1,18 @@ +//! Checks the basic usage of raw pointers (`*const isize`) as function argument and return types. + +//@ run-pass + +#![allow(dead_code)] + +fn f(a: *const isize) -> *const isize { + return a; +} + +fn g(a: *const isize) -> *const isize { + let b = f(a); + return b; +} + +pub fn main() { + return; +} diff --git a/tests/ui/reachable/diverging-expressions-unreachable-code.rs b/tests/ui/reachable/diverging-expressions-unreachable-code.rs new file mode 100644 index 00000000000..bb56987775f --- /dev/null +++ b/tests/ui/reachable/diverging-expressions-unreachable-code.rs @@ -0,0 +1,19 @@ +//@ run-pass + +#![allow(unused_must_use)] +#![allow(unreachable_code)] + +fn _id(x: bool) -> bool { + x +} + +fn _call_id() { + let _c = panic!(); + _id(_c); +} + +fn _call_id_3() { + _id(return) && _id(return); +} + +pub fn main() {} diff --git a/tests/ui/unreachable-code.rs b/tests/ui/reachable/unreachable-code-diverging-expressions.rs index 0c46a38d73f..00676418002 100644 --- a/tests/ui/unreachable-code.rs +++ b/tests/ui/reachable/unreachable-code-diverging-expressions.rs @@ -26,9 +26,13 @@ fn call_id_3() { fn ret_guard() { match 2 { - x if (return) => { x; } - x if let true = return => { x; } - _ => {} + x if (return) => { + x; + } + x if let true = return => { + x; + } + _ => {} } } diff --git a/tests/ui/recursion/recursion-tail-call-no-arg-leak.rs b/tests/ui/recursion/recursion-tail-call-no-arg-leak.rs new file mode 100644 index 00000000000..fe10b890700 --- /dev/null +++ b/tests/ui/recursion/recursion-tail-call-no-arg-leak.rs @@ -0,0 +1,15 @@ +//! This test verifies that tail call optimization does not lead to argument slot leaks. +//! +//! Regression test for: <https://github.com/rust-lang/rust/issues/160> + +//@ run-pass + +fn inner(dummy: String, b: bool) { + if b { + return inner(dummy, false); + } +} + +pub fn main() { + inner("hi".to_string(), true); +} diff --git a/tests/ui/recursion/recursion-tail-cps.rs b/tests/ui/recursion/recursion-tail-cps.rs new file mode 100644 index 00000000000..9014be0ce98 --- /dev/null +++ b/tests/ui/recursion/recursion-tail-cps.rs @@ -0,0 +1,34 @@ +//! Verify that mutually recursive functions use CPS to avoid overflowing the stack. + +//@ run-pass + +fn checktrue(rs: bool) -> bool { + assert!(rs); + return true; +} + +pub fn main() { + let k = checktrue; + evenk(42, k); + oddk(45, k); +} + +fn evenk(n: isize, k: fn(bool) -> bool) -> bool { + println!("evenk"); + println!("{}", n); + if n == 0 { + return k(true); + } else { + return oddk(n - 1, k); + } +} + +fn oddk(n: isize, k: fn(bool) -> bool) -> bool { + println!("oddk"); + println!("{}", n); + if n == 0 { + return k(false); + } else { + return evenk(n - 1, k); + } +} diff --git a/tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.stderr b/tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.stderr index ce2022374f7..9f31a731fed 100644 --- a/tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.stderr +++ b/tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.stderr @@ -38,9 +38,12 @@ error[E0308]: mismatched types --> $DIR/typo-in-repeat-expr-issue-80173.rs:32:29 | LL | let e = [String::new(), 10]; - | ^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found integer + | ^^ expected `String`, found integer + | +help: try using a conversion method + | +LL | let e = [String::new(), 10.to_string()]; + | ++++++++++++ error[E0308]: mismatched types --> $DIR/typo-in-repeat-expr-issue-80173.rs:36:19 diff --git a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr index ee1a336ea98..0eb1d46637b 100644 --- a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr +++ b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr @@ -14,7 +14,7 @@ LL + use std::collections::hash_map::Drain; | LL + use std::collections::hash_set::Drain; | - and 3 other candidates + = and 3 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr b/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr index 2da3925341e..7a3d8b43c2e 100644 --- a/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr +++ b/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr @@ -30,10 +30,10 @@ LL | fn a(self: impl Receiver<Target=Self>) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::a` help: consider borrowing here | -LL | &foo.a(); - | + -LL | &mut foo.a(); - | ++++ +LL | (&foo).a(); + | ++ + +LL | (&mut foo).a(); + | +++++ + error[E0277]: the trait bound `Foo: Deref` is not satisfied --> $DIR/arbitrary_self_types_generic_over_receiver.rs:21:9 @@ -48,10 +48,10 @@ LL | fn b(self: impl Deref<Target=Self>) -> u32 { | ^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::b` help: consider borrowing here | -LL | &foo.b(); - | + -LL | &mut foo.b(); - | ++++ +LL | (&foo).b(); + | ++ + +LL | (&mut foo).b(); + | +++++ + error: aborting due to 4 previous errors diff --git a/tests/ui/specialization/issue-111232.rs b/tests/ui/specialization/issue-111232.rs index 3ed3c580e6d..fa00f01886f 100644 --- a/tests/ui/specialization/issue-111232.rs +++ b/tests/ui/specialization/issue-111232.rs @@ -1,4 +1,13 @@ #![feature(min_specialization)] +#![feature(const_trait_impl)] + +trait From<T> { + fn from(t: T) -> Self; +} + +impl<T> From<T> for T { + fn from(t: T) -> T { t } +} struct S; diff --git a/tests/ui/specialization/issue-111232.stderr b/tests/ui/specialization/issue-111232.stderr index ed392e4f915..5f169f0bb36 100644 --- a/tests/ui/specialization/issue-111232.stderr +++ b/tests/ui/specialization/issue-111232.stderr @@ -1,10 +1,13 @@ error[E0520]: `from` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/issue-111232.rs:6:5 + --> $DIR/issue-111232.rs:15:5 | +LL | impl<T> From<T> for T { + | --------------------- parent `impl` is here +... LL | fn from(s: S) -> S { - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ cannot specialize default item `from` | - = note: parent implementation is in crate `core` + = note: to specialize, `from` in the parent `impl` must be marked `default` error: aborting due to 1 previous error diff --git a/tests/ui/specialization/specialization-default-types.current.stderr b/tests/ui/specialization/specialization-default-types.current.stderr index 67477f9a6d5..09689681740 100644 --- a/tests/ui/specialization/specialization-default-types.current.stderr +++ b/tests/ui/specialization/specialization-default-types.current.stderr @@ -12,7 +12,7 @@ error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:19:9 | LL | default type Output = Box<T>; - | ----------------------------- associated type is `default` and may be overridden + | ------------------- associated type is `default` and may be overridden LL | default fn generate(self) -> Self::Output { | ------------ expected `<T as Example>::Output` because of return type LL | Box::new(self) diff --git a/tests/ui/specialization/specialization-default-types.next.stderr b/tests/ui/specialization/specialization-default-types.next.stderr index 4f7c4765446..1535c6473bd 100644 --- a/tests/ui/specialization/specialization-default-types.next.stderr +++ b/tests/ui/specialization/specialization-default-types.next.stderr @@ -12,7 +12,7 @@ error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:19:9 | LL | default type Output = Box<T>; - | ----------------------------- associated type is `default` and may be overridden + | ------------------- associated type is `default` and may be overridden LL | default fn generate(self) -> Self::Output { | ------------ expected `<T as Example>::Output` because of return type LL | Box::new(self) diff --git a/tests/ui/static/bad-const-type.stderr b/tests/ui/static/bad-const-type.stderr index 807cd2f7a25..8573a11ef29 100644 --- a/tests/ui/static/bad-const-type.stderr +++ b/tests/ui/static/bad-const-type.stderr @@ -2,9 +2,12 @@ error[E0308]: mismatched types --> $DIR/bad-const-type.rs:1:20 | LL | static i: String = 10; - | ^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found integer + | ^^ expected `String`, found integer + | +help: try using a conversion method + | +LL | static i: String = 10.to_string(); + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr index eb038bbcaf1..72a9820bb64 100644 --- a/tests/ui/stats/input-stats.stderr +++ b/tests/ui/stats/input-stats.stderr @@ -107,17 +107,17 @@ hir-stats WherePredicate 72 (NN.N%) 3 24 hir-stats - BoundPredicate 72 (NN.N%) 3 hir-stats Local 72 (NN.N%) 1 72 hir-stats InlineAsm 72 (NN.N%) 1 72 -hir-stats ImplItemRef 72 (NN.N%) 2 36 hir-stats Body 72 (NN.N%) 3 24 hir-stats Param 64 (NN.N%) 2 32 hir-stats GenericArg 64 (NN.N%) 4 16 hir-stats - Type 16 (NN.N%) 1 hir-stats - Lifetime 48 (NN.N%) 3 -hir-stats TraitItemRef 56 (NN.N%) 2 28 hir-stats ExprField 40 (NN.N%) 1 40 hir-stats Mod 32 (NN.N%) 1 32 hir-stats Lifetime 28 (NN.N%) 1 28 -hir-stats ForeignItemRef 24 (NN.N%) 1 24 +hir-stats TraitItemId 8 (NN.N%) 2 4 +hir-stats ImplItemId 8 (NN.N%) 2 4 +hir-stats ForeignItemId 4 (NN.N%) 1 4 hir-stats ---------------------------------------------------------------- -hir-stats Total 8_716 173 +hir-stats Total 8_584 173 hir-stats ================================================================ diff --git a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.fixed b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.fixed index 95fd920dec2..00b92b42bb5 100644 --- a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.fixed +++ b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.fixed @@ -4,14 +4,24 @@ struct S; trait Trait { fn foo() {} } -impl Trait for &S {} impl Trait for &mut S {} +trait Trait2 { + fn bar() {} +} +impl Trait2 for &S {} +impl Trait2 for &mut S {} fn main() { let _ = <&str>::from("value"); //~^ ERROR the trait bound `str: From<_>` is not satisfied //~| ERROR the size for values of type `str` cannot be known at compilation time let _ = <&mut S>::foo(); //~^ ERROR the trait bound `S: Trait` is not satisfied - let _ = <&S>::foo(); + let _ = <&mut S>::foo(); + //~^ ERROR the trait bound `S: Trait` is not satisfied + let _ = <&mut S>::foo(); //~^ ERROR the trait bound `S: Trait` is not satisfied + let _ = <&mut S>::bar(); + //~^ ERROR the trait bound `S: Trait2` is not satisfied + let _ = <&S>::bar(); + //~^ ERROR the trait bound `S: Trait2` is not satisfied } diff --git a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.rs b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.rs index f79d2465062..3059ccdffb4 100644 --- a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.rs +++ b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.rs @@ -4,8 +4,12 @@ struct S; trait Trait { fn foo() {} } -impl Trait for &S {} impl Trait for &mut S {} +trait Trait2 { + fn bar() {} +} +impl Trait2 for &S {} +impl Trait2 for &mut S {} fn main() { let _ = &str::from("value"); //~^ ERROR the trait bound `str: From<_>` is not satisfied @@ -14,4 +18,10 @@ fn main() { //~^ ERROR the trait bound `S: Trait` is not satisfied let _ = &S::foo(); //~^ ERROR the trait bound `S: Trait` is not satisfied + let _ = S::foo(); + //~^ ERROR the trait bound `S: Trait` is not satisfied + let _ = &mut S::bar(); + //~^ ERROR the trait bound `S: Trait2` is not satisfied + let _ = &S::bar(); + //~^ ERROR the trait bound `S: Trait2` is not satisfied } diff --git a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr index ac96ec76da7..c2e2fe941a6 100644 --- a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr +++ b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `str: From<_>` is not satisfied - --> $DIR/dont-suggest-borrowing-existing-borrow.rs:10:14 + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:14:14 | LL | let _ = &str::from("value"); | ^^^ the trait `From<_>` is not implemented for `str` @@ -17,35 +17,71 @@ LL | let _ = <&str>::from("value"); | + + error[E0277]: the trait bound `S: Trait` is not satisfied - --> $DIR/dont-suggest-borrowing-existing-borrow.rs:13:18 + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:17:18 | LL | let _ = &mut S::foo(); | ^ the trait `Trait` is not implemented for `S` | - = help: the following other types implement trait `Trait`: - &S - &mut S + = help: the trait `Trait` is implemented for `&mut S` help: you likely meant to call the associated function `foo` for type `&mut S`, but the code as written calls associated function `foo` on type `S` | LL | let _ = <&mut S>::foo(); | + + error[E0277]: the trait bound `S: Trait` is not satisfied - --> $DIR/dont-suggest-borrowing-existing-borrow.rs:15:14 + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:19:14 | LL | let _ = &S::foo(); | ^ the trait `Trait` is not implemented for `S` | - = help: the following other types implement trait `Trait`: + = help: the trait `Trait` is implemented for `&mut S` +help: you likely meant to call the associated function `foo` for type `&S`, but the code as written calls associated function `foo` on type `S` + | +LL - let _ = &S::foo(); +LL + let _ = <&mut S>::foo(); + | + +error[E0277]: the trait bound `S: Trait` is not satisfied + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:21:13 + | +LL | let _ = S::foo(); + | ^ the trait `Trait` is not implemented for `S` + | +help: consider mutably borrowing here + | +LL | let _ = <&mut S>::foo(); + | +++++ + + +error[E0277]: the trait bound `S: Trait2` is not satisfied + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:23:18 + | +LL | let _ = &mut S::bar(); + | ^ the trait `Trait2` is not implemented for `S` + | + = help: the following other types implement trait `Trait2`: &S &mut S -help: you likely meant to call the associated function `foo` for type `&S`, but the code as written calls associated function `foo` on type `S` +help: you likely meant to call the associated function `bar` for type `&mut S`, but the code as written calls associated function `bar` on type `S` + | +LL | let _ = <&mut S>::bar(); + | + + + +error[E0277]: the trait bound `S: Trait2` is not satisfied + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:25:14 + | +LL | let _ = &S::bar(); + | ^ the trait `Trait2` is not implemented for `S` + | + = help: the following other types implement trait `Trait2`: + &S + &mut S +help: you likely meant to call the associated function `bar` for type `&S`, but the code as written calls associated function `bar` on type `S` | -LL | let _ = <&S>::foo(); +LL | let _ = <&S>::bar(); | + + error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/dont-suggest-borrowing-existing-borrow.rs:10:14 + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:14:14 | LL | let _ = &str::from("value"); | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -53,6 +89,6 @@ LL | let _ = &str::from("value"); = help: the trait `Sized` is not implemented for `str` = note: the return type of a function must have a statically known size -error: aborting due to 4 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/suggestions/issue-104327.stderr b/tests/ui/suggestions/issue-104327.stderr index 1bad82d471e..4515fe223c7 100644 --- a/tests/ui/suggestions/issue-104327.stderr +++ b/tests/ui/suggestions/issue-104327.stderr @@ -2,7 +2,7 @@ error[E0790]: cannot call associated function on trait without specifying the co --> $DIR/issue-104327.rs:10:5 | LL | fn f() {} - | --------- `Foo::f` defined here + | ------ `Foo::f` defined here ... LL | Foo::f(); | ^^^^^^^^ cannot call associated function of trait diff --git a/tests/ui/suggestions/issue-52820.stderr b/tests/ui/suggestions/issue-52820.stderr index a67d7501417..de2c9542f61 100644 --- a/tests/ui/suggestions/issue-52820.stderr +++ b/tests/ui/suggestions/issue-52820.stderr @@ -13,10 +13,13 @@ error[E0308]: mismatched types --> $DIR/issue-52820.rs:13:17 | LL | brains: guts.clone(), - | ^^^^^-----^^ - | | | - | | help: try using a conversion method: `to_string` - | expected `String`, found `&str` + | ^^^^^^^^^^^^ expected `String`, found `&str` + | +help: try using a conversion method + | +LL - brains: guts.clone(), +LL + brains: guts.to_string(), + | error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/issue-53692.stderr b/tests/ui/suggestions/issue-53692.stderr index 469a538411f..10ebb30a5b2 100644 --- a/tests/ui/suggestions/issue-53692.stderr +++ b/tests/ui/suggestions/issue-53692.stderr @@ -2,24 +2,31 @@ error[E0308]: mismatched types --> $DIR/issue-53692.rs:7:33 | LL | let items_clone: Vec<i32> = ref_items.clone(); - | -------- ^^^^^^^^^^-----^^ - | | | | - | | | help: try using a conversion method: `to_vec` - | | expected `Vec<i32>`, found `&[i32]` + | -------- ^^^^^^^^^^^^^^^^^ expected `Vec<i32>`, found `&[i32]` + | | | expected due to this | = note: expected struct `Vec<i32>` found reference `&[i32]` +help: try using a conversion method + | +LL - let items_clone: Vec<i32> = ref_items.clone(); +LL + let items_clone: Vec<i32> = ref_items.to_vec(); + | error[E0308]: mismatched types --> $DIR/issue-53692.rs:14:26 | LL | let string: String = s.clone(); - | ------ ^^-----^^ - | | | | - | | | help: try using a conversion method: `to_string` - | | expected `String`, found `&str` + | ------ ^^^^^^^^^ expected `String`, found `&str` + | | | expected due to this + | +help: try using a conversion method + | +LL - let string: String = s.clone(); +LL + let string: String = s.to_string(); + | error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/issue-59819.stderr b/tests/ui/suggestions/issue-59819.stderr index 43acf9549c2..ab91961192f 100644 --- a/tests/ui/suggestions/issue-59819.stderr +++ b/tests/ui/suggestions/issue-59819.stderr @@ -28,10 +28,14 @@ error[E0308]: mismatched types --> $DIR/issue-59819.rs:34:21 | LL | let g: String = f; - | ------ ^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found `Bar` + | ------ ^ expected `String`, found `Bar` + | | | expected due to this + | +help: try using a conversion method + | +LL | let g: String = f.to_string(); + | ++++++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/issue-83943.stderr b/tests/ui/suggestions/issue-83943.stderr index 1a085368485..e714a126f4a 100644 --- a/tests/ui/suggestions/issue-83943.stderr +++ b/tests/ui/suggestions/issue-83943.stderr @@ -6,11 +6,14 @@ LL | | "A".to_string() | | --------------- expected because of this LL | | } else { LL | | "B" - | | ^^^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found `&str` + | | ^^^ expected `String`, found `&str` LL | | }; | |_____- `if` and `else` have incompatible types + | +help: try using a conversion method + | +LL | "B".to_string() + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr new file mode 100644 index 00000000000..f2a146fbd52 --- /dev/null +++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr @@ -0,0 +1,130 @@ +error[E0423]: expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` + --> $DIR/multi-suggestion.rs:17:13 + | +LL | let _ = std::collections::HashMap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + | + = note: `std::collections::HashMap` defined here + | +help: you might have meant to use an associated function to build this type + | +LL | let _ = std::collections::HashMap::new(); + | +++++ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity(_); + | +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_hasher(_); + | +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + | +help: consider using the `Default` trait + | +LL | let _ = <std::collections::HashMap as std::default::Default>::default(); + | + ++++++++++++++++++++++++++++++++++ + +error[E0423]: cannot initialize a tuple struct which contains private fields + --> $DIR/multi-suggestion.rs:11:19 + | +LL | wtf: Some(Box(U { + | ^^^ + | +note: constructor is not visible here due to private fields + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: private field + | + = note: private field +help: you might have meant to use an associated function to build this type + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new(_)), + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_uninit()), + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_zeroed()), + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_in(_, _)), + | + = and 12 other candidates +help: consider using the `Default` trait + | +LL - wtf: Some(Box(U { +LL + wtf: Some(<Box as std::default::Default>::default()), + | + +error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + --> $DIR/multi-suggestion.rs:19:13 + | +LL | let _ = std::collections::HashMap {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: private field `base` that was not provided +help: you might have meant to use an associated function to build this type + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new(); + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity(_); + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_hasher(_); + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + | +help: consider using the `Default` trait + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = <std::collections::HashMap as std::default::Default>::default(); + | + +error: cannot construct `Box<_, _>` with struct literal syntax due to private fields + --> $DIR/multi-suggestion.rs:21:13 + | +LL | let _ = Box {}; + | ^^^ + | + = note: private fields `0` and `1` that were not provided +help: you might have meant to use an associated function to build this type + | +LL - let _ = Box {}; +LL + let _ = Box::new(_); + | +LL - let _ = Box {}; +LL + let _ = Box::new_uninit(); + | +LL - let _ = Box {}; +LL + let _ = Box::new_zeroed(); + | +LL - let _ = Box {}; +LL + let _ = Box::new_in(_, _); + | + = and 12 other candidates +help: consider using the `Default` trait + | +LL - let _ = Box {}; +LL + let _ = <Box as std::default::Default>::default(); + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/suggestions/multi-suggestion.rs b/tests/ui/suggestions/multi-suggestion.rs new file mode 100644 index 00000000000..99d2407aa21 --- /dev/null +++ b/tests/ui/suggestions/multi-suggestion.rs @@ -0,0 +1,22 @@ +//@ revisions: ascii unicode +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode + +#![allow(dead_code)] +struct U <T> { + wtf: Option<Box<U<T>>>, + x: T, +} +fn main() { + U { + wtf: Some(Box(U { //[ascii]~ ERROR cannot initialize a tuple struct which contains private fields + wtf: None, + x: (), + })), + x: () + }; + let _ = std::collections::HashMap(); + //[ascii]~^ ERROR expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` + let _ = std::collections::HashMap {}; + //[ascii]~^ ERROR cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + let _ = Box {}; //[ascii]~ ERROR cannot construct `Box<_, _>` with struct literal syntax due to private fields +} diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr new file mode 100644 index 00000000000..69df481579b --- /dev/null +++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr @@ -0,0 +1,130 @@ +error[E0423]: expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` + ╭▸ $DIR/multi-suggestion.rs:17:13 + │ +LL │ let _ = std::collections::HashMap(); + │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━ + ╭▸ $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + │ + ╰ note: `std::collections::HashMap` defined here + ╰╴ +help: you might have meant to use an associated function to build this type + ╭╴ +LL │ let _ = std::collections::HashMap::new(); + ├╴ +++++ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity(_); + ├╴ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_hasher(_); + ├╴ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + ╰╴ +help: consider using the `Default` trait + ╭╴ +LL │ let _ = <std::collections::HashMap as std::default::Default>::default(); + ╰╴ + ++++++++++++++++++++++++++++++++++ + +error[E0423]: cannot initialize a tuple struct which contains private fields + ╭▸ $DIR/multi-suggestion.rs:11:19 + │ +LL │ wtf: Some(Box(U { + │ ━━━ + ╰╴ +note: constructor is not visible here due to private fields + ╭▸ $SRC_DIR/alloc/src/boxed.rs:LL:COL + │ + ╰ note: private field + │ + ╰ note: private field +help: you might have meant to use an associated function to build this type + ╭╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new(_)), + ├╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_uninit()), + ├╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_zeroed()), + ├╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_in(_, _)), + │ + ╰ and 12 other candidates +help: consider using the `Default` trait + ╭╴ +LL - wtf: Some(Box(U { +LL + wtf: Some(<Box as std::default::Default>::default()), + ╰╴ + +error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + ╭▸ $DIR/multi-suggestion.rs:19:13 + │ +LL │ let _ = std::collections::HashMap {}; + │ ━━━━━━━━━━━━━━━━━━━━━━━━━ + │ + ╰ note: private field `base` that was not provided +help: you might have meant to use an associated function to build this type + ╭╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new(); + ├╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity(_); + ├╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_hasher(_); + ├╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + ╰╴ +help: consider using the `Default` trait + ╭╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = <std::collections::HashMap as std::default::Default>::default(); + ╰╴ + +error: cannot construct `Box<_, _>` with struct literal syntax due to private fields + ╭▸ $DIR/multi-suggestion.rs:21:13 + │ +LL │ let _ = Box {}; + │ ━━━ + │ + ╰ note: private fields `0` and `1` that were not provided +help: you might have meant to use an associated function to build this type + ╭╴ +LL - let _ = Box {}; +LL + let _ = Box::new(_); + ├╴ +LL - let _ = Box {}; +LL + let _ = Box::new_uninit(); + ├╴ +LL - let _ = Box {}; +LL + let _ = Box::new_zeroed(); + ├╴ +LL - let _ = Box {}; +LL + let _ = Box::new_in(_, _); + │ + ╰ and 12 other candidates +help: consider using the `Default` trait + ╭╴ +LL - let _ = Box {}; +LL + let _ = <Box as std::default::Default>::default(); + ╰╴ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr b/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr index c721ceb1146..ed94ebd27ff 100644 --- a/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr +++ b/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr @@ -5,9 +5,12 @@ LL | fn get_name() -> String { | ------ expected `String` because of return type ... LL | your_name.trim() - | ^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found `&str` + | ^^^^^^^^^^^^^^^^ expected `String`, found `&str` + | +help: try using a conversion method + | +LL | your_name.trim().to_string() + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/too-many-field-suggestions.stderr b/tests/ui/suggestions/too-many-field-suggestions.stderr index ac5c8cb60cc..0cb0c8bec07 100644 --- a/tests/ui/suggestions/too-many-field-suggestions.stderr +++ b/tests/ui/suggestions/too-many-field-suggestions.stderr @@ -17,7 +17,7 @@ LL | t.a2.bar(); | +++ LL | t.a3.bar(); | +++ - and 6 other candidates + = and 6 other candidates error[E0609]: no field `field` on type `Thing` --> $DIR/too-many-field-suggestions.rs:26:7 @@ -35,7 +35,7 @@ LL | t.a2.field; | +++ LL | t.a3.field; | +++ - and 6 other candidates + = and 6 other candidates error: aborting due to 2 previous errors diff --git a/tests/ui/super-at-top-level.rs b/tests/ui/super-at-top-level.rs deleted file mode 100644 index e4d587bc9ef..00000000000 --- a/tests/ui/super-at-top-level.rs +++ /dev/null @@ -1,4 +0,0 @@ -use super::f; //~ ERROR there are too many leading `super` keywords - -fn main() { -} diff --git a/tests/ui/super.rs b/tests/ui/super.rs deleted file mode 100644 index 69aff4f98e0..00000000000 --- a/tests/ui/super.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-pass - -#![allow(dead_code)] - -pub mod a { - pub fn f() {} - pub mod b { - fn g() { - super::f(); - } - } -} - -pub fn main() { -} diff --git a/tests/ui/svh-add-nothing.rs b/tests/ui/svh-add-nothing.rs deleted file mode 100644 index 6e4b9fa7f4c..00000000000 --- a/tests/ui/svh-add-nothing.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ run-pass -// note that these aux-build directives must be in this order -//@ aux-build:svh-a-base.rs -//@ aux-build:svh-b.rs -//@ aux-build:svh-a-base.rs - - -extern crate a; -extern crate b; - -fn main() { - b::foo() -} diff --git a/tests/ui/svh/svh-no-api-change-no-recompile.rs b/tests/ui/svh/svh-no-api-change-no-recompile.rs new file mode 100644 index 00000000000..d4b8ac77444 --- /dev/null +++ b/tests/ui/svh/svh-no-api-change-no-recompile.rs @@ -0,0 +1,20 @@ +//! This test verifies that the Signature Version Hash (SVH) system correctly identifies +//! when changes to an auxiliary crate do not affect its public API. +//! +//! Specifically, it checks that adding non-public items to a crate does not alter +//! its SVH, preventing unnecessary recompilations of dependent crates. + +//@ run-pass + +// Note that these aux-build directives must be in this order + +//@ aux-build:svh-a-base.rs +//@ aux-build:svh-b.rs +//@ aux-build:svh-a-base.rs + +extern crate a; +extern crate b; + +fn main() { + b::foo() +} diff --git a/tests/ui/swap-1.rs b/tests/ui/swap-1.rs deleted file mode 100644 index b104c3ade42..00000000000 --- a/tests/ui/swap-1.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass - -use std::mem::swap; - -pub fn main() { - let mut x = 3; let mut y = 7; - swap(&mut x, &mut y); - assert_eq!(x, 7); - assert_eq!(y, 3); -} diff --git a/tests/ui/switched-expectations.rs b/tests/ui/switched-expectations.rs deleted file mode 100644 index c5bc84de54c..00000000000 --- a/tests/ui/switched-expectations.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - let var = 10i32; - let ref string: String = var; //~ ERROR mismatched types [E0308] -} diff --git a/tests/ui/switched-expectations.stderr b/tests/ui/switched-expectations.stderr deleted file mode 100644 index cc576747400..00000000000 --- a/tests/ui/switched-expectations.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/switched-expectations.rs:3:30 - | -LL | let ref string: String = var; - | ^^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found `i32` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/tag-type-args.rs b/tests/ui/tag-type-args.rs deleted file mode 100644 index 75a54927443..00000000000 --- a/tests/ui/tag-type-args.rs +++ /dev/null @@ -1,6 +0,0 @@ -enum Quux<T> { Bar } -//~^ ERROR: parameter `T` is never used - -fn foo(c: Quux) { assert!((false)); } //~ ERROR missing generics for enum `Quux` - -fn main() { panic!(); } diff --git a/tests/ui/tail-call-arg-leak.rs b/tests/ui/tail-call-arg-leak.rs deleted file mode 100644 index 234924307c3..00000000000 --- a/tests/ui/tail-call-arg-leak.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass -// use of tail calls causes arg slot leaks, issue #160. - -fn inner(dummy: String, b: bool) { if b { return inner(dummy, false); } } - -pub fn main() { - inner("hi".to_string(), true); -} diff --git a/tests/ui/tail-cps.rs b/tests/ui/tail-cps.rs deleted file mode 100644 index fe99dadf795..00000000000 --- a/tests/ui/tail-cps.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ run-pass - -fn checktrue(rs: bool) -> bool { assert!(rs); return true; } - -pub fn main() { let k = checktrue; evenk(42, k); oddk(45, k); } - -fn evenk(n: isize, k: fn(bool) -> bool) -> bool { - println!("evenk"); - println!("{}", n); - if n == 0 { return k(true); } else { return oddk(n - 1, k); } -} - -fn oddk(n: isize, k: fn(bool) -> bool) -> bool { - println!("oddk"); - println!("{}", n); - if n == 0 { return k(false); } else { return evenk(n - 1, k); } -} diff --git a/tests/ui/tail-typeck.rs b/tests/ui/tail-typeck.rs deleted file mode 100644 index 1deb43c9496..00000000000 --- a/tests/ui/tail-typeck.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn f() -> isize { return g(); } //~ ERROR mismatched types - -fn g() -> usize { return 0; } - -fn main() { let y = f(); } diff --git a/tests/ui/tail-typeck.stderr b/tests/ui/tail-typeck.stderr deleted file mode 100644 index 3cfbfa0fb56..00000000000 --- a/tests/ui/tail-typeck.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/tail-typeck.rs:1:26 - | -LL | fn f() -> isize { return g(); } - | ----- ^^^ expected `isize`, found `usize` - | | - | expected `isize` because of return type - | -help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit - | -LL | fn f() -> isize { return g().try_into().unwrap(); } - | ++++++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/trait-method-number-parameters.rs b/tests/ui/trait-method-number-parameters.rs deleted file mode 100644 index 719005d6643..00000000000 --- a/tests/ui/trait-method-number-parameters.rs +++ /dev/null @@ -1,13 +0,0 @@ -trait Foo { - fn foo(&mut self, x: i32, y: i32) -> i32; -} - -impl Foo for i32 { - fn foo( - &mut self, //~ ERROR - x: i32, - ) { - } -} - -fn main() {} diff --git a/tests/ui/traits/const-traits/call-const-trait-method-pass.rs b/tests/ui/traits/const-traits/call-const-trait-method-pass.rs index d66a11490c5..2d9c2ca0861 100644 --- a/tests/ui/traits/const-traits/call-const-trait-method-pass.rs +++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl, const_ops)] +#![feature(const_trait_impl, const_ops, const_cmp)] //@ check-pass struct Int(i32); diff --git a/tests/ui/traits/const-traits/call-generic-in-impl.rs b/tests/ui/traits/const-traits/call-generic-in-impl.rs index f38590fa3c0..72fc80c50e0 100644 --- a/tests/ui/traits/const-traits/call-generic-in-impl.rs +++ b/tests/ui/traits/const-traits/call-generic-in-impl.rs @@ -1,5 +1,5 @@ //@ check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_cmp)] #[const_trait] trait MyPartialEq { diff --git a/tests/ui/traits/const-traits/call-generic-method-chain.rs b/tests/ui/traits/const-traits/call-generic-method-chain.rs index 1ad71c424a3..db053b48079 100644 --- a/tests/ui/traits/const-traits/call-generic-method-chain.rs +++ b/tests/ui/traits/const-traits/call-generic-method-chain.rs @@ -3,7 +3,7 @@ //@ compile-flags: -Znext-solver //@ check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_cmp)] struct S; diff --git a/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs b/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs index 58f293b5ac5..5913cbf8a21 100644 --- a/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs +++ b/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Znext-solver //@ check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_cmp)] struct S; diff --git a/tests/ui/traits/const-traits/call-generic-method-fail.rs b/tests/ui/traits/const-traits/call-generic-method-fail.rs index 4528f3b122f..6744176d40a 100644 --- a/tests/ui/traits/const-traits/call-generic-method-fail.rs +++ b/tests/ui/traits/const-traits/call-generic-method-fail.rs @@ -1,5 +1,5 @@ //@ compile-flags: -Znext-solver -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_cmp)] pub const fn equals_self<T: PartialEq>(t: &T) -> bool { *t == *t diff --git a/tests/ui/traits/const-traits/call-generic-method-pass.rs b/tests/ui/traits/const-traits/call-generic-method-pass.rs index aa52a7b9e47..01c5860c8ec 100644 --- a/tests/ui/traits/const-traits/call-generic-method-pass.rs +++ b/tests/ui/traits/const-traits/call-generic-method-pass.rs @@ -3,7 +3,7 @@ //@ compile-flags: -Znext-solver //@ check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_cmp)] struct S; diff --git a/tests/ui/traits/const-traits/const-drop.rs b/tests/ui/traits/const-traits/const-drop.rs index 5df3a77f73a..dc985a8f620 100644 --- a/tests/ui/traits/const-traits/const-drop.rs +++ b/tests/ui/traits/const-traits/const-drop.rs @@ -17,12 +17,10 @@ impl<'a> const Drop for S<'a> { } const fn a<T: [const] Destruct>(_: T) {} -//FIXME ~^ ERROR destructor of const fn b() -> u8 { let mut c = 0; let _ = S(&mut c); - //FIXME ~^ ERROR destructor of a(S(&mut c)); c } diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs index b39f97b5938..bbc0faee10f 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs +++ b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.rs @@ -1,7 +1,7 @@ //@ check-pass #![feature(derive_const)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, const_cmp)] #[derive_const(PartialEq)] pub struct Reverse<T>(T); diff --git a/tests/ui/traits/const-traits/issue-102985.rs b/tests/ui/traits/const-traits/issue-102985.rs index e5394ddd688..ebab6566d4b 100644 --- a/tests/ui/traits/const-traits/issue-102985.rs +++ b/tests/ui/traits/const-traits/issue-102985.rs @@ -1,12 +1,9 @@ -//@ known-bug: #110395 #![feature(const_trait_impl)] struct Bug { inner: [(); match || 1 { n => n(), - //FIXME ~^ ERROR the trait bound - //FIXME ~| ERROR the trait bound - //FIXME ~| ERROR cannot call non-const closure in constants + //~^ ERROR cannot call non-const closure in constants }], } diff --git a/tests/ui/traits/const-traits/issue-102985.stderr b/tests/ui/traits/const-traits/issue-102985.stderr index 7c5c5acf207..8588dc17e70 100644 --- a/tests/ui/traits/const-traits/issue-102985.stderr +++ b/tests/ui/traits/const-traits/issue-102985.stderr @@ -1,5 +1,5 @@ error[E0015]: cannot call non-const closure in constants - --> $DIR/issue-102985.rs:6:14 + --> $DIR/issue-102985.rs:5:14 | LL | n => n(), | ^^^ diff --git a/tests/ui/traits/const-traits/issue-88155.rs b/tests/ui/traits/const-traits/issue-88155.rs index a26128a6ecc..a642e1101c7 100644 --- a/tests/ui/traits/const-traits/issue-88155.rs +++ b/tests/ui/traits/const-traits/issue-88155.rs @@ -1,5 +1,3 @@ -//@ known-bug: #110395 - #![feature(const_trait_impl)] pub trait A { @@ -8,8 +6,7 @@ pub trait A { pub const fn foo<T: A>() -> bool { T::assoc() - //FIXME ~^ ERROR the trait bound - //FIXME ~| ERROR cannot call non-const function + //~^ ERROR cannot call non-const associated function } fn main() {} diff --git a/tests/ui/traits/const-traits/issue-88155.stderr b/tests/ui/traits/const-traits/issue-88155.stderr index 2e140ac9ff6..96a3c4187f5 100644 --- a/tests/ui/traits/const-traits/issue-88155.stderr +++ b/tests/ui/traits/const-traits/issue-88155.stderr @@ -1,5 +1,5 @@ error[E0015]: cannot call non-const associated function `<T as A>::assoc` in constant functions - --> $DIR/issue-88155.rs:10:5 + --> $DIR/issue-88155.rs:8:5 | LL | T::assoc() | ^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs index 86e3e5f769f..d5f80acc15b 100644 --- a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs +++ b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs @@ -1,6 +1,6 @@ -//@ known-bug: #110395 +#![feature(const_trait_impl, const_from)] -#![feature(const_trait_impl)] +//@ check-pass #[const_trait] trait Convert<T> { diff --git a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr deleted file mode 100644 index e7f10e73c69..00000000000 --- a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error: `[const]` can only be applied to `#[const_trait]` traits - --> $DIR/non-const-op-in-closure-in-const.rs:10:44 - | -LL | impl<A, B> const Convert<B> for A where B: [const] From<A> { - | ^^^^^^^ can't be applied to `From` - | -note: `From` can't be used with `[const]` because it isn't annotated with `#[const_trait]` - --> $SRC_DIR/core/src/convert/mod.rs:LL:COL - -error: `[const]` can only be applied to `#[const_trait]` traits - --> $DIR/non-const-op-in-closure-in-const.rs:10:44 - | -LL | impl<A, B> const Convert<B> for A where B: [const] From<A> { - | ^^^^^^^ can't be applied to `From` - | -note: `From` can't be used with `[const]` because it isn't annotated with `#[const_trait]` - --> $SRC_DIR/core/src/convert/mod.rs:LL:COL - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0015]: cannot call non-const associated function `<B as From<A>>::from` in constant functions - --> $DIR/non-const-op-in-closure-in-const.rs:12:9 - | -LL | B::from(self) - | ^^^^^^^^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr index 38e692521ca..cf197d035b3 100644 --- a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr +++ b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr @@ -50,7 +50,7 @@ error: not a function --> $DIR/rustc_must_implement_one_of_misuse.rs:26:5 | LL | const A: u8 = 1; - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ | note: required by this annotation --> $DIR/rustc_must_implement_one_of_misuse.rs:24:1 @@ -63,7 +63,7 @@ error: not a function --> $DIR/rustc_must_implement_one_of_misuse.rs:28:5 | LL | type B; - | ^^^^^^^ + | ^^^^^^ | note: required by this annotation --> $DIR/rustc_must_implement_one_of_misuse.rs:24:1 diff --git a/tests/ui/traits/trait-method-signature-mismatch.rs b/tests/ui/traits/trait-method-signature-mismatch.rs new file mode 100644 index 00000000000..118aff69e4e --- /dev/null +++ b/tests/ui/traits/trait-method-signature-mismatch.rs @@ -0,0 +1,18 @@ +//! This test verifies that implementing a trait method with a signature that does not +//! exactly match its declaration in the trait results in a compilation error. +//! Specifically, it checks for errors when the number of parameters or the return type +//! in the `impl` differs from the trait definition. + +trait Foo { + fn foo(&mut self, x: i32, y: i32) -> i32; +} + +impl Foo for i32 { + fn foo( + &mut self, //~ ERROR method `foo` has 2 parameters but the declaration + x: i32, + ) { + } +} + +fn main() {} diff --git a/tests/ui/trait-method-number-parameters.stderr b/tests/ui/traits/trait-method-signature-mismatch.stderr index cf9b4f2ae79..c7a77aa7aba 100644 --- a/tests/ui/trait-method-number-parameters.stderr +++ b/tests/ui/traits/trait-method-signature-mismatch.stderr @@ -1,5 +1,5 @@ error[E0050]: method `foo` has 2 parameters but the declaration in trait `Foo::foo` has 3 - --> $DIR/trait-method-number-parameters.rs:7:9 + --> $DIR/trait-method-signature-mismatch.rs:12:9 | LL | fn foo(&mut self, x: i32, y: i32) -> i32; | ------------------------- trait requires 3 parameters diff --git a/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr b/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr index 0d7f957a50e..6744899e951 100644 --- a/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr +++ b/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr @@ -5,7 +5,7 @@ LL | impl<'a> Deref for dyn Foo + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref<Target = dyn Bar<u32>>` which conflicts with supertrait `Bar<i32>` LL | LL | type Target = dyn Bar<u32> + 'a; - | -------------------------------- target type is a supertrait of `dyn Foo` + | ----------- target type is a supertrait of `dyn Foo` | note: the lint level is defined here --> $DIR/deref-upcast-shadowing-lint.rs:2:9 diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr index 806c57e44a2..0d43563e1ab 100644 --- a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr +++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr @@ -5,7 +5,7 @@ LL | impl<'a> Deref for dyn Foo<'a> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo<'_>` implements `Deref<Target = dyn Bar<'_>>` which conflicts with supertrait `Bar<'_>` LL | LL | type Target = dyn Bar<'a>; - | -------------------------- target type is a supertrait of `dyn Foo<'_>` + | ----------- target type is a supertrait of `dyn Foo<'_>` | note: the lint level is defined here --> $DIR/migrate-lint-deny-regions.rs:2:9 diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr index 86cff5233ff..a483e98efea 100644 --- a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr +++ b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr @@ -5,7 +5,7 @@ LL | impl<'a> Deref for dyn Foo + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref<Target = dyn Bar<u32>>` which conflicts with supertrait `Bar<i32>` LL | LL | type Target = dyn Bar<u32> + 'a; - | -------------------------------- target type is a supertrait of `dyn Foo` + | ----------- target type is a supertrait of `dyn Foo` | note: the lint level is defined here --> $DIR/migrate-lint-different-substs.rs:2:9 diff --git a/tests/ui/traits/tryfrominterror-result-comparison.rs b/tests/ui/traits/tryfrominterror-result-comparison.rs new file mode 100644 index 00000000000..8a2741e9058 --- /dev/null +++ b/tests/ui/traits/tryfrominterror-result-comparison.rs @@ -0,0 +1,19 @@ +//! This test verifies that `std::num::TryFromIntError` correctly implements `PartialEq`, +//! allowing `Result<T, TryFromIntError>` values to be compared for equality using `==`. +//! It specifically checks a successful numeric conversion scenario where the `Result::Ok` +//! variant is compared, ensuring that the comparison yields the expected boolean result. + +//@ run-pass + +#![allow(unused_must_use)] // Allow ignoring the result of the comparison for the test's purpose + +use std::convert::TryFrom; +use std::num::TryFromIntError; + +fn main() { + let x: u32 = 125; + // Attempt to convert u32 to u8, which should succeed as 125 fits in u8. + let y: Result<u8, TryFromIntError> = u8::try_from(x); + // Verify that the Result can be correctly compared with an Ok value. + y == Ok(125); +} diff --git a/tests/ui/virtual-call-attrs-issue-137646.rs b/tests/ui/traits/virtual-call-parameter-handling.rs index e80bd5768a4..71ed459d15a 100644 --- a/tests/ui/virtual-call-attrs-issue-137646.rs +++ b/tests/ui/traits/virtual-call-parameter-handling.rs @@ -1,5 +1,7 @@ -//! Regression test for https://github.com/rust-lang/rust/issues/137646. -//! The parameter value at all calls to `check` should be `(1, 1, 1)`. +//! This test checks the correct parameter handling during virtual method calls +//! through a `dyn Trait` object. +//! +//! Regression test for: <https://github.com/rust-lang/rust/issues/137646> //@ run-pass diff --git a/tests/ui/transmute-non-immediate-to-immediate.rs b/tests/ui/transmute-non-immediate-to-immediate.rs deleted file mode 100644 index d99bbcc600f..00000000000 --- a/tests/ui/transmute-non-immediate-to-immediate.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -// Issue #7988 -// Transmuting non-immediate type to immediate type - - -pub fn main() { - unsafe { - ::std::mem::transmute::<[isize; 1],isize>([1]) - }; -} diff --git a/tests/ui/transmute/transmute-array-to-scalar.rs b/tests/ui/transmute/transmute-array-to-scalar.rs new file mode 100644 index 00000000000..cd6dbb040c8 --- /dev/null +++ b/tests/ui/transmute/transmute-array-to-scalar.rs @@ -0,0 +1,14 @@ +//! Verify transmuting from a single-element array to a scalar is allowed. +//! +//! Regression test: <https://github.com/rust-lang/rust/issues/7988> + +//@ run-pass + +pub fn main() { + unsafe { + // Transmute a single-element array `[1]` (which might be treated as a "non-immediate" type) + // to a scalar `isize` (an "immediate" type). + // This is safe because `[isize; 1]` and `isize` have the same size and alignment. + ::std::mem::transmute::<[isize; 1], isize>([1]); + } +} diff --git a/tests/ui/transmute-equal-assoc-types.rs b/tests/ui/transmute/transmute-same-associated-type.rs index 526f4ebbffa..8bc452c6df4 100644 --- a/tests/ui/transmute-equal-assoc-types.rs +++ b/tests/ui/transmute/transmute-same-associated-type.rs @@ -1,3 +1,5 @@ +//! Verify transmuting is allowed when `Src` and `Dst` are the same associated type. + //@ check-pass trait Foo { diff --git a/tests/ui/try-from-int-error-partial-eq.rs b/tests/ui/try-from-int-error-partial-eq.rs deleted file mode 100644 index 66a78b3f842..00000000000 --- a/tests/ui/try-from-int-error-partial-eq.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass - -#![allow(unused_must_use)] - -use std::convert::TryFrom; -use std::num::TryFromIntError; - -fn main() { - let x: u32 = 125; - let y: Result<u8, TryFromIntError> = u8::try_from(x); - y == Ok(125); -} diff --git a/tests/ui/try-operator-hygiene.rs b/tests/ui/try-operator-hygiene.rs deleted file mode 100644 index 20538e094c6..00000000000 --- a/tests/ui/try-operator-hygiene.rs +++ /dev/null @@ -1,26 +0,0 @@ -//@ run-pass - -#![allow(non_upper_case_globals)] -#![allow(dead_code)] -// `expr?` expands to: -// -// match expr { -// Ok(val) => val, -// Err(err) => return Err(From::from(err)), -// } -// -// This test verifies that the expansion is hygienic, i.e., it's not affected by other `val` and -// `err` bindings that may be in scope. - -use std::num::ParseIntError; - -fn main() { - assert_eq!(parse(), Ok(1)); -} - -fn parse() -> Result<i32, ParseIntError> { - const val: char = 'a'; - const err: char = 'b'; - - Ok("1".parse::<i32>()?) -} diff --git a/tests/ui/try-trait/try-operator-expansion-hygiene.rs b/tests/ui/try-trait/try-operator-expansion-hygiene.rs new file mode 100644 index 00000000000..b6f4e533d8d --- /dev/null +++ b/tests/ui/try-trait/try-operator-expansion-hygiene.rs @@ -0,0 +1,24 @@ +//! This test verifies that the `?` operator expansion is hygienic, +//! i.e., it's not affected by other `val` and `err` bindings that may be in scope. +//! +//! Note: Prior to the Try trait stabilization, `expr?` expanded to a match +//! with `val` and `err` bindings. The current implementation uses Try::branch() +//! but this test remains relevant for hygiene verification. + +//@ run-pass + +#![allow(non_upper_case_globals)] +#![allow(dead_code)] + +use std::num::ParseIntError; + +fn main() { + assert_eq!(parse(), Ok(1)); +} + +fn parse() -> Result<i32, ParseIntError> { + const val: char = 'a'; + const err: char = 'b'; + + Ok("1".parse::<i32>()?) +} diff --git a/tests/ui/try-operator.rs b/tests/ui/try-trait/try-operator-various-contexts.rs index b9978204557..41c3679c96f 100644 --- a/tests/ui/try-operator.rs +++ b/tests/ui/try-trait/try-operator-various-contexts.rs @@ -1,9 +1,11 @@ +//! Checks the functionality of the `?` operator in various syntactic contexts. + //@ run-pass #![allow(dead_code)] use std::fs::File; -use std::io::{Read, self}; +use std::io::{self, Read}; use std::num::ParseIntError; use std::str::FromStr; @@ -35,7 +37,9 @@ fn on_path() -> Result<i32, ParseIntError> { fn on_macro() -> Result<i32, ParseIntError> { macro_rules! id { - ($e:expr) => { $e } + ($e:expr) => { + $e + }; } Ok(id!("7".parse::<i32>())?) @@ -50,11 +54,14 @@ fn on_parens() -> Result<i32, ParseIntError> { fn on_block() -> Result<i32, ParseIntError> { let x = "9".parse::<i32>(); - Ok({x}?) + Ok({ x }?) } fn on_field() -> Result<i32, ParseIntError> { - struct Pair<A, B> { a: A, b: B } + struct Pair<A, B> { + a: A, + b: B, + } let x = Pair { a: "10".parse::<i32>(), b: 0 }; @@ -89,7 +96,9 @@ fn on_index() -> Result<i32, ParseIntError> { } fn on_args() -> Result<i32, ParseIntError> { - fn sub(x: i32, y: i32) -> i32 { x - y } + fn sub(x: i32, y: i32) -> i32 { + x - y + } let x = "20".parse(); let y = "21".parse(); @@ -98,19 +107,11 @@ fn on_args() -> Result<i32, ParseIntError> { } fn on_if() -> Result<i32, ParseIntError> { - Ok(if true { - "22".parse::<i32>() - } else { - "23".parse::<i32>() - }?) + Ok(if true { "22".parse::<i32>() } else { "23".parse::<i32>() }?) } fn on_if_let() -> Result<i32, ParseIntError> { - Ok(if let Ok(..) = "24".parse::<i32>() { - "25".parse::<i32>() - } else { - "26".parse::<i32>() - }?) + Ok(if let Ok(..) = "24".parse::<i32>() { "25".parse::<i32>() } else { "26".parse::<i32>() }?) } fn on_match() -> Result<i32, ParseIntError> { @@ -121,7 +122,9 @@ fn on_match() -> Result<i32, ParseIntError> { } fn tight_binding() -> Result<bool, ()> { - fn ok<T>(x: T) -> Result<T, ()> { Ok(x) } + fn ok<T>(x: T) -> Result<T, ()> { + Ok(x) + } let x = ok(true); Ok(!x?) diff --git a/tests/ui/tydesc-name.rs b/tests/ui/tydesc-name.rs deleted file mode 100644 index 068a42606c2..00000000000 --- a/tests/ui/tydesc-name.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass - -#![allow(dead_code)] - -use std::any::type_name; - -struct Foo<T> { - x: T -} - -pub fn main() { - assert_eq!(type_name::<isize>(), "isize"); - assert_eq!(type_name::<Foo<usize>>(), "tydesc_name::Foo<usize>"); -} diff --git a/tests/ui/type-inference/type-inference-none-in-generic-ref.rs b/tests/ui/type-inference/type-inference-none-in-generic-ref.rs new file mode 100644 index 00000000000..9c1b7c19e3d --- /dev/null +++ b/tests/ui/type-inference/type-inference-none-in-generic-ref.rs @@ -0,0 +1,9 @@ +//! Checks that unconstrained `None` is rejected through references and generics + +struct S<'a, T: 'a> { + o: &'a Option<T>, +} + +fn main() { + S { o: &None }; //~ ERROR type annotations needed [E0282] +} diff --git a/tests/ui/unconstrained-ref.stderr b/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr index 72fd0202f4e..d671c189b37 100644 --- a/tests/ui/unconstrained-ref.stderr +++ b/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/unconstrained-ref.rs:6:5 + --> $DIR/type-inference-none-in-generic-ref.rs:8:5 | LL | S { o: &None }; | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `S` diff --git a/tests/ui/type-inference/type-inference-unconstrained-none.rs b/tests/ui/type-inference/type-inference-unconstrained-none.rs new file mode 100644 index 00000000000..38a506763c7 --- /dev/null +++ b/tests/ui/type-inference/type-inference-unconstrained-none.rs @@ -0,0 +1,5 @@ +//! Regression test for <https://github.com/rust-lang/rust/issues/5062>. + +fn main() { + None; //~ ERROR type annotations needed [E0282] +} diff --git a/tests/ui/unconstrained-none.stderr b/tests/ui/type-inference/type-inference-unconstrained-none.stderr index 4af6f412e5b..80572b845e8 100644 --- a/tests/ui/unconstrained-none.stderr +++ b/tests/ui/type-inference/type-inference-unconstrained-none.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/unconstrained-none.rs:4:5 + --> $DIR/type-inference-unconstrained-none.rs:4:5 | LL | None; | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` diff --git a/tests/ui/type-namespace.rs b/tests/ui/type-namespace.rs deleted file mode 100644 index 31dc684a214..00000000000 --- a/tests/ui/type-namespace.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -struct A { a: isize } - -fn a(a: A) -> isize { return a.a; } - -pub fn main() { let x: A = A {a: 1}; assert_eq!(a(x), 1); } diff --git a/tests/ui/type-ptr.rs b/tests/ui/type-ptr.rs deleted file mode 100644 index 5c8ed344ab3..00000000000 --- a/tests/ui/type-ptr.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass - -#![allow(dead_code)] - -fn f(a: *const isize) -> *const isize { return a; } - -fn g(a: *const isize) -> *const isize { let b = f(a); return b; } - -pub fn main() { return; } diff --git a/tests/ui/type-use-i1-versus-i8.rs b/tests/ui/type-use-i1-versus-i8.rs deleted file mode 100644 index 4eb25329223..00000000000 --- a/tests/ui/type-use-i1-versus-i8.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass - -use std::ptr; - -pub fn main() { - unsafe { - let mut x: bool = false; - // this line breaks it - ptr::write(&mut x, false); - } -} diff --git a/tests/ui/auxiliary/typeid-intrinsic-aux1.rs b/tests/ui/type/auxiliary/typeid-consistency-aux1.rs index a028008c6ae..a028008c6ae 100644 --- a/tests/ui/auxiliary/typeid-intrinsic-aux1.rs +++ b/tests/ui/type/auxiliary/typeid-consistency-aux1.rs diff --git a/tests/ui/auxiliary/typeid-intrinsic-aux2.rs b/tests/ui/type/auxiliary/typeid-consistency-aux2.rs index a028008c6ae..a028008c6ae 100644 --- a/tests/ui/auxiliary/typeid-intrinsic-aux2.rs +++ b/tests/ui/type/auxiliary/typeid-consistency-aux2.rs diff --git a/tests/ui/type/type-name-basic.rs b/tests/ui/type/type-name-basic.rs new file mode 100644 index 00000000000..9381cb82578 --- /dev/null +++ b/tests/ui/type/type-name-basic.rs @@ -0,0 +1,17 @@ +//! Checks the basic functionality of `std::any::type_name` for primitive types +//! and simple generic structs. + +//@ run-pass + +#![allow(dead_code)] + +use std::any::type_name; + +struct Foo<T> { + x: T, +} + +pub fn main() { + assert_eq!(type_name::<isize>(), "isize"); + assert_eq!(type_name::<Foo<usize>>(), "type_name_basic::Foo<usize>"); +} diff --git a/tests/ui/typeid-intrinsic.rs b/tests/ui/type/typeid-consistency.rs index 7c4fb3f95a9..67ee1b6d839 100644 --- a/tests/ui/typeid-intrinsic.rs +++ b/tests/ui/type/typeid-consistency.rs @@ -1,16 +1,18 @@ +//! Checks the correctness and consistency of `std::any::TypeId::of`. + //@ run-pass #![allow(deprecated)] -//@ aux-build:typeid-intrinsic-aux1.rs -//@ aux-build:typeid-intrinsic-aux2.rs - #![feature(core_intrinsics)] -extern crate typeid_intrinsic_aux1 as other1; -extern crate typeid_intrinsic_aux2 as other2; +//@ aux-build:typeid-consistency-aux1.rs +//@ aux-build:typeid-consistency-aux2.rs + +extern crate typeid_consistency_aux1 as other1; +extern crate typeid_consistency_aux2 as other2; -use std::hash::{SipHasher, Hasher, Hash}; use std::any::TypeId; +use std::hash::{Hash, Hasher, SipHasher}; struct A; struct Test; @@ -34,7 +36,7 @@ pub fn main() { assert_eq!(TypeId::of::<other2::F>(), other2::id_F()); assert_eq!(TypeId::of::<other2::G>(), other2::id_G()); assert_eq!(TypeId::of::<other2::H>(), other2::id_H()); - assert_eq!(TypeId::of::<other1::I>(), other2::id_I()); + assert_eq!(TypeId::of::<other2::I>(), other2::id_I()); assert_eq!(other1::id_F(), other2::id_F()); assert_eq!(other1::id_G(), other2::id_G()); @@ -49,10 +51,8 @@ pub fn main() { assert_eq!(other2::foo::<A>(), other1::foo::<A>()); // sanity test of TypeId - let (a, b, c) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(), - TypeId::of::<Test>()); - let (d, e, f) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(), - TypeId::of::<Test>()); + let (a, b, c) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(), TypeId::of::<Test>()); + let (d, e, f) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(), TypeId::of::<Test>()); assert!(a != b); assert!(a != c); @@ -82,10 +82,7 @@ pub fn main() { assert_ne!(TypeId::of::<other1::I32Iterator>(), TypeId::of::<other1::U32Iterator>()); // Check fn pointer against collisions - assert_ne!( - TypeId::of::<fn(fn(A) -> A) -> A>(), - TypeId::of::<fn(fn() -> A, A) -> A>() - ); + assert_ne!(TypeId::of::<fn(fn(A) -> A) -> A>(), TypeId::of::<fn(fn() -> A, A) -> A>()); assert_ne!( TypeId::of::<for<'a> fn(&'a i32) -> &'a i32>(), TypeId::of::<for<'a> fn(&'a i32) -> &'static i32>() diff --git a/tests/ui/type/unit-type-basic-usages.rs b/tests/ui/type/unit-type-basic-usages.rs new file mode 100644 index 00000000000..c3ee8067f59 --- /dev/null +++ b/tests/ui/type/unit-type-basic-usages.rs @@ -0,0 +1,14 @@ +//! Checks the basic usage of unit type + +//@ run-pass + +fn f(u: ()) { + u +} + +pub fn main() { + let u1: () = (); + let mut _u2: () = f(u1); + _u2 = (); + () +} diff --git a/tests/ui/usize-generic-argument-parent.rs b/tests/ui/type/usize-no-generic-arguments.rs index 4ab80d944a5..d4d1eea757c 100644 --- a/tests/ui/usize-generic-argument-parent.rs +++ b/tests/ui/type/usize-no-generic-arguments.rs @@ -1,3 +1,5 @@ +//! Sanity test that primitives cannot have const generics. + fn foo() { let x: usize<foo>; //~ ERROR const arguments are not allowed on builtin type `usize` } diff --git a/tests/ui/usize-generic-argument-parent.stderr b/tests/ui/type/usize-no-generic-arguments.stderr index 9c081a287ed..f1f3456461f 100644 --- a/tests/ui/usize-generic-argument-parent.stderr +++ b/tests/ui/type/usize-no-generic-arguments.stderr @@ -1,5 +1,5 @@ error[E0109]: const arguments are not allowed on builtin type `usize` - --> $DIR/usize-generic-argument-parent.rs:2:18 + --> $DIR/usize-no-generic-arguments.rs:4:18 | LL | let x: usize<foo>; | ----- ^^^ const argument not allowed diff --git a/tests/ui/typeck/conversion-methods.stderr b/tests/ui/typeck/conversion-methods.stderr index a9b5078ccdd..fa8928f1454 100644 --- a/tests/ui/typeck/conversion-methods.stderr +++ b/tests/ui/typeck/conversion-methods.stderr @@ -2,28 +2,40 @@ error[E0308]: mismatched types --> $DIR/conversion-methods.rs:5:41 | LL | let _tis_an_instants_play: String = "'Tis a fond Ambush—"; - | ------ ^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found `&str` + | ------ ^^^^^^^^^^^^^^^^^^^^^ expected `String`, found `&str` + | | | expected due to this + | +help: try using a conversion method + | +LL | let _tis_an_instants_play: String = "'Tis a fond Ambush—".to_string(); + | ++++++++++++ error[E0308]: mismatched types --> $DIR/conversion-methods.rs:6:40 | LL | let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise"); - | ------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_path_buf()` - | | | - | | expected `PathBuf`, found `&Path` + | ------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `PathBuf`, found `&Path` + | | | expected due to this + | +help: try using a conversion method + | +LL | let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise").to_path_buf(); + | ++++++++++++++ error[E0308]: mismatched types --> $DIR/conversion-methods.rs:9:40 | LL | let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here - | ------ ^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found integer + | ------ ^ expected `String`, found integer + | | | expected due to this + | +help: try using a conversion method + | +LL | let _but_should_the_play: String = 2.to_string(); // Perhaps surprisingly, we suggest .to_string() here + | ++++++++++++ error[E0308]: mismatched types --> $DIR/conversion-methods.rs:12:47 diff --git a/tests/ui/typeck/mismatched-types-ref-binding.rs b/tests/ui/typeck/mismatched-types-ref-binding.rs new file mode 100644 index 00000000000..baf9056dfeb --- /dev/null +++ b/tests/ui/typeck/mismatched-types-ref-binding.rs @@ -0,0 +1,8 @@ +//! Check that a `mismatched types` error (E0308) is correctly reported when attempting to +//! bind a reference to an `i32` to a reference to a `String`. +//! Ensure `ref` bindings report a mismatched type error. + +fn main() { + let var = 10i32; + let ref string: String = var; //~ ERROR mismatched types [E0308] +} diff --git a/tests/ui/typeck/mismatched-types-ref-binding.stderr b/tests/ui/typeck/mismatched-types-ref-binding.stderr new file mode 100644 index 00000000000..c08e5d2a60b --- /dev/null +++ b/tests/ui/typeck/mismatched-types-ref-binding.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/mismatched-types-ref-binding.rs:7:30 + | +LL | let ref string: String = var; + | ^^^ expected `String`, found `i32` + | +help: try using a conversion method + | +LL | let ref string: String = var.to_string(); + | ++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/typeck/tail-return-type-mismatch.rs b/tests/ui/typeck/tail-return-type-mismatch.rs new file mode 100644 index 00000000000..fa0d205ad82 --- /dev/null +++ b/tests/ui/typeck/tail-return-type-mismatch.rs @@ -0,0 +1,14 @@ +//! Test for type mismatch error when returning `usize` from `isize` function. + +fn f() -> isize { + return g(); + //~^ ERROR mismatched types [E0308] +} + +fn g() -> usize { + return 0; +} + +fn main() { + let y = f(); +} diff --git a/tests/ui/typeck/tail-return-type-mismatch.stderr b/tests/ui/typeck/tail-return-type-mismatch.stderr new file mode 100644 index 00000000000..36da65d0304 --- /dev/null +++ b/tests/ui/typeck/tail-return-type-mismatch.stderr @@ -0,0 +1,16 @@ +error[E0308]: mismatched types + --> $DIR/tail-return-type-mismatch.rs:4:12 + | +LL | fn f() -> isize { + | ----- expected `isize` because of return type +LL | return g(); + | ^^^ expected `isize`, found `usize` + | +help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit + | +LL | return g().try_into().unwrap(); + | ++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/unconstrained-none.rs b/tests/ui/unconstrained-none.rs deleted file mode 100644 index e180b3163d4..00000000000 --- a/tests/ui/unconstrained-none.rs +++ /dev/null @@ -1,5 +0,0 @@ -// Issue #5062 - -fn main() { - None; //~ ERROR type annotations needed [E0282] -} diff --git a/tests/ui/unconstrained-ref.rs b/tests/ui/unconstrained-ref.rs deleted file mode 100644 index 473ca954b23..00000000000 --- a/tests/ui/unconstrained-ref.rs +++ /dev/null @@ -1,7 +0,0 @@ -struct S<'a, T:'a> { - o: &'a Option<T> -} - -fn main() { - S { o: &None }; //~ ERROR type annotations needed [E0282] -} diff --git a/tests/ui/underscore-ident-matcher.rs b/tests/ui/underscore-ident-matcher.rs deleted file mode 100644 index 77ec70d43d5..00000000000 --- a/tests/ui/underscore-ident-matcher.rs +++ /dev/null @@ -1,9 +0,0 @@ -macro_rules! identity { - ($i: ident) => ( - $i - ) -} - -fn main() { - let identity!(_) = 10; //~ ERROR no rules expected reserved identifier `_` -} diff --git a/tests/ui/underscore-lifetimes.rs b/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs index a372851f9cf..a2e3c8e26d4 100644 --- a/tests/ui/underscore-lifetimes.rs +++ b/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs @@ -1,6 +1,9 @@ +//! Checks the correct usage and behavior of the anonymous lifetime `'_` (underscore lifetime) + //@ run-pass #![allow(dead_code, mismatched_lifetime_syntaxes)] + struct Foo<'a>(&'a u8); fn foo(x: &u8) -> Foo<'_> { @@ -31,8 +34,5 @@ fn main() { let _ = foo2(x); let _ = foo3(x); foo4(Foo(x)); - let _ = foo5(Foo2 { - a: x, - b: &6, - }); + let _ = foo5(Foo2 { a: x, b: &6 }); } diff --git a/tests/ui/underscore-method-after-integer.rs b/tests/ui/underscore-method-after-integer.rs deleted file mode 100644 index d9eb21894e8..00000000000 --- a/tests/ui/underscore-method-after-integer.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass - -trait Tr : Sized { - fn _method_on_numbers(self) {} -} - -impl Tr for i32 {} - -fn main() { - 42._method_on_numbers(); -} diff --git a/tests/ui/unevaluated_fixed_size_array_len.rs b/tests/ui/unevaluated_fixed_size_array_len.rs deleted file mode 100644 index 6c545913dd9..00000000000 --- a/tests/ui/unevaluated_fixed_size_array_len.rs +++ /dev/null @@ -1,13 +0,0 @@ -// https://github.com/rust-lang/rust/issues/49208 - -trait Foo { - fn foo(); -} - -impl Foo for [(); 1] { - fn foo() {} -} - -fn main() { - <[(); 0] as Foo>::foo() //~ ERROR E0277 -} diff --git a/tests/ui/unit.rs b/tests/ui/unit.rs deleted file mode 100644 index 04404fc3f5e..00000000000 --- a/tests/ui/unit.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ run-pass - -#![allow(unused_assignments)] -#![allow(unknown_lints)] - -#![allow(unused_variables)] -#![allow(dead_assignment)] - -fn f(u: ()) { return u; } - -pub fn main() { - let u1: () = (); - let mut u2: () = f(u1); - u2 = (); - return (); -} diff --git a/tests/ui/unknown-language-item.rs b/tests/ui/unknown-language-item.rs deleted file mode 100644 index ce206d20358..00000000000 --- a/tests/ui/unknown-language-item.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow(unused)] -#![feature(lang_items)] - -#[lang = "foo"] -fn bar() -> ! { -//~^^ ERROR definition of an unknown lang item: `foo` - loop {} -} - -fn main() {} diff --git a/tests/ui/unnamed_argument_mode.rs b/tests/ui/unnamed_argument_mode.rs deleted file mode 100644 index 2014e0d23d8..00000000000 --- a/tests/ui/unnamed_argument_mode.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ run-pass - -fn good(_a: &isize) { -} - -// unnamed argument &isize is now parse x: &isize - -fn called<F>(_f: F) where F: FnOnce(&isize) { -} - -pub fn main() { - called(good); -} diff --git a/tests/ui/unpretty/frontmatter.rs b/tests/ui/unpretty/frontmatter.rs new file mode 100644 index 00000000000..1971808e2a8 --- /dev/null +++ b/tests/ui/unpretty/frontmatter.rs @@ -0,0 +1,10 @@ +--- +--- + +//@ compile-flags: -Zunpretty=normal +//@ check-pass + +#![feature(frontmatter)] + +fn main() { +} diff --git a/tests/ui/unpretty/frontmatter.stdout b/tests/ui/unpretty/frontmatter.stdout new file mode 100644 index 00000000000..2ccbb1b2582 --- /dev/null +++ b/tests/ui/unpretty/frontmatter.stdout @@ -0,0 +1,9 @@ +--- +--- + +//@ compile-flags: -Zunpretty=normal +//@ check-pass + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/unreachable-code-1.rs b/tests/ui/unreachable-code-1.rs deleted file mode 100644 index 9c5f7c8f451..00000000000 --- a/tests/ui/unreachable-code-1.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@ run-pass - -#![allow(unused_must_use)] -#![allow(unreachable_code)] - -#![allow(unused_variables)] -#![allow(dead_code)] - -fn id(x: bool) -> bool { x } - -fn call_id() { - let c = panic!(); - id(c); -} - -fn call_id_3() { id(return) && id(return); } - -pub fn main() { -} diff --git a/tests/ui/uninit-empty-types.rs b/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs index 82474d873b7..e587ca554fe 100644 --- a/tests/ui/uninit-empty-types.rs +++ b/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs @@ -1,6 +1,9 @@ -//@ build-pass -// Test the uninit() construct returning various empty types. +//! This test checks that ZSTs can be safely initialized from +//! `MaybeUninit::uninit().assume_init()` and `std::mem::uninitialized()` +//! (which is deprecated). This is safe because ZSTs inherently +//! require no actual memory initialization, as they occupy no memory. +//@ build-pass use std::mem::MaybeUninit; diff --git a/tests/ui/unsized-locals/unsized-exprs-rpass.rs b/tests/ui/unsized-locals/unsized-exprs-rpass.rs index 54ecd000343..ce31bd63f7c 100644 --- a/tests/ui/unsized-locals/unsized-exprs-rpass.rs +++ b/tests/ui/unsized-locals/unsized-exprs-rpass.rs @@ -18,11 +18,6 @@ impl std::ops::Add<i32> for A<[u8]> { } fn main() { - udrop::<[u8]>(loop { - break *foo(); - }); - udrop::<[u8]>(if true { *foo() } else { *foo() }); - udrop::<[u8]>({ *foo() }); udrop::<[u8]>((*foo())); *afoo() + 42; udrop as fn([u8]); diff --git a/tests/ui/unsized-locals/unsized-exprs.stderr b/tests/ui/unsized-locals/unsized-exprs.stderr index 1b61254870f..0455edbe8e7 100644 --- a/tests/ui/unsized-locals/unsized-exprs.stderr +++ b/tests/ui/unsized-locals/unsized-exprs.stderr @@ -10,7 +10,11 @@ note: required because it appears within the type `A<[u8]>` | LL | struct A<X: ?Sized>(X); | ^ - = note: structs must have a statically known size to be initialized +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-exprs.rs:19:22 + | +LL | udrop::<A<[u8]>>(A { 0: *foo() }); + | ^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/unsized-exprs.rs:21:22 @@ -24,7 +28,11 @@ note: required because it appears within the type `A<[u8]>` | LL | struct A<X: ?Sized>(X); | ^ - = note: the return type of a function must have a statically known size +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-exprs.rs:21:22 + | +LL | udrop::<A<[u8]>>(A(*foo())); + | ^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/unsized-locals/unsized-non-place-exprs.rs b/tests/ui/unsized-locals/unsized-non-place-exprs.rs new file mode 100644 index 00000000000..d724fcf81a4 --- /dev/null +++ b/tests/ui/unsized-locals/unsized-non-place-exprs.rs @@ -0,0 +1,27 @@ +//! `#![feature(unsized_fn_params)]` lets you use unsized function parameters. In particular this +//! is load bearing for `Box<dyn FnOnce()>: FnOnce()`. To do that, borrowck relaxes the requirement +//! that certain places must be `Sized`. But in #142911 we removed alloca support, so these +//! arguments cannot be put in temporaries (or ICE at codegen) That means when `unsized_fn_params` +//! is enabled, we must explicitly check that unsized function arguments are place expressions. +//! +//! Also see tests/ui/unsized_locals/unsized-exprs-rpass.rs + +#![feature(unsized_fn_params)] + +fn foo() -> Box<[u8]> { + Box::new(*b"foo") +} + +fn udrop<T: ?Sized>(_x: T) {} + +fn main(){ + // NB The ordering of the following operations matters, otherwise errors get swallowed somehow. + + udrop::<[u8]>(if true { *foo() } else { *foo() }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time + udrop::<[u8]>({ *foo() }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time + udrop(match foo() { x => *x }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time + udrop::<[u8]>({ loop { break *foo(); } }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time + + { *foo() }; //~ERROR the size for values of type `[u8]` cannot be known at compilation time + { loop { break *foo(); } }; //~ERROR the size for values of type `[u8]` cannot be known at compilation time +} diff --git a/tests/ui/unsized-locals/unsized-non-place-exprs.stderr b/tests/ui/unsized-locals/unsized-non-place-exprs.stderr new file mode 100644 index 00000000000..f9507e9a888 --- /dev/null +++ b/tests/ui/unsized-locals/unsized-non-place-exprs.stderr @@ -0,0 +1,81 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:20:19 + | +LL | udrop::<[u8]>(if true { *foo() } else { *foo() }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:20:19 + | +LL | udrop::<[u8]>(if true { *foo() } else { *foo() }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:21:19 + | +LL | udrop::<[u8]>({ *foo() }); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:21:19 + | +LL | udrop::<[u8]>({ *foo() }); + | ^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:22:11 + | +LL | udrop(match foo() { x => *x }); + | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:22:11 + | +LL | udrop(match foo() { x => *x }); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:23:19 + | +LL | udrop::<[u8]>({ loop { break *foo(); } }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:23:19 + | +LL | udrop::<[u8]>({ loop { break *foo(); } }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:25:5 + | +LL | { *foo() }; + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:25:5 + | +LL | { *foo() }; + | ^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:26:5 + | +LL | { loop { break *foo(); } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:26:5 + | +LL | { loop { break *foo(); } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unused-move.rs b/tests/ui/unused-move.rs deleted file mode 100644 index 3d5eff2c48d..00000000000 --- a/tests/ui/unused-move.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass -// Issue #3878 -// Issue Name: Unused move causes a crash -// Abstract: zero-fill to block after drop - - -#![allow(path_statements)] - -pub fn main() { - let y: Box<_> = Box::new(1); - y; -} diff --git a/tests/ui/use-import-export.rs b/tests/ui/use-import-export.rs deleted file mode 100644 index d948ffc1520..00000000000 --- a/tests/ui/use-import-export.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass - -mod foo { - pub fn x() -> isize { return 1; } -} - -mod bar { - pub fn y() -> isize { return 1; } -} - -pub fn main() { foo::x(); bar::y(); } diff --git a/tests/ui/use-module-level-int-consts.rs b/tests/ui/use-module-level-int-consts.rs deleted file mode 100644 index 6e8c7053c57..00000000000 --- a/tests/ui/use-module-level-int-consts.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass - -// Make sure the module level constants are still there and accessible even after -// the corresponding associated constants have been added, and later stabilized. -#![allow(deprecated, deprecated_in_future)] -use std::{u16, f32}; - -fn main() { - let _ = u16::MAX; - let _ = f32::EPSILON; - let _ = std::f64::MANTISSA_DIGITS; -} diff --git a/tests/ui/walk-struct-literal-with.rs b/tests/ui/walk-struct-literal-with.rs deleted file mode 100644 index ee1a77eb9a4..00000000000 --- a/tests/ui/walk-struct-literal-with.rs +++ /dev/null @@ -1,17 +0,0 @@ -struct Mine{ - test: String, - other_val: isize -} - -impl Mine{ - fn make_string_bar(mut self) -> Mine{ - self.test = "Bar".to_string(); - self - } -} - -fn main(){ - let start = Mine{test:"Foo".to_string(), other_val:0}; - let end = Mine{other_val:1, ..start.make_string_bar()}; - println!("{}", start.test); //~ ERROR borrow of moved value: `start` -} diff --git a/tests/ui/weak-new-uninhabited-issue-48493.rs b/tests/ui/weak-new-uninhabited-issue-48493.rs deleted file mode 100644 index ce7d5786b41..00000000000 --- a/tests/ui/weak-new-uninhabited-issue-48493.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -fn main() { - enum Void {} - let _ = std::rc::Weak::<Void>::new(); - let _ = std::sync::Weak::<Void>::new(); -} diff --git a/tests/ui/weird-exit-code.rs b/tests/ui/weird-exit-code.rs deleted file mode 100644 index e016343f8ba..00000000000 --- a/tests/ui/weird-exit-code.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ run-pass -// On Windows the GetExitCodeProcess API is used to get the exit code of a -// process, but it's easy to mistake a process exiting with the code 259 as -// "still running" because this is the value of the STILL_ACTIVE constant. Make -// sure we handle this case in the standard library and correctly report the -// status. -// -// Note that this is disabled on unix as processes exiting with 259 will have -// their exit status truncated to 3 (only the lower 8 bits are used). - -#[cfg(windows)] -fn main() { - use std::process::{self, Command}; - use std::env; - - if env::args().len() == 1 { - let status = Command::new(env::current_exe().unwrap()) - .arg("foo") - .status() - .unwrap(); - assert_eq!(status.code(), Some(259)); - } else { - process::exit(259); - } -} - -#[cfg(not(windows))] -fn main() {} diff --git a/triagebot.toml b/triagebot.toml index 9f8ea2dad52..125617fce74 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -171,6 +171,19 @@ adjusting release notes. Could you take a look if available? Thanks <3 [prioritize] label = "I-prioritize" +[autolabel."S-waiting-on-review"] +new_pr = true + +[autolabel."S-waiting-on-author"] +new_draft = true + +[autolabel."needs-triage"] +new_issue = true +exclude_labels = [ + "C-tracking-issue", + "A-diagnostics", +] + [autolabel."I-prioritize"] trigger_labels = [ "regression-untriaged", @@ -216,7 +229,6 @@ trigger_files = [ exclude_labels = [ "T-*", ] - trigger_labels = [ "A-rustdoc-json", "A-rustdoc-type-layout", @@ -265,7 +277,6 @@ trigger_labels = [ "A-rustdoc-ui", "A-rustdoc-js", ] - trigger_files = [ "src/librustdoc/html/", "tests/rustdoc/", @@ -281,7 +292,6 @@ trigger_files = [ "tests/rustdoc-js/", "tests/rustdoc-js-std", ] - trigger_labels = [ "A-type-based-search", ] @@ -311,20 +321,17 @@ trigger_files = [ exclude_labels = [ "T-*", ] - trigger_labels = [ "D-*", "A-diagnostics", ] [autolabel."A-diagnostics"] - trigger_labels = [ "D-*", ] [autolabel."A-lints"] - trigger_labels = [ "L-*", ] @@ -532,19 +539,6 @@ trigger_files = [ "src/version" ] -[autolabel."S-waiting-on-review"] -new_pr = true - -[autolabel."S-waiting-on-author"] -new_draft = true - -[autolabel."needs-triage"] -new_issue = true -exclude_labels = [ - "C-tracking-issue", - "A-diagnostics", -] - [autolabel."WG-trait-system-refactor"] trigger_files = [ "compiler/rustc_next_trait_solver", @@ -600,6 +594,10 @@ trigger_files = [ "compiler/rustc_codegen_llvm", ] +[autolabel."T-clippy"] +trigger_files = [ + "src/tools/clippy", +] # ------------------------------------------------------------------------------ # Prioritization and team nominations |
