diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 5f8941d4754e6..dc00b52a59360 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -294,7 +294,7 @@ impl DefKind { DefKind::GlobalAsm => DefPathData::GlobalAsm, DefKind::Impl { .. } => DefPathData::Impl, DefKind::Closure => DefPathData::Closure, - DefKind::SyntheticCoroutineBody => DefPathData::Closure, + DefKind::SyntheticCoroutineBody => DefPathData::SyntheticCoroutineBody, } } diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 61f5efd9978c3..c52954aa96fc8 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -291,6 +291,8 @@ pub enum DefPathData { /// An existential `impl Trait` type node. /// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name. OpaqueTy, + /// A synthetic body for a coroutine's by-move body. + SyntheticCoroutineBody, } impl Definitions { @@ -415,8 +417,16 @@ impl DefPathData { ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), - Impl | ForeignMod | CrateRoot | Use | GlobalAsm | Closure | Ctor | AnonConst - | OpaqueTy => None, + Impl + | ForeignMod + | CrateRoot + | Use + | GlobalAsm + | Closure + | Ctor + | AnonConst + | OpaqueTy + | SyntheticCoroutineBody => None, } } @@ -441,6 +451,7 @@ impl DefPathData { Ctor => DefPathDataName::Anon { namespace: sym::constructor }, AnonConst => DefPathDataName::Anon { namespace: sym::constant }, OpaqueTy => DefPathDataName::Anon { namespace: sym::opaque }, + SyntheticCoroutineBody => DefPathDataName::Anon { namespace: sym::synthetic }, } } } diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 0cc72a261a5a3..00da1a6aeec7d 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -172,6 +172,8 @@ impl CodegenFnAttrs { /// * `#[no_mangle]` is present /// * `#[export_name(...)]` is present /// * `#[linkage]` is present + /// + /// Keep this in sync with the logic for the unused_attributes for `#[inline]` lint. pub fn contains_extern_indicator(&self) -> bool { self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 83ada5c8afb3e..1ffe958dbdd0e 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -150,6 +150,7 @@ impl<'tcx> MonoItem<'tcx> { // If the function is #[naked] or contains any other attribute that requires exactly-once // instantiation: + // We emit an unused_attributes lint for this case, which should be kept in sync if possible. let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id()); if codegen_fn_attrs.contains_extern_indicator() || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 811bd8fb4588a..aa2ee756bc502 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -95,10 +95,16 @@ pub type EvaluationCache<'tcx, ENV> = Cache<(ENV, ty::PolyTraitPredicate<'tcx>), /// parameter environment. #[derive(PartialEq, Eq, Debug, Clone, TypeVisitable)] pub enum SelectionCandidate<'tcx> { + /// A built-in implementation for the `Sized` trait. This is preferred + /// over all other candidates. + SizedCandidate { + has_nested: bool, + }, + /// A builtin implementation for some specific traits, used in cases /// where we cannot rely an ordinary library implementations. /// - /// The most notable examples are `sized`, `Copy` and `Clone`. This is also + /// The most notable examples are `Copy` and `Clone`. This is also /// used for the `DiscriminantKind` and `Pointee` trait, both of which have /// an associated type. BuiltinCandidate { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 08d4c1f9cf2f3..618a65a018644 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1930,10 +1930,10 @@ impl<'tcx> TyCtxt<'tcx> { // As a consequence, this LocalDefId is always re-created before it is needed by the incr. // comp. engine itself. // - // This call also writes to the value of `source_span` and `expn_that_defined` queries. + // This call also writes to the value of the `source_span` query. // This is fine because: - // - those queries are `eval_always` so we won't miss their result changing; - // - this write will have happened before these queries are called. + // - that query is `eval_always` so we won't miss its result changing; + // - this write will have happened before that query is called. let def_id = self.untracked.definitions.write().create_def(parent, data); // This function modifies `self.definitions` using a side-effect. diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index dc2040aa5cf85..5904deaaaad83 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -139,8 +139,7 @@ pub trait Printer<'tcx>: Sized { match key.disambiguated_data.data { DefPathData::Closure => { - // FIXME(async_closures): This is somewhat ugly. - // We need to additionally print the `kind` field of a closure if + // We need to additionally print the `kind` field of a coroutine if // it is desugared from a coroutine-closure. if let Some(hir::CoroutineKind::Desugared( _, @@ -156,6 +155,10 @@ pub trait Printer<'tcx>: Sized { // Closures' own generics are only captures, don't print them. } } + DefPathData::SyntheticCoroutineBody => { + // Synthetic coroutine bodies have no distinct generics, since like + // closures they're all just internal state of the coroutine. + } // This covers both `DefKind::AnonConst` and `DefKind::InlineConst`. // Anon consts doesn't have their own generics, and inline consts' own // generics are their inferred types, so don't print them. diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index f813c3380fcbd..1b4341ec28d1a 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -810,16 +810,16 @@ pub(crate) enum WrapInParentheses { #[derive(Diagnostic)] #[diag(parse_array_brackets_instead_of_braces)] -pub(crate) struct ArrayBracketsInsteadOfSpaces { +pub(crate) struct ArrayBracketsInsteadOfBraces { #[primary_span] pub span: Span, #[subdiagnostic] - pub sub: ArrayBracketsInsteadOfSpacesSugg, + pub sub: ArrayBracketsInsteadOfBracesSugg, } #[derive(Subdiagnostic)] #[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")] -pub(crate) struct ArrayBracketsInsteadOfSpacesSugg { +pub(crate) struct ArrayBracketsInsteadOfBracesSugg { #[suggestion_part(code = "[")] pub left: Span, #[suggestion_part(code = "]")] diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 92e83577f1b13..00e75cc2c2fc1 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2200,7 +2200,9 @@ impl<'a> Parser<'a> { } fn is_array_like_block(&mut self) -> bool { - self.look_ahead(1, |t| matches!(t.kind, TokenKind::Ident(..) | TokenKind::Literal(_))) + matches!(self.token.kind, TokenKind::OpenDelim(Delimiter::Brace)) + && self + .look_ahead(1, |t| matches!(t.kind, TokenKind::Ident(..) | TokenKind::Literal(_))) && self.look_ahead(2, |t| t == &token::Comma) && self.look_ahead(3, |t| t.can_begin_expr()) } @@ -2212,9 +2214,9 @@ impl<'a> Parser<'a> { let mut snapshot = self.create_snapshot_for_diagnostic(); match snapshot.parse_expr_array_or_repeat(exp!(CloseBrace)) { Ok(arr) => { - let guar = self.dcx().emit_err(errors::ArrayBracketsInsteadOfSpaces { + let guar = self.dcx().emit_err(errors::ArrayBracketsInsteadOfBraces { span: arr.span, - sub: errors::ArrayBracketsInsteadOfSpacesSugg { + sub: errors::ArrayBracketsInsteadOfBracesSugg { left: lo, right: snapshot.prev_token.span, }, @@ -2337,7 +2339,8 @@ impl<'a> Parser<'a> { let capture_clause = self.parse_capture_clause()?; let (fn_decl, fn_arg_span) = self.parse_fn_block_decl()?; let decl_hi = self.prev_token.span; - let mut body = match fn_decl.output { + let mut body = match &fn_decl.output { + // No return type. FnRetTy::Default(_) => { let restrictions = self.restrictions - Restrictions::STMT_EXPR - Restrictions::ALLOW_LET; @@ -2349,11 +2352,8 @@ impl<'a> Parser<'a> { Err(err) => self.recover_closure_body(err, before, prev, token, lo, decl_hi)?, } } - _ => { - // If an explicit return type is given, require a block to appear (RFC 968). - let body_lo = self.token.span; - self.parse_expr_block(None, body_lo, BlockCheckMode::Default)? - } + // Explicit return type (`->`) needs block `-> T { }`. + FnRetTy::Ty(ty) => self.parse_closure_block_body(ty.span)?, }; match coroutine_kind { @@ -2405,6 +2405,49 @@ impl<'a> Parser<'a> { Ok(closure) } + /// If an explicit return type is given, require a block to appear (RFC 968). + fn parse_closure_block_body(&mut self, ret_span: Span) -> PResult<'a, P> { + if self.may_recover() + && self.token.can_begin_expr() + && !matches!(self.token.kind, TokenKind::OpenDelim(Delimiter::Brace)) + && !self.token.is_whole_block() + { + let snapshot = self.create_snapshot_for_diagnostic(); + let restrictions = + self.restrictions - Restrictions::STMT_EXPR - Restrictions::ALLOW_LET; + let tok = self.token.clone(); + match self.parse_expr_res(restrictions, AttrWrapper::empty()) { + Ok((expr, _)) => { + let descr = super::token_descr(&tok); + let mut diag = self + .dcx() + .struct_span_err(tok.span, format!("expected `{{`, found {descr}")); + diag.span_label( + ret_span, + "explicit return type requires closure body to be enclosed in braces", + ); + diag.multipart_suggestion_verbose( + "wrap the expression in curly braces", + vec![ + (expr.span.shrink_to_lo(), "{ ".to_string()), + (expr.span.shrink_to_hi(), " }".to_string()), + ], + Applicability::MachineApplicable, + ); + diag.emit(); + return Ok(expr); + } + Err(diag) => { + diag.cancel(); + self.restore_snapshot(snapshot); + } + } + } + + let body_lo = self.token.span; + self.parse_expr_block(None, body_lo, BlockCheckMode::Default) + } + /// Parses an optional `move` or `use` prefix to a closure-like construct. fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> { if self.eat_keyword(exp!(Move)) { diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 06398dd4f725b..bea86801ed753 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -383,6 +383,10 @@ passes_inline_ignored_constants = .warn = {-passes_previously_accepted} .note = {-passes_see_issue(issue: "65833")} +passes_inline_ignored_for_exported = + `#[inline]` is ignored on externally exported functions + .help = externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]` + passes_inline_ignored_function_prototype = `#[inline]` is ignored on function prototypes diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 1e1fb42a48fe2..ada3151c3b8c1 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -451,6 +451,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }); } } + + // `#[inline]` is ignored if the symbol must be codegened upstream because it's exported. + if let Some(did) = hir_id.as_owner() + && self.tcx.def_kind(did).has_codegen_attrs() + && !matches!(attr.meta_item_list().as_deref(), Some([item]) if item.has_name(sym::never)) + { + let attrs = self.tcx.codegen_fn_attrs(did); + // Not checking naked as `#[inline]` is forbidden for naked functions anyways. + if attrs.contains_extern_indicator() { + self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr.span(), + errors::InlineIgnoredForExported {}, + ); + } + } } /// Checks that `#[coverage(..)]` is applied to a function/closure/method, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 0ee17430aab8e..4e3e0324205a4 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1441,6 +1441,11 @@ pub(crate) struct OnlyHasEffectOn { pub target_name: String, } +#[derive(LintDiagnostic)] +#[diag(passes_inline_ignored_for_exported)] +#[help] +pub(crate) struct InlineIgnoredForExported {} + #[derive(Diagnostic)] #[diag(passes_object_lifetime_err)] pub(crate) struct ObjectLifetimeErr { diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 495f34733f704..127dcd825da56 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -66,6 +66,7 @@ pub struct MarkFrame<'a> { parent: Option<&'a MarkFrame<'a>>, } +#[derive(Debug)] pub(super) enum DepNodeColor { Red, Green(DepNodeIndex), @@ -909,7 +910,7 @@ impl DepGraphData { self.try_mark_previous_green(qcx, parent_dep_node_index, dep_dep_node, frame); if node_index.is_some() { - debug!("managed to MARK dependency {dep_dep_node:?} as green",); + debug!("managed to MARK dependency {dep_dep_node:?} as green"); return Some(()); } } @@ -930,7 +931,7 @@ impl DepGraphData { return Some(()); } Some(DepNodeColor::Red) => { - debug!("dependency {dep_dep_node:?} was red after forcing",); + debug!("dependency {dep_dep_node:?} was red after forcing"); return None; } None => {} @@ -950,7 +951,7 @@ impl DepGraphData { // invalid state will not be persisted to the // incremental compilation cache because of // compilation errors being present. - debug!("dependency {dep_dep_node:?} resulted in compilation error",); + debug!("dependency {dep_dep_node:?} resulted in compilation error"); return None; } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index e088417d72e35..d56ca9c245386 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -716,6 +716,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String { hir::definitions::DefPathData::Ctor => "c", hir::definitions::DefPathData::AnonConst => "k", hir::definitions::DefPathData::OpaqueTy => "i", + hir::definitions::DefPathData::SyntheticCoroutineBody => "s", hir::definitions::DefPathData::CrateRoot | hir::definitions::DefPathData::Use | hir::definitions::DefPathData::GlobalAsm diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 88754f1f15b46..2802e8918073f 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -28,7 +28,10 @@ pub(super) fn mangle<'tcx>( loop { let key = tcx.def_key(ty_def_id); match key.disambiguated_data.data { - DefPathData::TypeNs(_) | DefPathData::ValueNs(_) | DefPathData::Closure => { + DefPathData::TypeNs(_) + | DefPathData::ValueNs(_) + | DefPathData::Closure + | DefPathData::SyntheticCoroutineBody => { instance_ty = tcx.type_of(ty_def_id).instantiate_identity(); debug!(?instance_ty); break; diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index d824a23279b1b..99d44bcd7eb80 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -850,6 +850,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { DefPathData::Ctor => 'c', DefPathData::AnonConst => 'k', DefPathData::OpaqueTy => 'i', + DefPathData::SyntheticCoroutineBody => 's', // These should never show up as `path_append` arguments. DefPathData::CrateRoot diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 4cfd8149b1e95..d15c9afef3abc 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -86,10 +86,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // `Pointee` is automatically implemented for every type. candidates.vec.push(BuiltinCandidate { has_nested: false }); } else if tcx.is_lang_item(def_id, LangItem::Sized) { - // Sized is never implementable by end-users, it is - // always automatically computed. - let sized_conditions = self.sized_conditions(obligation); - self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates); + self.assemble_builtin_sized_candidate(obligation, &mut candidates); } else if tcx.is_lang_item(def_id, LangItem::Unsize) { self.assemble_candidates_for_unsizing(obligation, &mut candidates); } else if tcx.is_lang_item(def_id, LangItem::Destruct) { @@ -1061,6 +1058,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Assembles the trait which are built-in to the language itself: /// `Copy`, `Clone` and `Sized`. #[instrument(level = "debug", skip(self, candidates))] + fn assemble_builtin_sized_candidate( + &mut self, + obligation: &PolyTraitObligation<'tcx>, + candidates: &mut SelectionCandidateSet<'tcx>, + ) { + match self.sized_conditions(obligation) { + BuiltinImplConditions::Where(nested) => { + candidates + .vec + .push(SizedCandidate { has_nested: !nested.skip_binder().is_empty() }); + } + BuiltinImplConditions::None => {} + BuiltinImplConditions::Ambiguous => { + candidates.ambiguous = true; + } + } + } + + /// Assembles the trait which are built-in to the language itself: + /// e.g. `Copy` and `Clone`. + #[instrument(level = "debug", skip(self, candidates))] fn assemble_builtin_bound_candidates( &mut self, conditions: BuiltinImplConditions<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index a66c958c10978..630241725fdb2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -40,6 +40,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidate: SelectionCandidate<'tcx>, ) -> Result, SelectionError<'tcx>> { let mut impl_src = match candidate { + SizedCandidate { has_nested } => { + let data = self.confirm_builtin_candidate(obligation, has_nested); + ImplSource::Builtin(BuiltinImplSource::Misc, data) + } + BuiltinCandidate { has_nested } => { let data = self.confirm_builtin_candidate(obligation, has_nested); ImplSource::Builtin(BuiltinImplSource::Misc, data) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e439df76cd4b9..0679dbf1296af 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1801,17 +1801,21 @@ impl<'tcx> SelectionContext<'_, 'tcx> { return Some(candidates.pop().unwrap().candidate); } - // We prefer trivial builtin candidates, i.e. builtin impls without any nested - // requirements, over all others. This is a fix for #53123 and prevents winnowing - // from accidentally extending the lifetime of a variable. - let mut trivial_builtin = candidates - .iter() - .filter(|c| matches!(c.candidate, BuiltinCandidate { has_nested: false })); - if let Some(_trivial) = trivial_builtin.next() { - // There should only ever be a single trivial builtin candidate + // We prefer `Sized` candidates over everything. + let mut sized_candidates = + candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate { has_nested: _ })); + if let Some(sized_candidate) = sized_candidates.next() { + // There should only ever be a single sized candidate // as they would otherwise overlap. - debug_assert_eq!(trivial_builtin.next(), None); - return Some(BuiltinCandidate { has_nested: false }); + debug_assert_eq!(sized_candidates.next(), None); + // Only prefer the built-in `Sized` candidate if its nested goals are certain. + // Otherwise, we may encounter failure later on if inference causes this candidate + // to not hold, but a where clause would've applied instead. + if sized_candidate.evaluation.must_apply_modulo_regions() { + return Some(sized_candidate.candidate.clone()); + } else { + return None; + } } // Before we consider where-bounds, we have to deduplicate them here and also @@ -1940,7 +1944,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // Don't use impl candidates which overlap with other candidates. // This should pretty much only ever happen with malformed impls. if candidates.iter().all(|c| match c.candidate { - BuiltinCandidate { has_nested: _ } + SizedCandidate { has_nested: _ } + | BuiltinCandidate { has_nested: _ } | TransmutabilityCandidate | AutoImplCandidate | ClosureCandidate { .. } diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 89c856fe10746..ba4c849837e74 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -127,15 +127,13 @@ mod prim_bool {} /// [`Result`] which we can unpack like this: /// /// ``` -/// #![feature(exhaustive_patterns)] /// use std::str::FromStr; /// let Ok(s) = String::from_str("hello"); /// ``` /// -/// Since the [`Err`] variant contains a `!`, it can never occur. If the `exhaustive_patterns` -/// feature is present this means we can exhaustively match on [`Result`] by just taking the -/// [`Ok`] variant. This illustrates another behavior of `!` - it can be used to "delete" certain -/// enum variants from generic types like `Result`. +/// Since the [`Err`] variant contains a `!`, it can never occur. This means we can exhaustively +/// match on [`Result`] by just taking the [`Ok`] variant. This illustrates another behavior +/// of `!` - it can be used to "delete" certain enum variants from generic types like `Result`. /// /// ## Infinite loops /// diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map index 9144a938a9e24..0e1d987783075 100644 --- a/tests/coverage/async_closure.cov-map +++ b/tests/coverage/async_closure.cov-map @@ -38,21 +38,21 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36) Highest counter ID seen: c0 -Function name: async_closure::main::{closure#0}::{closure#0}:: -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24] +Function name: async_closure::main::{closure#0} +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 23, 00, 24] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36) +- Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36) Highest counter ID seen: c0 -Function name: async_closure::main::{closure#0}::{closure#1}:: -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 23, 00, 24] +Function name: async_closure::main::{closure#0}::{closure#0}:: +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36) +- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36) Highest counter ID seen: c0 diff --git a/tests/coverage/async_closure.coverage b/tests/coverage/async_closure.coverage index 7fbea26581258..10a8ea14504b3 100644 --- a/tests/coverage/async_closure.coverage +++ b/tests/coverage/async_closure.coverage @@ -14,7 +14,7 @@ | async_closure::main::{closure#0}: | LL| 1| let async_closure = async || {}; ------------------ - | async_closure::main::{closure#0}::{closure#1}::: + | async_closure::main::{closure#0}: | LL| 1| let async_closure = async || {}; ------------------ LL| 1| executor::block_on(async_closure()); diff --git a/tests/incremental/user-written-closure-synthetic-closure-conflict.rs b/tests/incremental/user-written-closure-synthetic-closure-conflict.rs new file mode 100644 index 0000000000000..618604d06b173 --- /dev/null +++ b/tests/incremental/user-written-closure-synthetic-closure-conflict.rs @@ -0,0 +1,15 @@ +//@ revisions: rpass1 rpass2 +//@ edition: 2024 + +#![allow(unused)] + +fn main() { + #[cfg(rpass1)] + async || {}; + + #[cfg(rpass2)] + || { + || (); + || (); + }; +} diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir similarity index 85% rename from tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir rename to tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir index bd0baddb1f892..9070c95bca4d4 100644 --- a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir +++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir @@ -1,6 +1,6 @@ -// MIR for `foo::{closure#0}::{closure#1}` after built +// MIR for `foo::{closure#0}::{synthetic#0}` after built -fn foo::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: ResumeTy) -> () +fn foo::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.rs b/tests/mir-opt/async_closure_fake_read_for_by_move.rs index 3c5aec94bbfe5..e78671f5e9d56 100644 --- a/tests/mir-opt/async_closure_fake_read_for_by_move.rs +++ b/tests/mir-opt/async_closure_fake_read_for_by_move.rs @@ -7,7 +7,7 @@ enum Foo { } // EMIT_MIR async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir -// EMIT_MIR async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir +// EMIT_MIR async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir fn foo(f: &Foo) { let x = async move || match f { Foo::Bar if true => {} diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir similarity index 80% rename from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir rename to tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir index a9e08d2e8f60f..c5f538e5ecd83 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir @@ -1,6 +1,6 @@ -// MIR for `main::{closure#0}::{closure#0}::{closure#1}` after built +// MIR for `main::{closure#0}::{closure#0}::{synthetic#0}` after built -fn main::{closure#0}::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir similarity index 80% rename from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir rename to tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir index 4452ae7812e36..e295f9b3cf120 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir @@ -1,6 +1,6 @@ -// MIR for `main::{closure#0}::{closure#1}::{closure#1}` after built +// MIR for `main::{closure#0}::{closure#1}::{synthetic#0}` after built -fn main::{closure#0}::{closure#1}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#1}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.rs b/tests/mir-opt/async_closure_shims.rs index cd2e83e939abe..93cc7834a643f 100644 --- a/tests/mir-opt/async_closure_shims.rs +++ b/tests/mir-opt/async_closure_shims.rs @@ -42,11 +42,11 @@ async fn call_normal_mut>(f: &mut impl FnMut(i32) -> F) { // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir -// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir +// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir -// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir +// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir pub fn main() { block_on(async { let b = 2i32; diff --git a/tests/ui/lint/inline-exported.rs b/tests/ui/lint/inline-exported.rs new file mode 100644 index 0000000000000..69e322ef513ae --- /dev/null +++ b/tests/ui/lint/inline-exported.rs @@ -0,0 +1,30 @@ +//! Ensure the unused_attributes lint fires for externally exported functions with `#[inline]`, +//! because `#[inline]` is ignored for such functions. + +#![crate_type = "lib"] + +#![feature(linkage)] +#![feature(naked_functions)] +#![deny(unused_attributes)] + +#[inline] +//~^ ERROR: `#[inline]` is ignored on externally exported functions +#[no_mangle] +fn no_mangle() {} + +#[inline] +//~^ ERROR: `#[inline]` is ignored on externally exported functions +#[export_name = "export_name"] +fn export_name() {} + +#[inline] +//~^ ERROR: `#[inline]` is ignored on externally exported functions +#[linkage = "external"] +fn external_linkage() {} + +#[inline] +fn normal() {} + +#[inline] +#[linkage = "internal"] // not exported +fn internal_linkage() {} diff --git a/tests/ui/lint/inline-exported.stderr b/tests/ui/lint/inline-exported.stderr new file mode 100644 index 0000000000000..dcf63cc4090e4 --- /dev/null +++ b/tests/ui/lint/inline-exported.stderr @@ -0,0 +1,31 @@ +error: `#[inline]` is ignored on externally exported functions + --> $DIR/inline-exported.rs:10:1 + | +LL | #[inline] + | ^^^^^^^^^ + | + = help: externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]` +note: the lint level is defined here + --> $DIR/inline-exported.rs:8:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: `#[inline]` is ignored on externally exported functions + --> $DIR/inline-exported.rs:15:1 + | +LL | #[inline] + | ^^^^^^^^^ + | + = help: externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]` + +error: `#[inline]` is ignored on externally exported functions + --> $DIR/inline-exported.rs:20:1 + | +LL | #[inline] + | ^^^^^^^^^ + | + = help: externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/parser/closure-return-syntax.rs b/tests/ui/parser/closure-return-syntax.rs index c6a08abeff4ba..6865d8c5393d4 100644 --- a/tests/ui/parser/closure-return-syntax.rs +++ b/tests/ui/parser/closure-return-syntax.rs @@ -1,7 +1,21 @@ // Test that we cannot parse a closure with an explicit return type // unless it uses braces. -fn main() { +fn needs_braces_1() { let x = || -> i32 22; //~^ ERROR expected `{`, found `22` } + +// Check other delimiters too. + +fn needs_braces_2() { + let x = || -> (i32, i32) (1, 2); + //~^ ERROR expected `{`, found `(` +} + +fn needs_braces_3() { + let c = || -> [i32; 2] [1, 2]; + //~^ ERROR expected `{`, found `[` +} + +fn main() {} diff --git a/tests/ui/parser/closure-return-syntax.stderr b/tests/ui/parser/closure-return-syntax.stderr index aacc31ed871d3..763f19ccc6454 100644 --- a/tests/ui/parser/closure-return-syntax.stderr +++ b/tests/ui/parser/closure-return-syntax.stderr @@ -2,12 +2,40 @@ error: expected `{`, found `22` --> $DIR/closure-return-syntax.rs:5:23 | LL | let x = || -> i32 22; - | ^^ expected `{` + | --- ^^ + | | + | explicit return type requires closure body to be enclosed in braces | -help: you might have meant to write this as part of a block +help: wrap the expression in curly braces | LL | let x = || -> i32 { 22 }; | + + -error: aborting due to 1 previous error +error: expected `{`, found `(` + --> $DIR/closure-return-syntax.rs:12:34 + | +LL | let x = || -> (i32, i32) (1, 2); + | ---------- ^ + | | + | explicit return type requires closure body to be enclosed in braces + | +help: wrap the expression in curly braces + | +LL | let x = || -> (i32, i32) { (1, 2) }; + | + + + +error: expected `{`, found `[` + --> $DIR/closure-return-syntax.rs:17:32 + | +LL | let c = || -> [i32; 2] [1, 2]; + | -------- ^ + | | + | explicit return type requires closure body to be enclosed in braces + | +help: wrap the expression in curly braces + | +LL | let c = || -> [i32; 2] { [1, 2] }; + | + + + +error: aborting due to 3 previous errors diff --git a/tests/ui/sized/dont-incompletely-prefer-built-in.rs b/tests/ui/sized/dont-incompletely-prefer-built-in.rs new file mode 100644 index 0000000000000..f5bf0c8915e76 --- /dev/null +++ b/tests/ui/sized/dont-incompletely-prefer-built-in.rs @@ -0,0 +1,21 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +struct W(T); + +fn is_sized(x: *const T) {} + +fn dummy() -> *const T { todo!() } + +fn non_param_where_bound() +where + W: Sized, +{ + let x: *const W<_> = dummy(); + is_sized::>(x); + let _: *const W = x; +} + +fn main() {} diff --git a/tests/ui/stable-mir-print/async-closure.stdout b/tests/ui/stable-mir-print/async-closure.stdout index 21df1fd395403..12e7a5530ace6 100644 --- a/tests/ui/stable-mir-print/async-closure.stdout +++ b/tests/ui/stable-mir-print/async-closure.stdout @@ -56,7 +56,7 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo unreachable; } } -fn foo::{closure#0}::{closure#1}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> { +fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: Poll<()>; let _3: i32; let mut _4: &i32; diff --git a/tests/ui/target-feature/invalid-attribute.stderr b/tests/ui/target-feature/invalid-attribute.stderr index dc8a53041640e..05ae49d6b0ddb 100644 --- a/tests/ui/target-feature/invalid-attribute.stderr +++ b/tests/ui/target-feature/invalid-attribute.stderr @@ -98,6 +98,12 @@ LL | LL | trait Baz {} | ------------ not a function definition +error: cannot use `#[inline(always)]` with `#[target_feature]` + --> $DIR/invalid-attribute.rs:69:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + error: attribute should be applied to a function definition --> $DIR/invalid-attribute.rs:74:1 | @@ -163,12 +169,6 @@ error: malformed `target_feature` attribute input LL | #[target_feature(disable = "baz")] | ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."` -error: cannot use `#[inline(always)]` with `#[target_feature]` - --> $DIR/invalid-attribute.rs:69:1 - | -LL | #[inline(always)] - | ^^^^^^^^^^^^^^^^^ - error[E0046]: not all trait items implemented, missing: `foo` --> $DIR/invalid-attribute.rs:81:1 | diff --git a/tests/ui/traits/incomplete-infer-via-sized-wc.current.stderr b/tests/ui/traits/incomplete-infer-via-sized-wc.current.stderr new file mode 100644 index 0000000000000..f4930bf890c2b --- /dev/null +++ b/tests/ui/traits/incomplete-infer-via-sized-wc.current.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/incomplete-infer-via-sized-wc.rs:15:5 + | +LL | is_sized::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `is_sized` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/incomplete-infer-via-sized-wc.next.stderr b/tests/ui/traits/incomplete-infer-via-sized-wc.next.stderr new file mode 100644 index 0000000000000..f4930bf890c2b --- /dev/null +++ b/tests/ui/traits/incomplete-infer-via-sized-wc.next.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/incomplete-infer-via-sized-wc.rs:15:5 + | +LL | is_sized::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `is_sized` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/incomplete-infer-via-sized-wc.rs b/tests/ui/traits/incomplete-infer-via-sized-wc.rs new file mode 100644 index 0000000000000..9dcddea3551d1 --- /dev/null +++ b/tests/ui/traits/incomplete-infer-via-sized-wc.rs @@ -0,0 +1,19 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Exercises change in . + +struct MaybeSized(T); + +fn is_sized() -> Box { todo!() } + +fn foo() +where + MaybeSized: Sized, +{ + is_sized::>(); + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc-2.rs b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc-2.rs new file mode 100644 index 0000000000000..8a8f7b933b539 --- /dev/null +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc-2.rs @@ -0,0 +1,28 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Exercises change in . + +trait Trait: Sized {} +impl Trait for T {} + +fn is_sized() {} + +fn normal_ref<'a, 'b, T>() +where + &'a u32: Trait, +{ + is_sized::<&'b u32>(); +} + +struct MyRef<'a, U: ?Sized = ()>(&'a u32, U); +fn my_ref<'a, 'b, T>() +where + MyRef<'a>: Trait, +{ + is_sized::>(); +} + +fn main() {} diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr new file mode 100644 index 0000000000000..dd9393fae853d --- /dev/null +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:13:23 + | +LL | (MyType<'a, T>,): Sized, + | ^^^^^ lifetime mismatch + | + = note: expected trait ` as Sized>` + found trait ` as Sized>` +note: the lifetime `'a` as defined here... + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:11:8 + | +LL | fn foo<'a, T: ?Sized>() + | ^^ + = note: ...does not necessarily outlive the static lifetime + +error: lifetime may not live long enough + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:22:5 + | +LL | fn foo<'a, T: ?Sized>() + | -- lifetime `'a` defined here +... +LL | is_sized::<(MyType<'a, T>,)>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr new file mode 100644 index 0000000000000..05861877d413b --- /dev/null +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr @@ -0,0 +1,25 @@ +error[E0478]: lifetime bound not satisfied + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:13:23 + | +LL | (MyType<'a, T>,): Sized, + | ^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'a` as defined here + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:11:8 + | +LL | fn foo<'a, T: ?Sized>() + | ^^ + = note: but lifetime parameter must outlive the static lifetime + +error: lifetime may not live long enough + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:22:5 + | +LL | fn foo<'a, T: ?Sized>() + | -- lifetime `'a` defined here +... +LL | is_sized::<(MyType<'a, T>,)>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0478`. diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs new file mode 100644 index 0000000000000..ae7a6c9bba335 --- /dev/null +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs @@ -0,0 +1,26 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Exercises change in . + +struct MyType<'a, T: ?Sized>(&'a (), T); + +fn is_sized() {} + +fn foo<'a, T: ?Sized>() +where + (MyType<'a, T>,): Sized, + //[current]~^ ERROR mismatched types + //[next]~^^ ERROR lifetime bound not satisfied + MyType<'static, T>: Sized, +{ + // Preferring the builtin `Sized` impl of tuples + // requires proving `MyType<'a, T>: Sized` which + // can only be proven by using the where-clause, + // adding an unnecessary `'static` constraint. + is_sized::<(MyType<'a, T>,)>(); + //~^ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/triagebot.toml b/triagebot.toml index 217da9935383c..3e7a441c45324 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1161,7 +1161,6 @@ compiler = [ ] libs = [ "@Mark-Simulacrum", - "@Amanieu", "@Noratrieb", "@workingjubilee", "@joboet",