diff --git a/Cargo.lock b/Cargo.lock index bc62ae98e0372..a1a43f47965c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -285,12 +285,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -2135,7 +2129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bdc5a74b0feeb5e6a1dc2dd08c34280a61e37668d10a6a3b27ad69d0fb9ce2e" dependencies = [ "aho-corasick", - "base64 0.22.1", + "base64", "bstr", "jaq-core", "jiff", @@ -4174,6 +4168,7 @@ dependencies = [ "rustc_abi", "rustc_ast", "rustc_ast_pretty", + "rustc_attr_ir", "rustc_hir", "rustc_span", ] @@ -4738,6 +4733,7 @@ dependencies = [ "rustc_arena", "rustc_ast", "rustc_ast_pretty", + "rustc_attr_ir", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", @@ -4854,6 +4850,7 @@ dependencies = [ "punycode", "rustc-demangle", "rustc_abi", + "rustc_attr_ir", "rustc_data_structures", "rustc_hashes", "rustc_hir", @@ -4953,8 +4950,8 @@ version = "0.0.0" dependencies = [ "itertools", "rustc_abi", + "rustc_attr_ir", "rustc_data_structures", - "rustc_hir", "rustc_middle", "rustc_span", "smallvec", @@ -4967,6 +4964,7 @@ version = "0.0.0" dependencies = [ "itertools", "rustc_abi", + "rustc_attr_ir", "rustc_data_structures", "rustc_errors", "rustc_hashes", @@ -5051,7 +5049,6 @@ version = "0.0.0" dependencies = [ "arrayvec", "askama", - "base64 0.21.7", "expect-test", "indexmap", "itertools", diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index b52af8fd3715a..b2cb1718b86a3 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -1,6 +1,6 @@ use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind}; +use rustc_attr_ir::target::Target; use rustc_hir as hir; -use rustc_hir::Target; use rustc_span::sym; use smallvec::SmallVec; diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index eaebff521cb68..80bd0f7f4bb95 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -1,6 +1,7 @@ use std::sync::Arc; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::target::Target; use thin_vec::thin_vec; use crate::LoweringContext; @@ -209,7 +210,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let postcond_checker = self.arena.alloc(self.expr_enum_variant_lang_item( postcond_checker.span, - rustc_hir::attrs::lang_items::LangItem::OptionSome, + LangItem::OptionSome, &*arena_vec![self; *postcond_checker], )); let then_block_stmts = self.block_all(span, stmts, Some(postcond_checker)); @@ -217,7 +218,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let none_expr = self.arena.alloc(self.expr_enum_variant_lang_item( postcond_checker.span, - rustc_hir::attrs::lang_items::LangItem::OptionNone, + LangItem::OptionNone, Default::default(), )); let else_block = self.block_expr(none_expr); @@ -350,7 +351,7 @@ impl<'hir> LoweringContext<'_, 'hir> { )); let attrs: rustc_ast::AttrVec = thin_vec![self.unreachable_code_attr(span)]; - self.lower_attrs(contract_check.hir_id, &attrs, span, rustc_hir::Target::Expression); + self.lower_attrs(contract_check.hir_id, &attrs, span, Target::Expression); let ret_block = self.block_all(span, arena_vec![self; ret_stmt], Some(contract_check)); self.arena.alloc(self.expr_block(self.arena.alloc(ret_block))) diff --git a/compiler/rustc_ast_lowering/src/delegation/attributes.rs b/compiler/rustc_ast_lowering/src/delegation/attributes.rs index 834f85450a2cd..686f5bbf06acc 100644 --- a/compiler/rustc_ast_lowering/src/delegation/attributes.rs +++ b/compiler/rustc_ast_lowering/src/delegation/attributes.rs @@ -1,5 +1,5 @@ +use rustc_attr_ir::{AttributeKind, InlineAttr}; use rustc_hir as hir; -use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_span::Span; use rustc_span::def_id::DefId; @@ -7,33 +7,37 @@ use crate::LoweringContext; use crate::delegation::DelegationResolution; struct AdditionInfo { - pub equals: fn(&hir::Attribute) -> bool, + pub equals: fn(&rustc_attr_ir::Attribute) -> bool, pub kind: AdditionKind, } enum AdditionKind { - Default { factory: fn(Span) -> hir::Attribute }, - Inherit { factory: fn(Span, &hir::Attribute) -> hir::Attribute }, + Default { factory: fn(Span) -> rustc_attr_ir::Attribute }, + Inherit { factory: fn(Span, &rustc_attr_ir::Attribute) -> rustc_attr_ir::Attribute }, } static ADDITIONS: &[AdditionInfo] = &[ AdditionInfo { - equals: |a| matches!(a, hir::Attribute::Parsed(AttributeKind::MustUse { .. })), + equals: |a| matches!(a, rustc_attr_ir::Attribute::Parsed(AttributeKind::MustUse { .. })), kind: AdditionKind::Inherit { factory: |span, original_attr| { let reason = match original_attr { - hir::Attribute::Parsed(AttributeKind::MustUse { reason, .. }) => *reason, + rustc_attr_ir::Attribute::Parsed(AttributeKind::MustUse { reason, .. }) => { + *reason + } _ => None, }; - hir::Attribute::Parsed(AttributeKind::MustUse { span, reason }) + rustc_attr_ir::Attribute::Parsed(AttributeKind::MustUse { span, reason }) }, }, }, AdditionInfo { - equals: |a| matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..))), + equals: |a| matches!(a, rustc_attr_ir::Attribute::Parsed(AttributeKind::Inline(..))), kind: AdditionKind::Default { - factory: |span| hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span)), + factory: |span| { + rustc_attr_ir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span)) + }, }, }, ]; @@ -61,8 +65,8 @@ impl<'hir> LoweringContext<'_, 'hir> { &self, span: Span, sig_id: DefId, - existing: Option<&&[hir::Attribute]>, - ) -> Vec { + existing: Option<&&[rustc_attr_ir::Attribute]>, + ) -> Vec { ADDITIONS .iter() .filter_map(|addition| { diff --git a/compiler/rustc_ast_lowering/src/delegation/mod.rs b/compiler/rustc_ast_lowering/src/delegation/mod.rs index 0e94016963c78..b2c0e1ffa81b1 100644 --- a/compiler/rustc_ast_lowering/src/delegation/mod.rs +++ b/compiler/rustc_ast_lowering/src/delegation/mod.rs @@ -45,7 +45,7 @@ use hir::def::Res; use rustc_abi::ExternAbi; use rustc_ast as ast; use rustc_ast::*; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir::def::DefKind; use rustc_hir::{self as hir, FnDeclFlags, QPath}; use rustc_middle::ty::Asyncness; diff --git a/compiler/rustc_ast_lowering/src/expr/closure.rs b/compiler/rustc_ast_lowering/src/expr/closure.rs index 1b8740948d726..c72956545b7c8 100644 --- a/compiler/rustc_ast_lowering/src/expr/closure.rs +++ b/compiler/rustc_ast_lowering/src/expr/closure.rs @@ -1,6 +1,8 @@ use rustc_ast::*; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::target::Target; use rustc_hir as hir; -use rustc_hir::{HirId, Target, find_attr}; +use rustc_hir::HirId; use rustc_span::{Span, span_bug}; use super::{LoweringContext, MoveExprState}; @@ -55,7 +57,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_expr_coroutine_closure_with_move_exprs( &mut self, expr_hir_id: HirId, - attrs: &[hir::Attribute], + attrs: &[rustc_attr_ir::Attribute], binder: &ClosureBinder, capture_clause: CaptureBy, closure_id: NodeId, @@ -114,7 +116,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_expr_plain_closure_with_move_exprs( &mut self, expr_hir_id: HirId, - attrs: &[hir::Attribute], + attrs: &[rustc_attr_ir::Attribute], binder: &ClosureBinder, capture_clause: CaptureBy, closure_id: NodeId, @@ -153,7 +155,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // local uses and the caller can later add the matching initializers. fn lower_expr_closure( &mut self, - attrs: &[hir::Attribute], + attrs: &[rustc_attr_ir::Attribute], binder: &ClosureBinder, capture_clause: CaptureBy, closure_id: NodeId, @@ -283,7 +285,7 @@ impl<'hir> LoweringContext<'_, 'hir> { body: &Expr, fn_decl_span: Span, fn_arg_span: Span, - attrs: &[hir::Attribute], + attrs: &[rustc_attr_ir::Attribute], ) -> hir::ExprKind<'hir> { let closure_def_id = self.local_def_id(closure_id); let (binder_clause, generic_params) = self.lower_closure_binder(binder); diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index b9974edea71a4..9da42511c0d7f 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -1,9 +1,9 @@ use std::borrow::Cow; use rustc_ast::*; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_session::config::FmtDebug; use rustc_span::{ByteSymbol, DesugaringKind, Ident, Span, Symbol, sym}; diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index f8106bd68d82c..33b73ed30c518 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1,12 +1,11 @@ use rustc_abi::ExternAbi; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; +use rustc_attr_ir::target::Target; +use rustc_attr_ir::{AttributeKind, EiiImplResolution, find_attr}; use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err}; -use rustc_hir::attrs::{AttributeKind, EiiImplResolution}; use rustc_hir::def::{DefKind, PerNS, Res}; -use rustc_hir::{ - self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr, -}; +use rustc_hir::{self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin}; use rustc_middle::ty::data_structures::IndexMap; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::edit_distance::find_best_match_for_name; @@ -68,8 +67,8 @@ impl<'hir> LoweringContext<'_, 'hir> { id: NodeId, name: Ident, EiiDecl { foreign_item, impl_unsafe }: &EiiDecl, - ) -> Option { - self.lower_path_simple_eii(id, foreign_item).map(|did| hir::attrs::EiiDecl { + ) -> Option { + self.lower_path_simple_eii(id, foreign_item).map(|did| rustc_attr_ir::EiiDecl { foreign_item: did, impl_unsafe: *impl_unsafe, name, @@ -87,7 +86,7 @@ impl<'hir> LoweringContext<'_, 'hir> { is_default, known_eii_macro_resolution, }: &EiiImpl, - ) -> hir::attrs::EiiImpl { + ) -> rustc_attr_ir::EiiImpl { let resolution = if let Some(target) = known_eii_macro_resolution && let Some(foreign_item_did) = self.lower_path_simple_eii(*node_id, target) { @@ -100,7 +99,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }; - hir::attrs::EiiImpl { + rustc_attr_ir::EiiImpl { span: self.lower_span(*span), inner_span: self.lower_span(*inner_span), impl_unsafe_span: match *impl_safety { @@ -116,19 +115,21 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, id: NodeId, i: &ItemKind, - ) -> Vec { + ) -> Vec { match i { ItemKind::Fn(Fn { eii_impl: None, .. }) | ItemKind::Static(StaticItem { eii_impl: None, .. }) => Vec::new(), ItemKind::Fn(Fn { eii_impl: Some(eii_impl), .. }) | ItemKind::Static(StaticItem { eii_impl: Some(eii_impl), .. }) => { - vec![hir::Attribute::Parsed(AttributeKind::EiiImpl(Box::new( + vec![rustc_attr_ir::Attribute::Parsed(AttributeKind::EiiImpl(Box::new( self.lower_eii_impl(eii_impl), )))] } ItemKind::MacroDef(name, MacroDef { eii_declaration: Some(target), .. }) => self .lower_eii_decl(id, *name, target) - .map(|decl| vec![hir::Attribute::Parsed(AttributeKind::EiiDeclaration(decl))]) + .map(|decl| { + vec![rustc_attr_ir::Attribute::Parsed(AttributeKind::EiiDeclaration(decl))] + }) .unwrap_or_default(), ItemKind::ExternCrate(..) @@ -184,7 +185,7 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, id: NodeId, hir_id: hir::HirId, - attrs: &'hir [hir::Attribute], + attrs: &'hir [rustc_attr_ir::Attribute], vis_span: Span, i: &ItemKind, ) -> hir::ItemKind<'hir> { @@ -551,7 +552,7 @@ impl<'hir> LoweringContext<'_, 'hir> { prefix: &Path, id: NodeId, vis_span: Span, - attrs: &'hir [hir::Attribute], + attrs: &'hir [rustc_attr_ir::Attribute], ) -> hir::ItemKind<'hir> { let path = &tree.prefix; let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect(); @@ -1351,7 +1352,7 @@ impl<'hir> LoweringContext<'_, 'hir> { decl: &FnDecl, coroutine_marker: Option, body: Option<&Block>, - attrs: &'hir [hir::Attribute], + attrs: &'hir [rustc_attr_ir::Attribute], contract: Option<&FnContract>, ) -> hir::BodyId { let Some(body) = body else { @@ -1612,7 +1613,7 @@ impl<'hir> LoweringContext<'_, 'hir> { id: NodeId, kind: FnDeclKind, coroutine_marker: Option, - attrs: &[hir::Attribute], + attrs: &[rustc_attr_ir::Attribute], ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) { let header = self.lower_fn_header(sig.header, hir::Safety::Safe, attrs); let itctx = ImplTraitContext::Universal; @@ -1626,7 +1627,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, h: FnHeader, default_safety: hir::Safety, - attrs: &[hir::Attribute], + attrs: &[rustc_attr_ir::Attribute], ) -> hir::FnHeader { let asyncness = if let Some(coroutine_marker) = h.coroutine_marker && let CoroutineKind::Async = coroutine_marker.kind @@ -1713,7 +1714,11 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Lowers constness or comptime attribute. /// Whether `const` is allowed here is checked by ast validation. /// Whether `comptime` is allowed here is checked by the `comptime` attribute parser. - pub(super) fn lower_constness(&mut self, attrs: &[hir::Attribute], c: Const) -> hir::Constness { + pub(super) fn lower_constness( + &mut self, + attrs: &[rustc_attr_ir::Attribute], + c: Const, + ) -> hir::Constness { let mut constness = match c { Const::Yes(_) => hir::Constness::Const { always: false }, Const::No => hir::Constness::NotConst, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 7ff6a2538c1e7..d35e8df40f20b 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -45,6 +45,9 @@ use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::node_id::NodeMap; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, *}; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::target::Target; use rustc_attr_parsing::{AttributeParser, Recovery, ShouldEmit}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedMap; @@ -54,15 +57,13 @@ use rustc_data_structures::tagged_ptr::TaggedRef; use rustc_data_structures::unord::ExtendUnord; use rustc_errors::codes::*; use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, ErrorGuaranteed}; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{DefKind, Namespace, PerNS, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::lints::DelayedLint; use rustc_hir::{ self as hir, AngleBrackets, CRATE_OWNER_ID, ConstArg, GenericArg, HirId, ItemLocalMap, - LifetimeSource, LifetimeSyntax, MissingLifetimeKind, ParamName, Target, TraitCandidate, - find_attr, + LifetimeSource, LifetimeSyntax, MissingLifetimeKind, ParamName, TraitCandidate, }; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; @@ -169,7 +170,7 @@ struct PerOwnerLoweringState<'a, 'hir> { // -- Accumulated outputs -- /// Attributes inside the owner being lowered. - attrs: SortedMap, + attrs: SortedMap, /// Bodies inside the owner being lowered. bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>, /// `#[define_opaque]` attributes @@ -1206,7 +1207,7 @@ impl<'hir> LoweringContext<'_, 'hir> { attrs: &[Attribute], target_span: Span, target: Target, - ) -> &'hir [hir::Attribute] { + ) -> &'hir [rustc_attr_ir::Attribute] { self.lower_attrs_with_extra(id, attrs, target_span, target, None, &[]) } @@ -1217,8 +1218,8 @@ impl<'hir> LoweringContext<'_, 'hir> { target_span: Span, target: Target, target_item: Option<&ast::Item>, - extra_hir_attributes: &[hir::Attribute], - ) -> &'hir [hir::Attribute] { + extra_hir_attributes: &[rustc_attr_ir::Attribute], + ) -> &'hir [rustc_attr_ir::Attribute] { if attrs.is_empty() && extra_hir_attributes.is_empty() { &[] } else { @@ -1251,7 +1252,7 @@ impl<'hir> LoweringContext<'_, 'hir> { target_hir_id: HirId, target: Target, target_item: Option<&ast::Item>, - ) -> Vec { + ) -> Vec { let l = self.span_lowerer(); self.attribute_parser.parse_attribute_list( attrs, @@ -3111,7 +3112,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn stmt_let_pat( &mut self, - attrs: Option<&'hir [hir::Attribute]>, + attrs: Option<&'hir [rustc_attr_ir::Attribute]>, span: Span, init: Option<&'hir hir::Expr<'hir>>, pat: &'hir hir::Pat<'hir>, diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 0edba3fe0cd14..df3d7b1a3c0a6 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -1,9 +1,10 @@ use std::sync::Arc; use rustc_ast::*; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::target::Target; +use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{self as hir, Target}; use rustc_span::{DesugaringKind, Ident, Span, Spanned, respan, span_bug}; use crate::diagnostics::{ diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index fed7fdd97ac4d..00f28ecd1cfeb 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -156,7 +156,7 @@ pub(crate) fn compute_regions<'tcx>( &universal_region_relations.universal_regions, body, move_data, - &location_map, + Rc::clone(&location_map), borrow_set, ); } diff --git a/compiler/rustc_borrowck/src/polonius/constraints.rs b/compiler/rustc_borrowck/src/polonius/constraints.rs index 44a21708c8419..5855f60a85217 100644 --- a/compiler/rustc_borrowck/src/polonius/constraints.rs +++ b/compiler/rustc_borrowck/src/polonius/constraints.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_index::IndexVec; use rustc_middle::mir::{Body, Location}; @@ -8,7 +10,7 @@ use crate::BorrowSet; use crate::constraints::OutlivesConstraint; use crate::dataflow::BorrowIndex; use crate::polonius::ConstraintDirection; -use crate::polonius::liveness::RegionLiveness; +use crate::polonius::liveness::LivenessSource; use crate::type_check::Locations; /// A localized outlives constraint reifies the CFG location where the outlives constraint holds, @@ -38,6 +40,8 @@ pub(super) struct LocalizedNode { /// The localized constraint graph indexes the physical and logical edges to lazily compute a given /// node's successors during traversal. pub(super) struct LocalizedConstraintGraph { + location_map: Rc, + /// The actual, physical, edges we have recorded for a given node. We localize them on-demand /// when traversing from the node to the successor region. edges: FxHashMap>, @@ -48,16 +52,10 @@ pub(super) struct LocalizedConstraintGraph { logical_edges: IndexVec>, } -/// The source of liveness information for a given region. -pub(super) trait LivenessSource<'loc> { - fn liveness_for_region(&mut self, region: RegionVid) -> RegionLiveness<'_>; - fn location_map(&self) -> &'loc DenseLocationMap; -} - /// The visitor interface when traversing a `LocalizedConstraintGraph`. pub(super) trait LocalizedConstraintGraphVisitor { /// Callback called when traversing a given `loan` encounters a localized `node` it hasn't - /// visited before. + /// visited before, and whether its region is live at that point. fn on_node_traversed(&mut self, _loan: BorrowIndex, _node: LocalizedNode, _is_live: bool) {} /// Callback called when discovering a new `successor` node for the `current_node`. @@ -68,7 +66,7 @@ pub(super) trait LocalizedConstraintGraphVisitor { impl LocalizedConstraintGraph { /// Traverses the constraints and returns the indexed graph of edges per node. pub(super) fn new<'tcx>( - location_map: &DenseLocationMap, + location_map: Rc, outlives_constraints: impl Iterator>, ) -> Self { let mut edges: FxHashMap<_, FxIndexSet<_>> = FxHashMap::default(); @@ -92,23 +90,21 @@ impl LocalizedConstraintGraph { } } - LocalizedConstraintGraph { edges, logical_edges } + LocalizedConstraintGraph { location_map, edges, logical_edges } } /// Traverses the localized constraint graph per-loan, and notifies the `visitor` of discovered /// nodes and successors. - pub(super) fn traverse<'tcx, 'loc>( + pub(super) fn traverse<'tcx>( &self, body: &Body<'tcx>, borrow_set: &BorrowSet<'tcx>, - liveness_source: &mut impl LivenessSource<'loc>, + liveness_source: &mut impl LivenessSource, visitor: &mut impl LocalizedConstraintGraphVisitor, ) { let mut visited = FxHashSet::default(); let mut stack = Vec::new(); - let location_map = liveness_source.location_map(); - // Compute reachability per loan by traversing each loan's subgraph starting from where it // is introduced. for (loan_idx, loan) in borrow_set.iter_enumerated() { @@ -117,7 +113,7 @@ impl LocalizedConstraintGraph { let start_node = LocalizedNode { region: loan.region, - point: location_map.point_from_location(loan.reserve_location), + point: self.location_map.point_from_location(loan.reserve_location), }; visited.insert(start_node); stack.push(start_node); @@ -125,7 +121,7 @@ impl LocalizedConstraintGraph { while let Some(node) = stack.pop() { let liveness = liveness_source.liveness_for_region(node.region); // We've reached a node we haven't visited before. - let location = location_map.to_location(node.point); + let location = self.location_map.to_location(node.point); visitor.on_node_traversed(loan_idx, node, liveness.is_live_at(node.point)); // When we find a _new_ successor, we'd like to @@ -181,7 +177,7 @@ impl LocalizedConstraintGraph { for successor_block in body[location.block].terminator().successors() { let next_location = Location { block: successor_block, statement_index: 0 }; - let next_point = location_map.point_from_location(next_location); + let next_point = self.location_map.point_from_location(next_location); if liveness.is_live_at(next_point) { successor_found(LocalizedNode { region: node.region, @@ -224,7 +220,7 @@ impl LocalizedConstraintGraph { statement_index: body[pred_block].statements.len(), }; let previous_point = - location_map.point_from_location(previous_location); + self.location_map.point_from_location(previous_location); successor_found(LocalizedNode { region: node.region, point: previous_point, diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs index fff31691f4086..fb4c6fbcc9da9 100644 --- a/compiler/rustc_borrowck/src/polonius/dump.rs +++ b/compiler/rustc_borrowck/src/polonius/dump.rs @@ -5,7 +5,7 @@ use rustc_index::IndexVec; use rustc_middle::mir::pretty::{MirDumper, PassWhere, PrettyPrintMirOptions}; use rustc_middle::mir::{Body, Location}; use rustc_middle::ty::{RegionVid, TyCtxt}; -use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex}; +use rustc_mir_dataflow::points::PointIndex; use rustc_session::config::MirIncludeSpans; use crate::borrow_set::BorrowSet; @@ -32,7 +32,7 @@ struct CachedLivenessSource<'a, 'tcx> { liveness: &'a LivenessValues, } -impl<'a, 'tcx> LivenessSource<'a> for CachedLivenessSource<'a, 'tcx> { +impl<'a, 'tcx> LivenessSource for CachedLivenessSource<'a, 'tcx> { fn liveness_for_region(&mut self, region: RegionVid) -> RegionLiveness<'_> { RegionLiveness::new( region, @@ -41,9 +41,6 @@ impl<'a, 'tcx> LivenessSource<'a> for CachedLivenessSource<'a, 'tcx> { self.liveness.points(), ) } - fn location_map(&self) -> &'a DenseLocationMap { - self.liveness.location_map() - } } /// `-Zdump-mir=polonius` dumps MIR annotated with NLL and polonius specific information. diff --git a/compiler/rustc_borrowck/src/polonius/liveness.rs b/compiler/rustc_borrowck/src/polonius/liveness.rs index 0bef063b0162c..9cbaa2d6ddc4d 100644 --- a/compiler/rustc_borrowck/src/polonius/liveness.rs +++ b/compiler/rustc_borrowck/src/polonius/liveness.rs @@ -1,15 +1,63 @@ use rustc_index::IndexVec; use rustc_index::interval::{IntervalSet, SparseIntervalMatrix}; use rustc_middle::mir::Local; -use rustc_middle::ty::{GenericArg, RegionVid, Ty}; +use rustc_middle::ty::{GenericArg, RegionVid, Ty, TyCtxt}; use rustc_mir_dataflow::points::PointIndex; -use crate::BorrowckInferCtxt; use crate::polonius::{ConstraintDirection, LiveRegionVariances}; use crate::region_infer::values::LivenessValues; use crate::type_check::liveness::LivenessComputation; use crate::universal_regions::UniversalRegions; +/// The source of liveness information for a given region. +pub(super) trait LivenessSource { + fn liveness_for_region(&mut self, region: RegionVid) -> RegionLiveness<'_>; +} + +/// For a given region, the relevant liveness and variance information. +pub(super) struct RegionLiveness<'a> { + pub(super) direction: ConstraintDirection, + live_points: Option<&'a IntervalSet>, +} + +impl<'a> RegionLiveness<'a> { + #[inline] + pub(super) fn new<'tcx>( + region: RegionVid, + live_region_variances: &LiveRegionVariances, + universal_regions: &UniversalRegions<'tcx>, + live_points: &'a SparseIntervalMatrix, + ) -> Self { + // Universal regions propagate loans along the CFG, i.e. forwards only. + let is_universal_region = universal_regions.is_universal_region(region); + + // Note: there currently are cases related to promoted and const generics, where we don't yet + // have variance information (possibly about temporary regions created when typeck sanitizes the + // promoteds). Until that is done, we conservatively fallback to maximizing reachability by + // adding a bidirectional edge here. This will not limit traversal whatsoever, and thus + // propagate liveness when needed. + // + // FIXME: add the missing variance information and remove this fallback bidirectional edge. + let direction = if is_universal_region { + ConstraintDirection::Forward + } else { + live_region_variances + .get(region) + .copied() + .flatten() + .unwrap_or(ConstraintDirection::Bidirectional) + }; + let live_points = live_points.row(region); + Self { direction, live_points } + } + + pub(super) fn is_live_at(&self, point: PointIndex) -> bool { + self.live_points.map_or(false, |points| points.contains(point)) + } +} + +/// The data needed to compute region liveness on-demand while traversing the localized outlives +/// constraint graph to compute loan liveness. #[derive(Default)] pub(crate) struct DeferredLocals<'tcx> { /// For each region, the local whose liveness is deferred. @@ -24,14 +72,12 @@ pub(crate) struct DeferredLocals<'tcx> { impl<'tcx> DeferredLocals<'tcx> { pub(crate) fn defer_local( &mut self, - infcx: &BorrowckInferCtxt<'tcx>, + tcx: TyCtxt<'tcx>, universal_regions: &UniversalRegions<'tcx>, local: Local, local_ty: Ty<'tcx>, dropck_kinds: &[GenericArg<'tcx>], ) { - let tcx = infcx.tcx; - // We already have drop data for this local, because we need to register // region constraints eagerly. So, we'll store this so we don't need to // recompute. @@ -42,7 +88,7 @@ impl<'tcx> DeferredLocals<'tcx> { // we can trace liveness for the local containing it. let by_region = &mut self.by_region; tcx.for_each_free_region(&local_ty, |region| { - // See note in [`VarianceExtractor::record_variance`]. + // See note in `VarianceExtractor::record_variance`. if region.is_bound() || region.is_erased() { return; } @@ -58,7 +104,7 @@ impl<'tcx> DeferredLocals<'tcx> { }); } - /// For a given region, compute the liveness for the local containing it, if if is deferred. + /// For a given region, compute the liveness for the local containing it, if it is deferred. #[inline] pub(crate) fn compute_deferred_local( &mut self, @@ -80,45 +126,3 @@ impl<'tcx> DeferredLocals<'tcx> { }); } } - -/// For a given region, the relevant liveness and variance information. -pub(super) struct RegionLiveness<'a> { - pub(super) direction: ConstraintDirection, - live_points: Option<&'a IntervalSet>, -} - -impl<'a> RegionLiveness<'a> { - #[inline] - pub(super) fn new<'tcx>( - region: RegionVid, - live_region_variances: &LiveRegionVariances, - universal_regions: &UniversalRegions<'tcx>, - live_points: &'a SparseIntervalMatrix, - ) -> Self { - // Universal regions propagate loans along the CFG, i.e. forwards only. - let is_universal_region = universal_regions.is_universal_region(region); - - // Note: there currently are cases related to promoted and const generics, where we don't yet - // have variance information (possibly about temporary regions created when typeck sanitizes the - // promoteds). Until that is done, we conservatively fallback to maximizing reachability by - // adding a bidirectional edge here. This will not limit traversal whatsoever, and thus - // propagate liveness when needed. - // - // FIXME: add the missing variance information and remove this fallback bidirectional edge. - let direction = if is_universal_region { - ConstraintDirection::Forward - } else { - live_region_variances - .get(region) - .copied() - .flatten() - .unwrap_or(ConstraintDirection::Bidirectional) - }; - let live_points = live_points.row(region); - Self { direction, live_points } - } - - pub(super) fn is_live_at(&self, point: PointIndex) -> bool { - self.live_points.map_or(false, |points| points.contains(point)) - } -} diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs index 654c750dfccd1..73133b6ca0811 100644 --- a/compiler/rustc_borrowck/src/polonius/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/mod.rs @@ -39,6 +39,8 @@ pub(crate) mod legacy; mod liveness; mod liveness_constraints; +use std::rc::Rc; + use rustc_data_structures::fx::FxHashSet; use rustc_index::IndexVec; use rustc_index::bit_set::DenseBitSet; @@ -53,7 +55,7 @@ pub(crate) use self::liveness_constraints::record_live_region_variance; use crate::constraints::OutlivesConstraint; use crate::dataflow::BorrowIndex; pub(crate) use crate::polonius::liveness::DeferredLocals; -use crate::polonius::liveness::RegionLiveness; +use crate::polonius::liveness::{LivenessSource, RegionLiveness}; use crate::region_infer::values::LivenessValues; use crate::type_check::liveness::{LivenessComputation, LocalUseMap}; use crate::universal_regions::UniversalRegions; @@ -141,7 +143,7 @@ impl<'tcx> PoloniusContext<'tcx> { universal_regions: &UniversalRegions<'tcx>, body: &Body<'tcx>, move_data: &MoveData<'tcx>, - location_map: &DenseLocationMap, + location_map: Rc, borrow_set: &BorrowSet<'tcx>, ) { // We don't need to prepare the graph (index NLL constraints, etc.) if we have no loans to @@ -151,7 +153,7 @@ impl<'tcx> PoloniusContext<'tcx> { // on the lazy localized constraint graph to trace the liveness of loans, for the next // step in the chain (the NLL loan scope and active loans computations). let graph = - LocalizedConstraintGraph::new(liveness.location_map(), outlives_constraints); + LocalizedConstraintGraph::new(Rc::clone(&location_map), outlives_constraints); let local_use_map = self .local_use_map @@ -161,7 +163,7 @@ impl<'tcx> PoloniusContext<'tcx> { std::mem::take(&mut self.deferred_locals_for_liveness); let mut live_loans = LiveLoans::new(location_map.num_points(), borrow_set.len()); let comp = - LivenessComputation::new(infcx, body, location_map, move_data, &local_use_map); + LivenessComputation::new(infcx, body, &location_map, move_data, &local_use_map); let mut liveness_source = DeferredLivenessSource { liveness, live_region_variances: &mut self.live_region_variances, @@ -190,7 +192,7 @@ struct DeferredLivenessSource<'a, 'tcx> { comp: LivenessComputation<'a, 'tcx>, } -impl<'a> LivenessSource<'a> for DeferredLivenessSource<'a, '_> { +impl<'a> LivenessSource for DeferredLivenessSource<'a, '_> { #[inline] fn liveness_for_region(&mut self, region: RegionVid) -> RegionLiveness<'_> { self.deferred_locals_for_liveness.compute_deferred_local( @@ -208,10 +210,6 @@ impl<'a> LivenessSource<'a> for DeferredLivenessSource<'a, '_> { self.liveness.points(), ) } - - fn location_map(&self) -> &'a DenseLocationMap { - self.comp.location_map - } } /// Visitor to record loan liveness when traversing the localized constraint graph. diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 6e4e9405e3ada..800f72275b052 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -201,10 +201,6 @@ impl LivenessValues { self.location_map.to_location(point) } - pub(crate) fn location_map(&self) -> &Rc { - &self.location_map - } - /// When using `-Zpolonius=next`, records the given live loans for the loan scopes and active /// loans dataflow computations. pub(crate) fn record_live_loans(&mut self, live_loans: LiveLoans) { diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs index 9c39645ec677d..0bb6ecb8e2049 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs @@ -82,7 +82,7 @@ impl<'a> Iterator for AppearancesIter<'a> { impl LocalUseMap { pub(crate) fn build( - live_locals: &[Local], + mut live_locals: impl Iterator, location_map: &DenseLocationMap, body: &Body<'_>, ) -> Self { @@ -94,13 +94,11 @@ impl LocalUseMap { appearances: IndexVec::new(), }; - if live_locals.is_empty() { - return local_use_map; - } + let Some(head) = live_locals.next() else { return local_use_map }; - let mut locals_with_use_data: DenseBitSet = - DenseBitSet::new_empty(body.local_decls.len()); - live_locals.iter().for_each(|&local| { + let mut locals_with_use_data = DenseBitSet::new_empty(body.local_decls.len()); + locals_with_use_data.insert(head); + live_locals.for_each(|local| { locals_with_use_data.insert(local); }); diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index 6b9eae7428475..905547c7dce51 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -78,13 +78,12 @@ pub(super) fn generate<'tcx>( break 'deferred FxIndexSet::default(); } - let free_regions: FxHashSet = - typeck.universal_regions.universal_regions_iter().collect(); + let free_regions = typeck.universal_regions.universal_regions_iter().collect(); let (polonius_relevant, _) = compute_relevant_live_locals(typeck.tcx(), &free_regions, typeck.body); - let boring: FxHashSet = boring_locals.iter().copied().collect(); - let deferred: FxIndexSet = + let boring: FxHashSet<_> = boring_locals.iter().copied().collect(); + let deferred = polonius_relevant.into_iter().filter(|local| boring.contains(local)).collect(); typeck.polonius_context.as_mut().unwrap().boring_nll_locals = boring; deferred diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 0811b66d43acf..21b2e0f304b05 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -52,8 +52,8 @@ pub(super) fn trace<'tcx>( // The use map must also cover the deferred locals: their liveness is computed later, from // this same map, when the loan liveness traversal first reaches one of their regions. - let use_map_locals: Vec = relevant_live_locals.iter().chain(deferred).copied().collect(); - let local_use_map = LocalUseMap::build(&use_map_locals, location_map, typeck.body); + let use_map_locals = relevant_live_locals.iter().chain(deferred).copied(); + let local_use_map = LocalUseMap::build(use_map_locals, location_map, typeck.body); let comp = LivenessComputation::new( typeck.infcx, typeck.body, @@ -221,7 +221,7 @@ impl<'a, 'typeck, 'tcx> LivenessResults<'a, 'typeck, 'tcx> { // are *no* drops (which is relatively cheap). if deferred.contains(&local) && self.comp.local_use_map.drops(local).next().is_none() { deferred_locals.defer_local( - typeck.infcx, + typeck.infcx.tcx, typeck.universal_regions, local, local_ty, @@ -265,7 +265,7 @@ impl<'a, 'typeck, 'tcx> LivenessResults<'a, 'typeck, 'tcx> { // Finally, we mark that this local is deferred, including the drop kinds. deferred_locals.defer_local( - typeck.infcx, + typeck.infcx.tcx, typeck.universal_regions, local, local_ty, @@ -279,8 +279,8 @@ impl<'a, 'typeck, 'tcx> LivenessResults<'a, 'typeck, 'tcx> { /// the function body only at certain nodes in the CFG. fn record_legacy_polonius_drop_facts( &mut self, - relevant_live_locals: &[Local], - deferred: &FxIndexSet, + nll_relevant_locals: &[Local], + deferred_polonius_relevant_locals: &FxIndexSet, ) { // This is *all wonky* because this used to call a shared // `add_drop_live_facts_for` function that was also used for regular @@ -292,16 +292,15 @@ impl<'a, 'typeck, 'tcx> LivenessResults<'a, 'typeck, 'tcx> { // `add_drop_live_facts_for()` that make sense. let Some(facts) = self.typeck.polonius_facts.as_ref() else { return }; let facts_to_add: Vec<_> = { - let relevant_live_locals: FxIndexSet<_> = - relevant_live_locals.iter().copied().collect(); + let nll_relevant_locals: FxIndexSet<_> = nll_relevant_locals.iter().copied().collect(); facts .var_dropped_at .iter() .filter_map(|&(local, location_index)| { let local_ty = self.comp.body.local_decls[local].ty; - if relevant_live_locals.contains(&local) - || deferred.contains(&local) + if nll_relevant_locals.contains(&local) + || deferred_polonius_relevant_locals.contains(&local) || !local_ty.has_free_regions() { return None; @@ -394,7 +393,7 @@ impl<'a, 'tcx> LivenessComputation<'a, 'tcx> { universal_regions: &UniversalRegions<'tcx>, live_region_variances: Option<&mut LiveRegionVariances>, liveness_constraints: &mut LivenessValues, - get_drop_args: impl FnOnce() -> &'drop_data Vec>, + get_drop_args: impl FnOnce() -> &'drop_data [GenericArg<'tcx>], ) where 'tcx: 'drop_data, { @@ -431,17 +430,16 @@ impl<'a, 'tcx> LivenessComputation<'a, 'tcx> { if !self.drop_live_at.is_empty() { let drop_data = get_drop_args(); - // `drop_live_at` is using a DenseBitSet, but `make_all_regions_live` - // expects an IntervalSet. We thus convert between those two here. - // Using a `DenseBitSet` has better performance, but storing liveness - // as a dense matrix has worse performance. There's probably room here - // for some cleanup, but this works for now. - let mut drop_live_at: IntervalSet = - IntervalSet::new(self.drop_live_at.domain_size()); - for item in self.drop_live_at.iter() { + // `compute_drop_live_points_for` computes `drop_live_at` as a `DenseBitSet`, but + // `make_all_regions_live` expects an `IntervalSet`. We thus convert between those two + // here. Using a `DenseBitSet` has better performance, but storing liveness as a dense + // matrix has worse performance. There's probably room here for some cleanup, but this + // works for now. + let mut drop_live_at = IntervalSet::new(self.drop_live_at.domain_size()); + for point in self.drop_live_at.iter() { // We iterate the `drop_live_at` set from smallest to largest values, so // we can use append to add things to the interval set at the end. - drop_live_at.append(item); + drop_live_at.append(point); } for &kind in drop_data { diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index 96b39f0ae6863..9774165c73400 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -15,8 +15,11 @@ pub(crate) const UNSUPPORTED_CONCAT_ELEM_ERR: &str = "expected identifier or str /// A meta-variable expression, for expansions based on properties of meta-variables. #[derive(Debug, PartialEq, Encodable, Decodable)] pub(crate) enum MetaVarExpr { - /// Unification of two or more identifiers. - Concat(Box<[MetaVarExprConcatElem]>), + /// Unification of two or more identifiers/literals/metavariables into an identifier. + ConcatIdent(Box<[MetaVarExprConcatElem]>), + + /// Unification of two or more identifiers/literals/metavariables into a string literal. + ConcatStr(Box<[MetaVarExprConcatElem]>), /// The number of repetitions of an identifier. Count(Ident, usize), @@ -73,7 +76,12 @@ impl MetaVarExpr { let mut iter = args.iter(); let rslt = match ident.name { - sym::concat => parse_concat(&mut iter, psess, outer_span, ident.span)?, + sym::concat => { + MetaVarExpr::ConcatIdent(parse_concat(&mut iter, psess, outer_span, ident.span)?) + } + sym::concat_str => { + MetaVarExpr::ConcatStr(parse_concat(&mut iter, psess, outer_span, ident.span)?) + } sym::count => parse_count(&mut iter, psess, ident.span)?, sym::ignore => { eat_dollar(&mut iter, psess, ident.span)?; @@ -95,7 +103,7 @@ impl MetaVarExpr { pub(crate) fn for_each_metavar(&self, mut aux: A, mut cb: impl FnMut(A, &Ident) -> A) -> A { match self { - MetaVarExpr::Concat(elems) => { + MetaVarExpr::ConcatIdent(elems) | MetaVarExpr::ConcatStr(elems) => { for elem in elems { if let MetaVarExprConcatElem::Var(ident) = elem { aux = cb(aux, ident) @@ -175,7 +183,7 @@ fn parse_concat<'psess>( psess: &'psess ParseSess, outer_span: Span, expr_ident_span: Span, -) -> PResult<'psess, MetaVarExpr> { +) -> PResult<'psess, Box<[MetaVarExprConcatElem]>> { let mut result = Vec::new(); loop { let is_var = try_eat_dollar(iter); @@ -210,7 +218,7 @@ fn parse_concat<'psess>( .dcx() .struct_span_err(expr_ident_span, "`concat` must have at least two elements")); } - Ok(MetaVarExpr::Concat(result.into())) + Ok(result.into()) } /// Parse a meta-variable `count` expression: `count(ident[, depth])` diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index aed69c9f5d938..ff1607c9e4456 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -7,7 +7,7 @@ use rustc_feature::Features; use rustc_session::Session; use rustc_session::diagnostics::feature_err; use rustc_span::edition::Edition; -use rustc_span::{Ident, Span, kw, sym}; +use rustc_span::{Ident, Span, Symbol, kw, sym}; use crate::diagnostics; use crate::mbe::macro_parser::count_metavar_decls; @@ -204,9 +204,14 @@ fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &Session, sp } } -fn maybe_emit_macro_metavar_expr_concat_feature(features: &Features, sess: &Session, span: Span) { +fn maybe_emit_macro_metavar_expr_concat_feature( + features: &Features, + sess: &Session, + span: Span, + what: Symbol, +) { if !features.macro_metavar_expr_concat() { - let msg = "the `concat` meta-variable expression is unstable"; + let msg = format!("the `{what}` meta-variable expression is unstable"); feature_err(sess, sym::macro_metavar_expr_concat, span, msg).emit(); } } @@ -278,11 +283,19 @@ fn parse_tree<'a>( return TokenTree::token(token::Dollar, dollar_span); } Ok(elem) => { - if let MetaVarExpr::Concat(_) = elem { + if matches!(elem, MetaVarExpr::ConcatIdent(_)) { + maybe_emit_macro_metavar_expr_concat_feature( + features, + sess, + delim_span.entire(), + sym::concat, + ); + } else if matches!(elem, MetaVarExpr::ConcatStr(_)) { maybe_emit_macro_metavar_expr_concat_feature( features, sess, delim_span.entire(), + sym::concat_str, ); } else { maybe_emit_macro_metavar_expr_feature( diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index c258d9e471079..8d036972ad592 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -597,7 +597,8 @@ fn transcribe_metavar_expr<'tx>( ) -> PResult<'tx, ()> { let dcx = tscx.psess.dcx(); let tt = match *expr { - MetaVarExpr::Concat(ref elements) => metavar_expr_concat(tscx, dspan, elements)?, + MetaVarExpr::ConcatIdent(ref elements) => metavar_expr_concat_ident(tscx, dspan, elements)?, + MetaVarExpr::ConcatStr(ref elements) => metavar_expr_concat_str(tscx, dspan, elements)?, MetaVarExpr::Count(original_ident, depth) => { let matched = matched_from_ident(dcx, original_ident, tscx.interp)?; let count = count_repetitions(dcx, depth, matched, &tscx.repeats, &dspan)?; @@ -635,11 +636,52 @@ fn transcribe_metavar_expr<'tx>( } /// Handle the `${concat(...)}` metavariable expression. -fn metavar_expr_concat<'tx>( +fn metavar_expr_concat_ident<'tx>( + tscx: &mut TranscrCtx<'tx, '_>, + dspan: DelimSpan, + elements: &[MetaVarExprConcatElem], +) -> PResult<'tx, TokenTree> { + let (symbol, concatenated_span) = metavar_expr_concat(tscx, dspan, elements)?; + if !rustc_lexer::is_ident(symbol.as_str()) { + return Err(tscx.psess.dcx().create_err(ConcatInvalidIdent { + span: concatenated_span, + reason: InvalidIdentReason::new(symbol), + })); + } + tscx.psess.symbol_gallery.insert(symbol, concatenated_span); + + // The current implementation marks the span as coming from the macro regardless of + // contexts of the concatenated identifiers but this behavior may change in the + // future. + Ok(TokenTree::Token( + Token::from_ast_ident(Ident::new(symbol, concatenated_span)), + Spacing::Alone, + )) +} + +/// Handle the `${concat_str(...)}` metavariable expression. +fn metavar_expr_concat_str<'tx>( tscx: &mut TranscrCtx<'tx, '_>, dspan: DelimSpan, elements: &[MetaVarExprConcatElem], ) -> PResult<'tx, TokenTree> { + let (symbol, concatenated_span) = metavar_expr_concat(tscx, dspan, elements)?; + + // The current implementation marks the span as coming from the macro regardless of + // contexts of the concatenated identifiers but this behavior may change in the + // future. + Ok(TokenTree::Token( + Token::new(TokenKind::lit(LitKind::Str, symbol, None), concatenated_span), + Spacing::Alone, + )) +} + +/// Shared logic for concat/concat_str metavariable expressions +fn metavar_expr_concat<'tx>( + tscx: &mut TranscrCtx<'tx, '_>, + dspan: DelimSpan, + elements: &[MetaVarExprConcatElem], +) -> PResult<'tx, (Symbol, Span)> { let dcx = tscx.psess.dcx(); let mut concatenated = String::new(); for element in elements { @@ -668,21 +710,7 @@ fn metavar_expr_concat<'tx>( } let symbol = nfc_normalize(&concatenated); let concatenated_span = tscx.visited_dspan(dspan); - if !rustc_lexer::is_ident(symbol.as_str()) { - return Err(dcx.create_err(ConcatInvalidIdent { - span: concatenated_span, - reason: InvalidIdentReason::new(symbol), - })); - } - tscx.psess.symbol_gallery.insert(symbol, concatenated_span); - - // The current implementation marks the span as coming from the macro regardless of - // contexts of the concatenated identifiers but this behavior may change in the - // future. - Ok(TokenTree::Token( - Token::from_ast_ident(Ident::new(symbol, concatenated_span)), - Spacing::Alone, - )) + Ok((symbol, concatenated_span)) } /// Store the metavariable span for this original span into a side table. diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 0f31ed196c3df..5855c1126a971 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -24,20 +24,18 @@ pub mod pat_util; mod stable_hash_impls; mod target_impls; +// FIXME: Remove this use tree, replace by `rustc_attr_ir` imports +#[doc(hidden)] +pub use attrs::{ + Attribute, ConstStability, DefaultBodyStability, Stability, StabilityLevel, StableSince, + UnstableReason, target::Target, +}; #[doc(no_inline)] pub use hir::*; +// FIXME: Remove this use tree, replace by `rustc_attr_ir` imports +#[doc(hidden)] pub use rustc_attr_ir::{self as attrs, find_attr}; pub use rustc_hir_id::*; pub use rustc_span::def_id; -// FIXME: Remove this use tree, replace by `rustc_hir::attrs` or `rustc_attr_ir` imports -#[doc(hidden)] -pub use { - attrs::target::{self, AssocCtxt, MethodKind, Target}, - attrs::{ - AttrArgs, AttrItem, AttrPath, Attribute, ConstStability, DefaultBodyStability, - HashIgnoredAttrId, PartialConstStability, Stability, StabilityLevel, StableSince, - UnstableReason, VERSION_PLACEHOLDER, - }, -}; pub use crate::arena::Arena; diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml index f5d7dbd3f96e4..8279d9c6d620a 100644 --- a/compiler/rustc_hir_pretty/Cargo.toml +++ b/compiler/rustc_hir_pretty/Cargo.toml @@ -8,6 +8,7 @@ edition = "2024" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_hir = { path = "../rustc_hir" } rustc_span = { path = "../rustc_span" } # tidy-alphabetical-end diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 6d1ae563a9fa2..ddd1a296ecd35 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -16,8 +16,8 @@ use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, BoxMarker, Breaks}; use rustc_ast_pretty::pprust::state::MacHeader; use rustc_ast_pretty::pprust::{Comments, PrintState}; +use rustc_attr_ir::{AttrArgs, AttrItem, Attribute, AttributeKind, PrintAttribute}; use rustc_hir as hir; -use rustc_hir::attrs::{AttributeKind, PrintAttribute}; use rustc_hir::{ BindingMode, ByRef, ConstArg, ConstArgExprField, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind, HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind, @@ -72,12 +72,12 @@ impl PpAnn for &dyn rustc_hir::intravisit::HirTyCtxt<'_> { pub struct State<'a> { pub s: pp::Printer, comments: Option>, - attrs: &'a dyn Fn(HirId) -> &'a [hir::Attribute], + attrs: &'a dyn Fn(HirId) -> &'a [Attribute], ann: &'a (dyn PpAnn + 'a), } impl<'a> State<'a> { - fn attrs(&self, id: HirId) -> &'a [hir::Attribute] { + fn attrs(&self, id: HirId) -> &'a [Attribute] { (self.attrs)(id) } @@ -86,7 +86,7 @@ impl<'a> State<'a> { expr.precedence(&has_attr) } - fn print_attrs(&mut self, attrs: &[hir::Attribute]) { + fn print_attrs(&mut self, attrs: &[Attribute]) { if attrs.is_empty() { return; } @@ -99,9 +99,9 @@ impl<'a> State<'a> { /// Print a single attribute as if it has style `style`, disregarding the /// actual style of the attribute. - fn print_attribute_as_style(&mut self, attr: &hir::Attribute, style: ast::AttrStyle) { + fn print_attribute_as_style(&mut self, attr: &Attribute, style: ast::AttrStyle) { match &attr { - hir::Attribute::Unparsed(unparsed) => { + Attribute::Unparsed(unparsed) => { self.maybe_print_comment(unparsed.span.lo()); match style { ast::AttrStyle::Inner => self.word("#!["), @@ -111,13 +111,13 @@ impl<'a> State<'a> { self.word("]"); self.hardbreak() } - hir::Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => { + Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => { self.word(rustc_ast_pretty::pprust::state::doc_comment_to_string( *kind, style, *comment, )); self.hardbreak() } - hir::Attribute::Parsed(pa) => { + Attribute::Parsed(pa) => { match style { ast::AttrStyle::Inner => self.word("#![attr = "), ast::AttrStyle::Outer => self.word("#[attr = "), @@ -129,7 +129,7 @@ impl<'a> State<'a> { } } - fn print_attr_item(&mut self, item: &hir::AttrItem, span: Span) { + fn print_attr_item(&mut self, item: &AttrItem, span: Span) { let ib = self.ibox(0); let path = ast::Path { span, @@ -146,21 +146,20 @@ impl<'a> State<'a> { }; match &item.args { - hir::AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self - .print_mac_common( - Some(MacHeader::Path(&path)), - false, - None, - *delim, - None, - &tokens, - true, - span, - ), - hir::AttrArgs::Empty => { + AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self.print_mac_common( + Some(MacHeader::Path(&path)), + false, + None, + *delim, + None, + &tokens, + true, + span, + ), + AttrArgs::Empty => { PrintState::print_path(self, &path, false, 0); } - hir::AttrArgs::Eq { eq_span: _, expr } => { + AttrArgs::Eq { eq_span: _, expr } => { PrintState::print_path(self, &path, false, 0); self.space(); self.word_space("="); @@ -277,7 +276,7 @@ pub fn print_crate<'a>( krate: &hir::Mod<'_>, filename: FileName, input: String, - attrs: &'a dyn Fn(HirId) -> &'a [hir::Attribute], + attrs: &'a dyn Fn(HirId) -> &'a [Attribute], ann: &'a dyn PpAnn, ) -> String { let mut s = State { @@ -311,7 +310,7 @@ where printer.s.eof() } -pub fn attribute_to_string(ann: &dyn PpAnn, attr: &hir::Attribute) -> String { +pub fn attribute_to_string(ann: &dyn PpAnn, attr: &Attribute) -> String { to_string(ann, |s| s.print_attribute_as_style(attr, ast::AttrStyle::Outer)) } diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 78f3929dbce47..450b98f20cde9 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -484,9 +484,8 @@ fn main() { let llvm_static_stdcpp = tracked_env_var_os("LLVM_STATIC_STDCPP"); let llvm_use_libcxx = tracked_env_var_os("LLVM_USE_LIBCXX"); - let stdcppname = if target.contains("openbsd") { - if target.contains("sparc64") { "estdc++" } else { "c++" } - } else if target.contains("darwin") + let stdcppname = if target.contains("openbsd") + || target.contains("darwin") || target.contains("freebsd") || target.contains("windows-gnullvm") || target.contains("aix") diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index ee71d4d46e48f..a423b6bdca5b2 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -107,9 +107,9 @@ rustc_arena::declare_arena! { upvars_mentioned: rustc_data_structures::fx::FxIndexMap, dyn_compatibility_violations: rustc_middle::traits::DynCompatibilityViolation, codegen_unit: rustc_middle::mono::CodegenUnit<'tcx>, - attribute: rustc_hir::Attribute, + attribute: rustc_attr_ir::Attribute, name_set: rustc_data_structures::unord::UnordSet, - autodiff_item: rustc_hir::attrs::AutoDiffItem, + autodiff_item: rustc_attr_ir::AutoDiffItem, ordered_name_set: rustc_data_structures::fx::FxIndexSet, stable_order_of_exportable_impls: rustc_data_structures::fx::FxIndexMap, @@ -131,7 +131,7 @@ rustc_arena::declare_arena! { >, external_constraints: rustc_middle::traits::solve::ExternalConstraintsData>, doc_link_resolutions: rustc_middle::middle::resolve::DocLinkResMap, - stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem, + stripped_cfg_items: rustc_attr_ir::StrippedCfgItem, mod_child: rustc_middle::middle::resolve::ModChild, features: rustc_feature::Features, specialization_graph: rustc_middle::traits::specialization_graph::Graph, @@ -204,9 +204,9 @@ impl_ref_decodable_into_arena! { Spanned>, rustc_ast::InlineAsmTemplatePiece, rustc_ast::tokenstream::TokenStream, + rustc_attr_ir::Attribute, rustc_data_structures::unord::UnordMap>>, rustc_data_structures::unord::UnordSet, - rustc_hir::Attribute, rustc_index::IndexVec>, rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs, rustc_middle::mir::Body<'tcx>, diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index affadfd0c6aaf..664c85980addd 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_ir::{Attribute, find_attr}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hash::{StableHash, StableHasher}; use rustc_data_structures::steal::Steal; diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index eae84fde7e305..d899ba0190f00 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -6,12 +6,13 @@ pub mod map; pub mod nested_filter; pub mod place; +use rustc_attr_ir::Attribute; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hash::{StableHash, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in}; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap, LocalModId}; use rustc_hir::lints::DelayedLints; diff --git a/compiler/rustc_middle/src/middle/debugger_visualizer.rs b/compiler/rustc_middle/src/middle/debugger_visualizer.rs index b6fc2d4f1a8d0..0fded7a77662d 100644 --- a/compiler/rustc_middle/src/middle/debugger_visualizer.rs +++ b/compiler/rustc_middle/src/middle/debugger_visualizer.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use std::sync::Arc; -use rustc_hir::attrs::DebuggerVisualizerType; +use rustc_attr_ir::DebuggerVisualizerType; use rustc_macros::{Decodable, Encodable, StableHash}; /// A single debugger visualizer file. diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index 829df12ff543c..9d07c2edeb386 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -7,7 +7,7 @@ //! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`. //! * Functions called by the compiler itself. -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_span::Span; use rustc_target::spec::PanicStrategy; diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 4c4a16953d5ed..6bb0190cd70b8 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1712,7 +1712,7 @@ pub enum BinOp { /// - `Ordering::Equal` (`0_i8`, as a Scalar) if `A == B` /// - `Ordering::Greater` (`+1_i8`, as a Scalar) if `A > B` /// - /// [`LangItem::OrderingEnum`]: rustc_hir::attrs::lang_items::LangItem + /// [`LangItem::OrderingEnum`]: rustc_attr_ir::lang_items::LangItem Cmp, /// The `ptr.offset` operator Offset, diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index cc75bebbb3f93..2d51f382f0998 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -3,9 +3,9 @@ use std::slice; use rustc_ast::InlineAsmOptions; +use rustc_attr_ir::AttributeKind; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::packed::Pu128; -use rustc_hir::attrs::AttributeKind; -use rustc_hir::attrs::lang_items::LangItem; use rustc_macros::{StableHash, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::bug; use smallvec::{SmallVec, smallvec}; diff --git a/compiler/rustc_middle/src/mono.rs b/compiler/rustc_middle/src/mono.rs index 76828cbee60f1..a54ca4faf81ee 100644 --- a/compiler/rustc_middle/src/mono.rs +++ b/compiler/rustc_middle/src/mono.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::fmt; use std::hash::Hash; +use rustc_attr_ir::{InlineAttr, Linkage}; use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexMap; @@ -11,7 +12,6 @@ use rustc_data_structures::stable_hash::{ use rustc_data_structures::unord::UnordMap; use rustc_hashes::Hash128; use rustc_hir::ItemId; -use rustc_hir::attrs::{InlineAttr, Linkage}; use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LOCAL_CRATE}; use rustc_macros::{StableHash, TyDecodable, TyEncodable}; use rustc_session::config::OptLevel; diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 9e1bafa4fd2a2..cb39c17cd4023 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -53,6 +53,7 @@ use rustc_arena::TypedArena; use rustc_ast as ast; use rustc_ast::expand::allocator::AllocatorKind; use rustc_ast::tokenstream::TokenStream; +use rustc_attr_ir::diagnostic_items::DiagnosticItems; use rustc_attr_ir::lang_items::{LangItem, LanguageItems}; use rustc_attr_ir::{CanonicalSymbols, EiiDecl, EiiImpl, StrippedCfgItem}; use rustc_crate_store::{ @@ -1493,19 +1494,19 @@ rustc_queries! { cache_on_disk } - query lookup_stability(def_id: DefId) -> Option { + query lookup_stability(def_id: DefId) -> Option { desc { "looking up stability of `{}`", tcx.def_path_str(def_id) } cache_on_disk separate_provide_extern } - query lookup_const_stability(def_id: DefId) -> Option { + query lookup_const_stability(def_id: DefId) -> Option { desc { "looking up const stability of `{}`", tcx.def_path_str(def_id) } cache_on_disk separate_provide_extern } - query lookup_default_body_stability(def_id: DefId) -> Option { + query lookup_default_body_stability(def_id: DefId) -> Option { desc { "looking up default body stability of `{}`", tcx.def_path_str(def_id) } separate_provide_extern } @@ -2302,7 +2303,7 @@ rustc_queries! { } /// Returns all diagnostic items defined in all crates. - query all_diagnostic_items(_: ()) -> &'tcx rustc_hir::attrs::diagnostic_items::DiagnosticItems { + query all_diagnostic_items(_: ()) -> &'tcx DiagnosticItems { arena_cache eval_always desc { "calculating the diagnostic items map" } @@ -2322,7 +2323,7 @@ rustc_queries! { } /// Returns the diagnostic items defined in a crate. - query diagnostic_items(_: CrateNum) -> &'tcx rustc_hir::attrs::diagnostic_items::DiagnosticItems { + query diagnostic_items(_: CrateNum) -> &'tcx DiagnosticItems { arena_cache desc { "calculating the diagnostic items map in a crate" } separate_provide_extern diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 15a684491dcab..b0281a70eeb73 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -185,11 +185,11 @@ impl_erasable_for_types_with_no_type_params! { Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>, Option, Option, + Option, + Option, + Option, Option, - Option, Option, - Option, - Option, Option, Option, Option, diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index b20dfe68d98e2..69d518bf82786 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -15,10 +15,10 @@ use std::sync::Arc; use rustc_abi::{FieldIdx, Integer, Size, VariantIdx}; use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece, Mutability}; +use rustc_attr_ir::AttributeKind; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::thin_vec::ThinVec; use rustc_hir as hir; -use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::DefId; use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd}; use rustc_index::{IndexVec, newtype_index}; diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 19b72d1a7d1c4..b13af2705c736 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -1,7 +1,7 @@ +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::{DefId, DefIdMap}; -use rustc_hir::find_attr; use rustc_macros::{StableHash, TyDecodable, TyEncodable}; use crate::diagnostics::StrictCoherenceNeedsNegativeCoherence; diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 00efbe912b883..b3a2925b24bfa 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -1,6 +1,6 @@ use rustc_abi::FieldIdx; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_macros::{StableHash, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::Span; diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index d189fbc5d59bd..8ad5de3fa85cc 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -4,6 +4,8 @@ use std::ops::Range; use std::str; use rustc_abi::{FIRST_VARIANT, FieldIdx, ReprOptions, VariantIdx}; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; @@ -11,10 +13,9 @@ use rustc_data_structures::stable_hash::{ StableHash, StableHashControls, StableHashCtxt, StableHasher, }; use rustc_errors::ErrorGuaranteed; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, find_attr}; use rustc_index::{IndexSlice, IndexVec}; use rustc_macros::{StableHash, TyDecodable, TyEncodable}; use rustc_session::DataTypeKind; diff --git a/compiler/rustc_middle/src/ty/consts/lit.rs b/compiler/rustc_middle/src/ty/consts/lit.rs index 08dadf6ad9f5f..9dd8c958cd2f0 100644 --- a/compiler/rustc_middle/src/ty/consts/lit.rs +++ b/compiler/rustc_middle/src/ty/consts/lit.rs @@ -1,6 +1,5 @@ use rustc_ast::{LitFloatType, LitIntType, LitKind}; -use rustc_hir; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_macros::StableHash; use crate::ty::{self, Ty, TyCtxt}; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index bd9a5e80b1855..108279fb55d8e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -17,6 +17,8 @@ use std::{debug_assert_matches, fmt, iter, mem}; use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx}; use rustc_ast as ast; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; use rustc_crate_store::{CrateStoreDyn, Untracked}; use rustc_data_structures::defer; use rustc_data_structures::fx::FxHashMap; @@ -29,12 +31,11 @@ use rustc_data_structures::sync::{ self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal, }; use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan}; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState}; use rustc_hir::intravisit::Visitor; -use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr}; +use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate}; use rustc_index::IndexVec; use rustc_lint_defs::Lint; use rustc_lint_defs::builtin::UNUSED_FEATURES; @@ -990,7 +991,7 @@ impl<'tcx> TyCtxt<'tcx> { } /// Obtain all lang items of this crate and all dependencies (recursively) - pub fn lang_items(self) -> &'tcx rustc_hir::attrs::lang_items::LanguageItems { + pub fn lang_items(self) -> &'tcx rustc_attr_ir::lang_items::LanguageItems { self.get_lang_items(()) } diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 6e838c4454c4c..26a8df2bc24d4 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -2,10 +2,10 @@ use std::{debug_assert_matches, fmt}; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::intern::Interned; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_span::{DUMMY_SP, Span, Symbol, bug}; diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 1f2a9aca60142..df1daac366c53 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -3,9 +3,9 @@ use std::fmt::Write; use std::ops::ControlFlow; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::{Applicability, Diag, DiagArgValue, IntoDiagArg, listify, pluralize}; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, AmbigArg, PredicateOrigin, WherePredicateKind}; diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 44e5a875a74ae..1a00293f8ffc6 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -1,9 +1,9 @@ use std::{assert_matches, fmt}; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_macros::{Lift, StableHash, TyDecodable, TyEncodable}; @@ -231,7 +231,7 @@ impl<'tcx> Instance<'tcx> { if !tcx.sess.opts.share_generics() // However, if the def_id is marked inline(never), then it's fine to just reuse the // upstream monomorphization. - && tcx.codegen_fn_attrs(self.def_id()).inline != rustc_hir::attrs::InlineAttr::Never + && tcx.codegen_fn_attrs(self.def_id()).inline != rustc_attr_ir::InlineAttr::Never { return None; } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index f717f8270daf3..53747bfbf826e 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -6,9 +6,9 @@ use rustc_abi::{ PointerKind, Primitive, ReprFlags, ReprOptions, Scalar, Size, TagEncoding, TargetDataLayout, TyAbiInterface, VariantIdx, Variants, }; +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::{Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, IntoDiagArg, Level}; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_macros::{StableHash, TyDecodable, TyEncodable, extension}; use rustc_session::config::OptLevel; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 94345380a544e..06b6260afd504 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1869,7 +1869,7 @@ impl<'tcx> TyCtxt<'tcx> { } /// Gets all attributes with the given name. - #[deprecated = "Though there are valid usecases for this method, especially when your attribute is not a parsed attribute, usually you want to call rustc_hir::find_attr! instead."] + #[deprecated = "Though there are valid usecases for this method, especially when your attribute is not a parsed attribute, usually you want to use `rustc_attr_ir::find_attr!` instead."] pub fn get_attrs( self, did: impl Into, @@ -1888,7 +1888,7 @@ impl<'tcx> TyCtxt<'tcx> { /// /// /// - #[deprecated = "Though there are valid usecases for this method, especially when your attribute is not a parsed attribute, usually you want to call rustc_hir::find_attr! instead."] + #[deprecated = "Though there are valid usecases for this method, especially when your attribute is not a parsed attribute, usually you want to use `rustc_attr_ir::find_attr!` instead."] pub fn get_all_attrs(self, did: impl Into) -> &'tcx [rustc_attr_ir::Attribute] { let did: DefId = did.into(); if let Some(did) = did.as_local() { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index ba4a59daad01d..73f41c632a552 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -6,11 +6,11 @@ use std::ops::{Deref, DerefMut}; use rustc_abi::{ExternAbi, Size}; use rustc_apfloat::Float; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; +use rustc_attr_ir::lang_items::LangItem; use rustc_crate_store::{ExternCrate, ExternCrateSource}; use rustc_data_structures::fx::{FxIndexMap, IndexEntry}; use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{DefIdMap, DefIdSet, LOCAL_CRATE, ModId}; use rustc_hir::definitions::{DefKey, DefPathDataName}; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 0ea7e403ee111..0b0a08217579d 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -229,11 +229,11 @@ TrivialTypeTraversalImpls! { rustc_abi::VariantIdx, rustc_ast::InlineAsmOptions, rustc_ast::InlineAsmTemplatePiece, + rustc_attr_ir::AttributeKind, rustc_hir::CoroutineKind, rustc_hir::HirId, rustc_hir::MatchSource, rustc_hir::RangeEnd, - rustc_hir::attrs::AttributeKind, rustc_hir::def_id::LocalDefId, rustc_span::Ident, rustc_span::Span, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f4b1f0ce0881d..e714f08929a2e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -8,9 +8,9 @@ use std::ops::{ControlFlow, Range}; use hir::def::{CtorKind, DefKind}; use rustc_abi::{FIRST_VARIANT, FieldIdx, NumScalableVectors, ScalableElt, VariantIdx}; +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_macros::{StableHash, TyDecodable, TyEncodable, TypeFoldable, extension}; use rustc_span::{DUMMY_SP, Span, Symbol, bug, kw, sym}; diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index fce9af1c465af..114e5331b8b9b 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -1,10 +1,11 @@ use std::iter; +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; +use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_hir::{self as hir, find_attr}; use rustc_macros::{Decodable, Encodable, StableHash}; use rustc_span::{Span, bug}; use tracing::debug; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index db983038e1af9..2200736f697dd 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -4,13 +4,14 @@ use std::{fmt, iter}; use rustc_abi::{Float, Integer, IntegerType, Size}; use rustc_apfloat::Float as _; +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hash::{StableHash, StableHasher}; use rustc_errors::ErrorGuaranteed; use rustc_hashes::Hash128; +use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; -use rustc_hir::{self as hir, find_attr}; use rustc_index::bit_set::GrowableBitSet; use rustc_macros::{StableHash, TyDecodable, TyEncodable, extension}; use rustc_span::{bug, span_bug, sym}; diff --git a/compiler/rustc_mir_transform/src/coroutine/layout.rs b/compiler/rustc_mir_transform/src/coroutine/layout.rs index a06ae343123d1..03d4aff960fcf 100644 --- a/compiler/rustc_mir_transform/src/coroutine/layout.rs +++ b/compiler/rustc_mir_transform/src/coroutine/layout.rs @@ -252,6 +252,7 @@ fn compute_storage_conflicts<'mir, 'tcx>( saved_locals, local_conflicts: BitMatrix::from_row_n(&ineligible_locals, body.local_decls.len()), eligible_storage_live: DenseBitSet::new_empty(body.local_decls.len()), + last_recorded_storage_live: DenseBitSet::new_empty(body.local_decls.len()), }; // Filter out: @@ -296,6 +297,10 @@ struct StorageConflictVisitor<'a> { local_conflicts: BitMatrix, // We keep this bitset as a buffer to avoid reallocating memory. eligible_storage_live: DenseBitSet, + // The last live set whose conflicts were recorded. This is just a fast path: + // if the current live set is a subset, we can skip updating the conflict matrix + // since its conflicts have already been recorded. + last_recorded_storage_live: DenseBitSet, } impl<'a, 'tcx> ResultsVisitor<'tcx, MaybeRequiresStorage> for StorageConflictVisitor<'a> { @@ -323,9 +328,14 @@ impl StorageConflictVisitor<'_> { self.eligible_storage_live.clone_from(state); self.eligible_storage_live.intersect(&**self.saved_locals); + if self.last_recorded_storage_live.superset(&self.eligible_storage_live) { + return; + } + for local in self.eligible_storage_live.iter() { self.local_conflicts.union_row_with(&self.eligible_storage_live, local); } + std::mem::swap(&mut self.last_recorded_storage_live, &mut self.eligible_storage_live); } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 3a4875c1d0951..e5b8c8759f9bc 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -460,7 +460,10 @@ where // Relating types is always unproductive. If we were to map proof trees to // corecursive functions as explained in #136824, relating types never // introduces a constructor which could cause the recursion to be guarded. - GoalSource::TypeRelating => PathKind::Inductive, + // + // FIXME(-Znext-solver=coinductive): For now we treat all inductive cycles as + // `Unknown`. See the comment in `fn initial_provisional_result`. + GoalSource::TypeRelating => PathKind::Unknown, // These goal sources are likely unproductive and can be changed to // `PathKind::Inductive`. Keeping them as unknown until we're confident // about this and have an example where it is necessary. diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index e147a139a65e1..ecd175d694d7d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -1,9 +1,9 @@ use std::convert::Infallible; use std::marker::PhantomData; +use rustc_type_ir::Interner; use rustc_type_ir::search_graph::{self, PathKind}; use rustc_type_ir::solve::{AccessedOpaques, Certainty, NoSolution, QueryResult, RerunResultExt}; -use rustc_type_ir::{Interner, MayBeErased, TypingMode}; use crate::canonical::response_no_constraints_raw; use crate::delegate::SolverDelegate; @@ -52,29 +52,21 @@ where PathKind::Unknown | PathKind::ForcedAmbiguity => { response_no_constraints(cx, input, Certainty::overflow(false)) } - // Even though we know these cycles to be unproductive, we still return - // overflow during coherence. This is both as we are not 100% confident in - // the implementation yet and any incorrect errors would be unsound there. + // Even though we know some cycles to be unproductive, we still treat them + // as unknown for now. This is both as we are not 100% confident in the + // implementation yet and any incorrect errors would be unsound there. + // // The affected cases are also fairly artificial and not necessarily desirable // so keeping this as ambiguity is fine for now. // - // See `tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs` for an - // example where this would matter. We likely should change these cycles to `NoSolution` - // even in coherence once this is a bit more settled. - PathKind::Inductive => match input.typing_mode.0 { - TypingMode::Coherence => { - response_no_constraints(cx, input, Certainty::overflow(false)) - } - TypingMode::Typeck { .. } - | TypingMode::PostTypeckUntilBorrowck { .. } - | TypingMode::Reflection - | TypingMode::PostBorrowck { .. } - | TypingMode::PostAnalysis - | TypingMode::Codegen - | TypingMode::ErasedNotCoherence(MayBeErased) => { - (Err(NoSolution), AccessedOpaques::default()) - } - }, + // See `tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs` and + // `tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.rs` + // for examples where this would matter. + // + // FIXME(-Znext-solver=coinductive): Long term, we probably do want to + // return `NoSolution` here. This should happen separately from the + // stabilization of the new solver. + PathKind::Inductive => unreachable!(), } } diff --git a/compiler/rustc_parse/src/diagnostics.rs b/compiler/rustc_parse/src/diagnostics.rs index 566b257d1058d..b6482aa23e836 100644 --- a/compiler/rustc_parse/src/diagnostics.rs +++ b/compiler/rustc_parse/src/diagnostics.rs @@ -4651,3 +4651,15 @@ pub(crate) struct SuggestIntroduceTypeParameter { pub span: Span, pub parameters: String, } + +#[derive(Subdiagnostic)] +#[suggestion( + "you might have meant to write a diverging block on a refutable `let` statement by using `let-else` + for more information, visit ", + code = " else ", + applicability = "maybe-incorrect" +)] +pub(crate) struct MissingElseInLet { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index db6af6ab17aca..928518c88fec6 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2140,16 +2140,32 @@ impl<'a> Parser<'a> { let pat = self.parse_pat_no_top_alt(Some(Expected::ArgumentName), None)?; self.expect(exp!(Colon))?; let ty = self.parse_ty()?; - self.dcx().emit_err(PatternMethodParamWithoutBody { - span: pat.span, - target: match context { - FnContext::Trait => "methods without bodies", - FnContext::FunctionPtrType => "function pointer types", - FnContext::ParenthesizedArgumentList => "parenthesized argument list", - FnContext::Free => unreachable!("This method is not called in free functions, as patterns are always allowed there"), - FnContext::Impl => unreachable!("This method is not called in impls, as patterns are always allowed there"), - }, - }); + match context { + FnContext::Trait + | FnContext::FunctionPtrType + | FnContext::ParenthesizedArgumentList => { + self.dcx().emit_err(PatternMethodParamWithoutBody { + span: pat.span, + target: if context == FnContext::Trait { + "methods without bodies" + } else if context == FnContext::FunctionPtrType { + "function pointer types" + } else { + "parenthesized argument list" + }, + }); + } + FnContext::Free | FnContext::Impl => { + self.dcx().span_delayed_bug( + pat.span, + if context == FnContext::Free { + "This method is not called in free functions, as patterns are always allowed there" + } else { + "This method is not called in impls, as patterns are always allowed there" + }, + ); + } + } // Pretend the pattern is `_`, to avoid duplicate errors from AST validation. let pat = Box::new(Pat { kind: PatKind::Wild, span: pat.span, id: ast::DUMMY_NODE_ID }); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a2db5c047394a..5bc30ae7ba325 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -57,7 +57,11 @@ impl<'a> Parser<'a> { self.current_closure.take(); self.parse_expr_res(Restrictions::empty()) } - + #[inline] + pub fn parse_expr_in_let(&mut self) -> PResult<'a, Box> { + self.current_closure.take(); + self.parse_expr_res(Restrictions::IN_LET) + } /// Parses an expression, forcing tokens to be collected. pub fn parse_expr_force_collect(&mut self) -> PResult<'a, Box> { self.current_closure.take(); @@ -3680,11 +3684,12 @@ impl<'a> Parser<'a> { Option, /* async blocks are forbidden in Rust 2015 */ ), > { + let open_span = self.prev_token.span; //{ let mut fields = ThinVec::new(); let mut base = ast::StructRest::None; let mut recovered_async = None; let in_if_guard = self.restrictions.contains(Restrictions::IN_IF_GUARD); - + let in_let = self.restrictions.contains(Restrictions::IN_LET); let async_block_err = |e: &mut Diag<'_>, span: Span| { crate::diagnostics::AsyncBlockIn2015 { span }.add_to_diag(e); crate::diagnostics::HelpUseLatestEdition::new().add_to_diag(e); @@ -3769,6 +3774,28 @@ impl<'a> Parser<'a> { return Err(e); } + if in_let { + // Better diagnostic for `foo { return 42; };` + // We've consumed `foo {` already + let mut snapshot = self.create_snapshot_for_diagnostic(); + let might_be_stmt = snapshot.token.is_keyword(kw::Return); + snapshot.consume_block( + exp!(OpenBrace), + exp!(CloseBrace), + super::diagnostics::ConsumeClosingDelim::Yes, + ); //consume to the end of the block, including `}` + + // make sure the block is at the end by eating a `;`, + // we shouldn't report such diagnostic for `let a = foo{return 43;}+bar;` + // also skip the suggestion if the span cross macro boundaries + if might_be_stmt && snapshot.eat(exp!(Semi)) && pth.span.eq_ctxt(open_span) + { + let span = pth.span.between(open_span); + e.subdiagnostic(crate::diagnostics::MissingElseInLet { span }); + self.restore_snapshot(snapshot); + return Err(e); + } + } let guar = e.emit_err(); if pth == kw::Async { recovered_async = Some(guar); diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 281ca98e97639..50ded81e3eeec 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -125,6 +125,9 @@ bitflags::bitflags! { /// expression, but halts parsing the expression when reaching certain /// tokens like `=`. const IS_PAT = 1 << 5; + /// Used to detect a missing `else` in a let statement. + /// e.g. let Some(foo) = bar{return;}; + const IN_LET = 1 << 6; } } diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index a082ea678737d..d59ef93eded21 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -3,14 +3,13 @@ use std::mem; use std::ops::Bound; use ast::Label; -use rustc_ast as ast; use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind}; use rustc_ast::tokenstream::TokenTree; use rustc_ast::util::classify::{self, TrailingBrace}; use rustc_ast::visit::{Visitor, walk_expr}; use rustc_ast::{ - AttrStyle, AttrVec, Block, BlockCheckMode, DUMMY_NODE_ID, Expr, ExprKind, HasAttrs, Local, - LocalKind, MacCall, MacCallStmt, MacStmtStyle, Recovered, Stmt, StmtKind, + self as ast, AttrStyle, AttrVec, Block, BlockCheckMode, DUMMY_NODE_ID, Expr, ExprKind, + HasAttrs, Local, LocalKind, MacCall, MacCallStmt, MacStmtStyle, Recovered, Stmt, StmtKind, }; use rustc_errors::{Applicability, Diag, PResult}; use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; @@ -517,7 +516,7 @@ impl<'a> Parser<'a> { _ => self.eat(exp!(Eq)), }; - Ok(if eq_consumed || eq_optional { Some(self.parse_expr()?) } else { None }) + Ok(if eq_consumed || eq_optional { Some(self.parse_expr_in_let()?) } else { None }) } /// Parses a block. No inner attributes are allowed. diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index f2b98f1fa2c03..1a2ccc75d0bcf 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -1,7 +1,6 @@ -use rustc_hir::attrs::RustcAbiAttrKind; +use rustc_attr_ir::{RustcAbiAttrKind, find_attr}; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_hir::find_attr; use rustc_middle::ty::layout::{FnAbiError, LayoutError}; use rustc_middle::ty::{self, GenericArgs, Instance, Ty, TyCtxt}; use rustc_span::{Span, span_bug}; diff --git a/compiler/rustc_passes/src/canonical_symbols.rs b/compiler/rustc_passes/src/canonical_symbols.rs index 7a67a46c5a738..afecab452bf3d 100644 --- a/compiler/rustc_passes/src/canonical_symbols.rs +++ b/compiler/rustc_passes/src/canonical_symbols.rs @@ -1,5 +1,5 @@ -use rustc_hir::attrs::CanonicalSymbols; -use rustc_hir::{ForeignItemId, find_attr}; +use rustc_attr_ir::{CanonicalSymbols, find_attr}; +use rustc_hir::ForeignItemId; use rustc_middle::query::{LocalCrate, Providers}; use rustc_middle::ty::{Instance, List, TyCtxt}; use rustc_span::def_id::{DefId, LOCAL_CRATE}; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index f6bd780802401..4926ec9872d3b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -10,23 +10,23 @@ use std::slice; use rustc_abi::ExternAbi; use rustc_ast::MetaItemKind; +use rustc_attr_ir::diagnostic::Directive; +use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::target::{AssocCtxt, MethodKind, Target}; +use rustc_attr_ir::{ + Attribute, AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, + InlineAttr, OptimizeAttr, ReprAttr, find_attr, +}; use rustc_attr_parsing::AttributeParser; use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, msg}; use rustc_feature::BUILTIN_ATTRIBUTE_SET; -use rustc_hir::attrs::diagnostic::Directive; -use rustc_hir::attrs::lang_items::LangItem; -use rustc_hir::attrs::{ - AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, InlineAttr, - OptimizeAttr, ReprAttr, -}; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalModId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ - self as hir, AssocCtxt, Attribute, CRATE_HIR_ID, Constness, FnSig, ForeignItem, GenericParam, - GenericParamKind, HirId, Item, ItemKind, MethodKind, Mod, Node, ParamName, Target, TraitItem, - find_attr, + self as hir, CRATE_HIR_ID, Constness, FnSig, ForeignItem, GenericParam, GenericParamKind, + HirId, Item, ItemKind, Mod, Node, ParamName, TraitItem, }; use rustc_lint_defs::builtin::{ CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_ATTRIBUTES, diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index 91e7c69c2efdb..f5aa163d59a6e 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -1,9 +1,8 @@ //! Detecting usage of the `#[debugger_visualizer]` attribute. use rustc_ast::{ItemKind, ast}; +use rustc_attr_ir::{Attribute, AttributeKind, DebugVisualizer}; use rustc_attr_parsing::AttributeParser; -use rustc_hir::Attribute; -use rustc_hir::attrs::{AttributeKind, DebugVisualizer}; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::query::{LocalCrate, Providers}; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 74cd94259f4b4..1f17edb3254e3 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -9,8 +9,9 @@ //! //! * Compiler internal types like `Ty` and `TyCtxt` -use rustc_hir::attrs::diagnostic_items::DiagnosticItems; -use rustc_hir::{CRATE_OWNER_ID, OwnerId, find_attr}; +use rustc_attr_ir::diagnostic_items::DiagnosticItems; +use rustc_attr_ir::find_attr; +use rustc_hir::{CRATE_OWNER_ID, OwnerId}; use rustc_middle::query::{LocalCrate, Providers}; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{DefId, LOCAL_CRATE}; diff --git a/compiler/rustc_passes/src/eii.rs b/compiler/rustc_passes/src/eii.rs index 05cb10e174d89..4daff2358e87f 100644 --- a/compiler/rustc_passes/src/eii.rs +++ b/compiler/rustc_passes/src/eii.rs @@ -3,8 +3,8 @@ use std::iter; +use rustc_attr_ir::{EiiDecl, EiiImpl}; use rustc_data_structures::fx::FxIndexMap; -use rustc_hir::attrs::{EiiDecl, EiiImpl}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_middle::diagnostics::DuplicateEiiImpls; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 68be74886a2e4..0306a0bc349af 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -9,9 +9,9 @@ use rustc_ast as ast; use rustc_ast::visit; +use rustc_attr_ir::lang_items::{GenericRequirement, LangItem, LanguageItems}; +use rustc_attr_ir::target::Target; use rustc_crate_store::ExternCrate; -use rustc_hir::Target; -use rustc_hir::attrs::lang_items::{GenericRequirement, LangItem, LanguageItems}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::middle::resolve::ResolverAstLowering; use rustc_middle::query::Providers; diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index f73916d861f27..961d39ec8e5ca 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -1,8 +1,7 @@ use rustc_abi::{HasDataLayout, TargetDataLayout}; -use rustc_hir::attrs::RustcDumpLayoutKind; +use rustc_attr_ir::{RustcDumpLayoutKind, find_attr}; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_hir::find_attr; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers}; use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized}; use rustc_span::{Span, span_bug}; diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index ceaad91d25982..2420d55545805 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -4,9 +4,8 @@ //! but are not declared in one single location (unlike lang features), which means we need to //! collect them instead. -use rustc_hir::attrs::AttributeKind; +use rustc_attr_ir::{Attribute, AttributeKind, StabilityLevel, StableSince}; use rustc_hir::intravisit::Visitor; -use rustc_hir::{Attribute, StabilityLevel, StableSince}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures}; use rustc_middle::query::{LocalCrate, Providers}; diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index b2535b4c4d9c0..1148aac51f3e8 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -4,17 +4,19 @@ use std::num::NonZero; use rustc_ast_lowering::stability::extern_abi_stability; +use rustc_attr_ir::{ + AttributeKind, ConstStability, DefaultBodyStability, DeprecatedSince, Stability, + StabilityLevel, StableSince, UnstableReason, VERSION_PLACEHOLDER, find_attr, +}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet}; use rustc_feature::{EnabledLangFeature, EnabledLibFeature, UNSTABLE_LANG_FEATURES}; -use rustc_hir::attrs::{AttributeKind, DeprecatedSince}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ - self as hir, AmbigArg, ConstStability, Constness, DefaultBodyStability, FieldDef, HirId, Item, - ItemKind, Path, Stability, StabilityLevel, StableSince, TraitRef, Ty, TyKind, UnstableReason, - UsePath, VERSION_PLACEHOLDER, Variant, find_attr, + self as hir, AmbigArg, Constness, FieldDef, HirId, Item, ItemKind, Path, TraitRef, Ty, TyKind, + UsePath, Variant, }; use rustc_lint_defs::builtin::{ DEPRECATED, DUPLICATE_FEATURES, INEFFECTIVE_UNSTABLE_REEXPORTS, diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index e7042767f8bae..42e07bc0eaaee 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -1,8 +1,8 @@ //! Validity checking for weak lang items +use rustc_attr_ir::lang_items::{self, LangItem}; +use rustc_attr_ir::weak_lang_items::WEAK_LANG_ITEMS; use rustc_data_structures::fx::FxHashSet; -use rustc_hir::attrs::lang_items::{self, LangItem}; -use rustc_hir::attrs::weak_lang_items::WEAK_LANG_ITEMS; use rustc_middle::middle::lang_items::required; use rustc_middle::ty::TyCtxt; use rustc_structures::CrateType; diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index 19a4ee5a55ff7..a635f7853d971 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -13,6 +13,7 @@ pulldown-cmark = { version = "0.11", features = [ rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 89ea973cb3ff8..ee35d23691628 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -2,11 +2,10 @@ use std::mem; use rustc_ast::visit::FnKind; use rustc_ast::*; -use rustc_attr_parsing as attr; +use rustc_attr_ir::target::Target; use rustc_attr_parsing::{AttributeParser, ShouldEmit}; use rustc_expand::expand::AstFragment; use rustc_hir as hir; -use rustc_hir::Target; use rustc_hir::def::DefKind; use rustc_hir::def::Namespace::{TypeNS, ValueNS}; use rustc_hir::def_id::LocalDefId; @@ -558,7 +557,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { let orig_in_attr = mem::replace(&mut self.invocation_parent.in_attr, true); match &attr.kind { AttrKind::Normal(normal) => { - if attr::is_builtin_attr(&normal.item) { + if rustc_attr_parsing::is_builtin_attr(&normal.item) { self.r .builtin_attrs .push((normal.item.path.segments[0].ident, self.parent_scope)); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 098b6595f166e..bd70e5acab4d7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -680,6 +680,7 @@ symbols! { complex, concat, concat_bytes, + concat_str, conservative_impl_trait, console, const_allocate, diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml index bb79bb3ece781..1e078015257d7 100644 --- a/compiler/rustc_symbol_mangling/Cargo.toml +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -8,6 +8,7 @@ edition = "2024" punycode = "0.4.0" rustc-demangle = "0.1.28" rustc_abi = { path = "../rustc_abi" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index a4364cc20b68e..646a916fb5085 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -4,7 +4,8 @@ //! def-path. This is used for unit testing the code that generates //! paths etc in all kinds of annoying scenarios. -use rustc_hir::{CRATE_OWNER_ID, find_attr}; +use rustc_attr_ir::find_attr; +use rustc_hir::CRATE_OWNER_ID; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{GenericArgs, Instance, TyCtxt}; diff --git a/compiler/rustc_target/src/asm/nvptx.rs b/compiler/rustc_target/src/asm/nvptx.rs index da8b79d8935be..4aaafe1e9b49c 100644 --- a/compiler/rustc_target/src/asm/nvptx.rs +++ b/compiler/rustc_target/src/asm/nvptx.rs @@ -36,9 +36,9 @@ impl NvptxInlineAsmRegClass { _arch: InlineAsmArch, ) -> &'static [(InlineAsmType, Option)] { match self { - Self::reg16 => types! { _: I8, I16; }, - Self::reg32 => types! { _: I8, I16, I32, F32; }, - Self::reg64 => types! { _: I8, I16, I32, F32, I64, F64; }, + Self::reg16 => types! { _: I8, I16, F16; }, + Self::reg32 => types! { _: I8, I16, F16, I32, F32; }, + Self::reg64 => types! { _: I8, I16, F16, I32, F32, I64, F64; }, } } } diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index 5da9435e77e63..55e2f7e99b869 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -6,8 +6,8 @@ edition = "2024" [dependencies] # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi", optional = true } +rustc_attr_ir = { path = "../rustc_attr_ir", optional = true } rustc_data_structures = { path = "../rustc_data_structures" } -rustc_hir = { path = "../rustc_hir", optional = true } rustc_middle = { path = "../rustc_middle", optional = true } rustc_span = { path = "../rustc_span", optional = true } smallvec = "1.8.1" @@ -23,7 +23,7 @@ itertools = "0.15" # tidy-alphabetical-start rustc = [ "dep:rustc_abi", - "dep:rustc_hir", + "dep:rustc_attr_ir", "dep:rustc_middle", "dep:rustc_span", ] diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index e2e1b0a08e15a..f29516fabc32a 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -103,7 +103,7 @@ pub enum Reason { #[cfg(feature = "rustc")] mod rustc { - use rustc_hir::attrs::lang_items::LangItem; + use rustc_attr_ir::lang_items::LangItem; use rustc_middle::ty::{Const, Region, Ty, TyCtxt}; use super::*; diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index e6de7bd1fab24..5ac4d72a6c573 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" # tidy-alphabetical-start itertools = "0.15" rustc_abi = { path = "../rustc_abi" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hashes = { path = "../rustc_hashes" } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 55140d2c5458d..bcba5839926db 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -2,7 +2,7 @@ use std::{assert_matches, iter}; use rustc_abi::Primitive::Pointer; use rustc_abi::{Align, BackendRepr, ExternAbi, PointerKind, Scalar, Size}; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir::{self as hir, find_attr}; use rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs; use rustc_middle::query::Providers; diff --git a/compiler/rustc_ty_utils/src/common_traits.rs b/compiler/rustc_ty_utils/src/common_traits.rs index 4d25a2886fa27..48e2a68bec7f6 100644 --- a/compiler/rustc_ty_utils/src/common_traits.rs +++ b/compiler/rustc_ty_utils/src/common_traits.rs @@ -1,6 +1,6 @@ //! Queries for checking whether a type implements one of a few common traits. -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index f0f0a66a8eeba..9a41caafc6da6 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,5 +1,5 @@ +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::ErrorGuaranteed; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index dee4b785e418d..43af74d10aba7 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -9,9 +9,9 @@ use rustc_abi::{ LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding, VariantIdx, Variants, WrappingRange, }; +use rustc_attr_ir::lang_items::LangItem; use rustc_hashes::Hash64; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::find_attr; use rustc_index::{Idx as _, IndexVec}; use rustc_middle::query::Providers; diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs index 85d13cfda743b..7dd596fa5bdfc 100644 --- a/compiler/rustc_ty_utils/src/structural_match.rs +++ b/compiler/rustc_ty_utils/src/structural_match.rs @@ -1,4 +1,4 @@ -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt, TypingMode}; diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index ce36a9324b119..201f0072dd330 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -668,8 +668,6 @@ impl Box { /// # Examples /// /// ``` - /// #![feature(box_take)] - /// /// let c = Box::new(5); /// /// // take the value out of the box @@ -680,7 +678,7 @@ impl Box { /// let c = Box::write(uninit, 6); /// assert_eq!(*c, 6); /// ``` - #[unstable(feature = "box_take", issue = "147212")] + #[stable(feature = "box_take", since = "CURRENT_RUSTC_VERSION")] pub fn take(boxed: Self) -> (T, Box, A>) { // SAFETY: Reading out an initialised value & leaving behind a // box with uninit contents. diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 5164365336c9d..53916bbfc2e7c 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -658,8 +658,8 @@ impl CStr { #[must_use = "this does not display the `CStr`; \ it returns an object that can be displayed"] #[inline] - pub fn display(&self) -> impl fmt::Display { - crate::bstr::ByteStr::from_bytes(self.to_bytes()) + pub fn display(&self) -> Display<'_> { + Display { c_str: self } } /// Returns the same string as a string slice `&CStr`. @@ -855,3 +855,41 @@ impl Iterator for Bytes<'_> { #[unstable(feature = "cstr_bytes", issue = "112115")] impl FusedIterator for Bytes<'_> {} + +/// Helper struct for safely printing a [`CStr`] with [`format!`] and `{}`. +/// +/// A [`CStr`] might contain non-Unicode data. This `struct` implements the +/// [`Display`] trait in a way that mitigates that. It is created by the +/// [`display`](CStr::display) method on [`CStr`]. This may perform lossy +/// conversion, depending on the platform. If you would like an implementation +/// which escapes the [`CStr`] please use [`Debug`] instead. +/// +/// # Examples +/// +/// ``` +/// #![feature(cstr_display)] +/// +/// let s = c"Hello, world!"; +/// println!("{}", s.display()); +/// ``` +/// +/// [`Display`]: fmt::Display +/// [`format!`]: ../../../std/macro.format.html +#[unstable(feature = "cstr_display", issue = "139984")] +pub struct Display<'a> { + c_str: &'a CStr, +} + +#[unstable(feature = "cstr_display", issue = "139984")] +impl fmt::Debug for Display<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.c_str, f) + } +} + +#[unstable(feature = "cstr_display", issue = "139984")] +impl fmt::Display for Display<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(crate::bstr::ByteStr::from_bytes(self.c_str.to_bytes()), f) + } +} diff --git a/library/core/src/io/borrowed_buf.rs b/library/core/src/io/borrowed_buf.rs index 7b03d58a3fd62..2cc1ebba1a85c 100644 --- a/library/core/src/io/borrowed_buf.rs +++ b/library/core/src/io/borrowed_buf.rs @@ -222,6 +222,14 @@ pub struct BorrowedCursor<'a, T> { borrowed_buf: NonNull>, } +// SAFETY: A `BorrowedCursor<'a, T>` is a unique borrow of a `BorrowedBuf<'a, T>`, which is a +// `&'a mut [MaybeUninit]` and two `Copy` fields. The `buf` raw pointer is used like +// `&mut [MaybeUninit]` so `T: Send` -> `Send` and is: `T: Sync` -> `Sync`, and the +// `borrowed_buf` only touches two `Copy` fields, without depending of `T`. +unsafe impl Send for BorrowedCursor<'_, T> {} +// SAFETY: See the `Send` impl above. +unsafe impl Sync for BorrowedCursor<'_, T> {} + impl Debug for BorrowedCursor<'_, T> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let buf = BorrowedBufDebug { diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index f5c7c853ef590..25326f4f066c6 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -1576,6 +1576,16 @@ pub enum FpCategory { #[inline(always)] #[unstable(issue = "none", feature = "std_internals")] pub const fn can_not_overflow(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool { + // Assume that `digits` represents a whole number N in base `radix`. + // Then in infinite precision arithmetic (on whole numbers), we have: + // + // |N| <= pow(radix, digits.len()) - 1 + // <= pow(16, 2 * size_of::() - is_signed) - 1 + // == pow(2, 8 * size_of::() - 4 * is_signed) - 1 + // <= pow(2, 8 * size_of::() - is_signed) - 1 + // == T::MAX + // + // Therefore this condition is sufficient for having no overflow. radix <= 16 && digits.len() <= size_of::() * 2 - is_signed_ty as usize } @@ -1819,20 +1829,23 @@ macro_rules! from_str_int_impl { // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest: // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow. // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow. - macro_rules! run_unchecked_loop { - ($unchecked_additive_op:tt) => {{ + // + // NOTE: We could use unchecked arithmetic here, but we don't, based on the observation + // that it produces the same assembly as wrapping ones. See #163099. + macro_rules! run_no_check_loop { + ($additive_op:ident) => {{ while let [c, rest @ ..] = digits { - result = result * (radix as $int_ty); + result = <$int_ty>::wrapping_mul(result, radix as _); let x = unwrap_or_PIE!((*c as char).to_digit(radix), InvalidDigit); - result = result $unchecked_additive_op (x as $int_ty); + result = result.$additive_op(x as $int_ty); digits = rest; } }}; } if is_positive { - run_unchecked_loop!(+) + run_no_check_loop!(wrapping_add) } else { - run_unchecked_loop!(-) + run_no_check_loop!(wrapping_sub) }; } else { macro_rules! run_checked_loop { diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index cb0ca5d1376ea..9c3a6758929a8 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -8,6 +8,8 @@ pub use alloc::ffi::c_str::IntoStringError; pub use alloc::ffi::c_str::{CString, NulError}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::ffi::c_str::CStr; +#[unstable(feature = "cstr_display", issue = "139984")] +pub use core::ffi::c_str::Display; #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] pub use core::ffi::c_str::FromBytesUntilNulError; #[stable(feature = "cstr_from_bytes", since = "1.10.0")] diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 043f854ea79fd..fb0acdab835a9 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -204,11 +204,7 @@ unsafe extern "C" {} #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] unsafe extern "C" {} -#[cfg(all(target_os = "openbsd", target_arch = "sparc64"))] -#[link(name = "gcc")] -unsafe extern "C" {} - -#[cfg(all(target_os = "openbsd", not(target_arch = "sparc64")))] +#[cfg(target_os = "openbsd")] #[link(name = "c++abi")] unsafe extern "C" {} diff --git a/src/doc/rustc/src/platform-support/openbsd.md b/src/doc/rustc/src/platform-support/openbsd.md index e6fb23ca9eefd..75bae0e2382fd 100644 --- a/src/doc/rustc/src/platform-support/openbsd.md +++ b/src/doc/rustc/src/platform-support/openbsd.md @@ -14,7 +14,7 @@ The target names follow this format: `$ARCH-unknown-openbsd`, where `$ARCH` spec | `i686-unknown-openbsd` | libc++ | [Standard PC and clones based on the Intel i386 architecture and compatible processors](https://www.openbsd.org/i386.html) | | `powerpc64-unknown-openbsd` | libc++ | [IBM POWER-based PowerNV systems](https://www.openbsd.org/powerpc64.html) | | `riscv64gc-unknown-openbsd` | libc++ | [64-bit RISC-V systems](https://www.openbsd.org/riscv64.html) | -| `sparc64-unknown-openbsd` | estdc++ | [Sun UltraSPARC and Fujitsu SPARC64 systems](https://www.openbsd.org/sparc64.html) | +| `sparc64-unknown-openbsd` | libc++ | [Sun UltraSPARC and Fujitsu SPARC64 systems](https://www.openbsd.org/sparc64.html) | | `x86_64-unknown-openbsd` | libc++ | [AMD64-based systems](https://www.openbsd.org/amd64.html) | Note that all OS versions are *major* even if using X.Y notation (`6.8` and `6.9` are different major versions) and could be binary incompatibles (with breaking changes). diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 4d7895264c158..64fff96201939 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -11,7 +11,6 @@ path = "lib.rs" # tidy-alphabetical-start arrayvec = { version = "0.7", default-features = false } askama = { version = "0.16.1", default-features = false, features = ["alloc", "config", "derive"] } -base64 = "0.21.7" indexmap = { version = "2", features = ["serde"] } itertools = "0.15" libc = "0.2" diff --git a/src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs b/src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs index e3b1a05bda7dd..ff929df0acded 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs @@ -2,7 +2,7 @@ use super::DEPRECATED_SEMVER; use clippy_utils::diagnostics::span_lint; use clippy_utils::sym; use rustc_ast::{LitKind, MetaItemLit}; -use rustc_hir::VERSION_PLACEHOLDER; +use rustc_attr_ir::VERSION_PLACEHOLDER; use rustc_lint::EarlyContext; use rustc_span::Span; use semver::Version; diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index af2c84737c655..2ef893edd4236 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -1,11 +1,9 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint; use clippy_utils::{is_doc_hidden, is_from_proc_macro}; -use rustc_attr_ir::AttributeKind; +use rustc_attr_ir::{AttrArgs, Attribute, AttributeKind}; use rustc_hir::def_id::LocalDefId; -use rustc_hir::{ - AttrArgs, Attribute, Body, BodyId, FieldDef, HirId, ImplItem, Item, ItemKind, Node, TraitItem, Variant, -}; +use rustc_hir::{Body, BodyId, FieldDef, HirId, ImplItem, Item, ItemKind, Node, TraitItem, Variant}; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; use rustc_middle::middle::privacy::Level; use rustc_middle::ty::Visibility; diff --git a/tests/assembly-llvm/asm/nvptx-types.rs b/tests/assembly-llvm/asm/nvptx-types.rs index 1cb176cf5148a..15c4dabbfecee 100644 --- a/tests/assembly-llvm/asm/nvptx-types.rs +++ b/tests/assembly-llvm/asm/nvptx-types.rs @@ -3,7 +3,7 @@ //@ compile-flags: --target nvptx64-nvidia-cuda //@ needs-llvm-components: nvptx -#![feature(no_core, asm_experimental_arch)] +#![feature(no_core, asm_experimental_arch, f16)] #![crate_type = "rlib"] #![no_core] @@ -38,78 +38,96 @@ macro_rules! check { // CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg16_i8 // CHECK: // begin inline asm -// CHECK: mov.i16 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b16 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg16_i8 i8 reg16 "mov.i16"); +check!(reg16_i8 i8 reg16 "mov.b16"); // CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg16_i16 // CHECK: // begin inline asm -// CHECK: mov.i16 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b16 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg16_i16 i16 reg16 "mov.i16"); +check!(reg16_i16 i16 reg16 "mov.b16"); + +// CHECK-LABEL: .visible .func (.param .align 2 .b8 func_retval0[2]) reg16_f16 +// CHECK: // begin inline asm +// CHECK: mov.b16 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: // end inline asm +check!(reg16_f16 f16 reg16 "mov.b16"); // CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg32_i8 // CHECK: // begin inline asm -// CHECK: mov.i32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg32_i8 i8 reg32 "mov.i32"); +check!(reg32_i8 i8 reg32 "mov.b32"); // CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg32_i16 // CHECK: // begin inline asm -// CHECK: mov.i32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg32_i16 i16 reg32 "mov.i32"); +check!(reg32_i16 i16 reg32 "mov.b32"); + +// CHECK-LABEL: .visible .func (.param .align 2 .b8 func_retval0[2]) reg32_f16 +// CHECK: // begin inline asm +// CHECK: mov.b32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: // end inline asm +check!(reg32_f16 f16 reg32 "mov.b32"); // CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg32_i32 // CHECK: // begin inline asm -// CHECK: mov.i32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg32_i32 i32 reg32 "mov.i32"); +check!(reg32_i32 i32 reg32 "mov.b32"); // CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg32_f32 // CHECK: // begin inline asm -// CHECK: mov.i32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg32_f32 f32 reg32 "mov.i32"); +check!(reg32_f32 f32 reg32 "mov.b32"); // CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg64_i8 // CHECK: // begin inline asm -// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg64_i8 i8 reg64 "mov.i64"); +check!(reg64_i8 i8 reg64 "mov.b64"); // CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg64_i16 // CHECK: // begin inline asm -// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: // end inline asm +check!(reg64_i16 i16 reg64 "mov.b64"); + +// CHECK-LABEL: .visible .func (.param .align 2 .b8 func_retval0[2]) reg64_f16 +// CHECK: // begin inline asm +// CHECK: mov.b64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg64_i16 i16 reg64 "mov.i64"); +check!(reg64_f16 f16 reg64 "mov.b64"); // CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg64_i32 // CHECK: // begin inline asm -// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg64_i32 i32 reg64 "mov.i64"); +check!(reg64_i32 i32 reg64 "mov.b64"); // CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg64_f32 // CHECK: // begin inline asm -// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg64_f32 f32 reg64 "mov.i64"); +check!(reg64_f32 f32 reg64 "mov.b64"); // CHECK-LABEL: .visible .func (.param .b64 func_retval0) reg64_i64 // CHECK: // begin inline asm -// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg64_i64 i64 reg64 "mov.i64"); +check!(reg64_i64 i64 reg64 "mov.b64"); // CHECK-LABEL: .visible .func (.param .b64 func_retval0) reg64_f64 // CHECK: // begin inline asm -// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg64_f64 f64 reg64 "mov.i64"); +check!(reg64_f64 f64 reg64 "mov.b64"); // CHECK-LABEL: .visible .func (.param .b64 func_retval0) reg64_ptr // CHECK: // begin inline asm -// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; +// CHECK: mov.b64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}}; // CHECK: // end inline asm -check!(reg64_ptr ptr reg64 "mov.i64"); +check!(reg64_ptr ptr reg64 "mov.b64"); diff --git a/tests/codegen-llvm/float/f16b.rs b/tests/codegen-llvm/float/f16b.rs index 7de6a776190c9..3bd245546b7cf 100644 --- a/tests/codegen-llvm/float/f16b.rs +++ b/tests/codegen-llvm/float/f16b.rs @@ -1,4 +1,13 @@ //@ compile-flags: -Copt-level=3 +//@ revisions: GENERIC LOONGARCH32 LOONGARCH64 RISCV32 RISCV64 +//@ [GENERIC] ignore-loongarch32 +//@ [GENERIC] ignore-loongarch64 +//@ [GENERIC] ignore-riscv32 +//@ [GENERIC] ignore-riscv64 +//@ [LOONGARCH32] only-loongarch32 +//@ [LOONGARCH64] only-loongarch64 +//@ [RISCV32] only-riscv32 +//@ [RISCV64] only-riscv64 #![crate_type = "lib"] #![feature(f16b)] @@ -8,31 +17,63 @@ extern crate core; use core::num::f16b; -// CHECK-LABEL: define{{.*}} bfloat @identity_f16b(bfloat +// GENERIC-LABEL: define{{.*}} bfloat @identity_f16b(bfloat +// LOONGARCH32-LABEL: define{{.*}} half @identity_f16b(half +// LOONGARCH64-LABEL: define{{.*}} half @identity_f16b(half +// RISCV32-LABEL: define{{.*}} half @identity_f16b(half +// RISCV64-LABEL: define{{.*}} half @identity_f16b(half #[no_mangle] pub extern "C" fn identity_f16b(value: f16b) -> f16b { - // CHECK: ret bfloat + // GENERIC: ret bfloat + // LOONGARCH32: ret half + // LOONGARCH64: ret half + // RISCV32: ret half + // RISCV64: ret half value } -// CHECK-LABEL: define{{.*}} i16 @f16b_to_bits(bfloat +// GENERIC-LABEL: define{{.*}} i16 @f16b_to_bits(bfloat +// LOONGARCH32-LABEL: define{{.*}} i16 @f16b_to_bits(half +// LOONGARCH64-LABEL: define{{.*}} i16 @f16b_to_bits(half +// RISCV32-LABEL: define{{.*}} i16 @f16b_to_bits(half +// RISCV64-LABEL: define{{.*}} i16 @f16b_to_bits(half #[no_mangle] pub extern "C" fn f16b_to_bits(value: f16b) -> u16 { - // CHECK: bitcast bfloat %value to i16 + // GENERIC: bitcast bfloat %value to i16 + // LOONGARCH32: bitcast half %0 to i16 + // LOONGARCH64: bitcast half %0 to i16 + // RISCV32: bitcast half %0 to i16 + // RISCV64: bitcast half %0 to i16 value.to_bits() } -// CHECK-LABEL: define{{.*}} bfloat @f16b_from_bits(i16 +// GENERIC-LABEL: define{{.*}} bfloat @f16b_from_bits(i16 +// LOONGARCH32-LABEL: define{{.*}} half @f16b_from_bits(i16 +// LOONGARCH64-LABEL: define{{.*}} half @f16b_from_bits(i16 +// RISCV32-LABEL: define{{.*}} half @f16b_from_bits(i16 +// RISCV64-LABEL: define{{.*}} half @f16b_from_bits(i16 #[no_mangle] pub extern "C" fn f16b_from_bits(bits: u16) -> f16b { - // CHECK: bitcast i16 %bits to bfloat + // GENERIC: bitcast i16 %bits to bfloat + // LOONGARCH32: bitcast i16 %bits to half + // LOONGARCH64: bitcast i16 %bits to half + // RISCV32: bitcast i16 %bits to half + // RISCV64: bitcast i16 %bits to half f16b::from_bits(bits) } -// CHECK-LABEL: define{{.*}} float @widen_f16b(bfloat +// GENERIC-LABEL: define{{.*}} float @widen_f16b(bfloat +// LOONGARCH32-LABEL: define{{.*}} float @widen_f16b(half +// LOONGARCH64-LABEL: define{{.*}} float @widen_f16b(half +// RISCV32-LABEL: define{{.*}} float @widen_f16b(half +// RISCV64-LABEL: define{{.*}} float @widen_f16b(half #[no_mangle] pub extern "C" fn widen_f16b(value: f16b) -> f32 { - // CHECK: bitcast bfloat %value to i16 + // GENERIC: bitcast bfloat %value to i16 + // LOONGARCH32: bitcast half %0 to i16 + // LOONGARCH64: bitcast half %0 to i16 + // RISCV32: bitcast half %0 to i16 + // RISCV64: bitcast half %0 to i16 // CHECK: zext i16 // CHECK: shl nuw i32 {{.*}}, 16 // CHECK: bitcast i32 {{.*}} to float diff --git a/tests/ui-fulldeps/internal-lints/find_attr.rs b/tests/ui-fulldeps/internal-lints/find_attr.rs index 90b9b96ba54ef..f2ee921c731f4 100644 --- a/tests/ui-fulldeps/internal-lints/find_attr.rs +++ b/tests/ui-fulldeps/internal-lints/find_attr.rs @@ -4,9 +4,9 @@ #![feature(rustc_private)] #![deny(rustc::bad_use_of_find_attr)] -extern crate rustc_hir; +extern crate rustc_attr_ir; -use rustc_hir::{attrs::AttributeKind, find_attr}; +use rustc_attr_ir::{AttributeKind, find_attr}; fn main() { let attrs = &[]; diff --git a/tests/ui-fulldeps/polymorphic-drop-glue.rs b/tests/ui-fulldeps/polymorphic-drop-glue.rs index 861c7c74b705c..4d85d342d7395 100644 --- a/tests/ui-fulldeps/polymorphic-drop-glue.rs +++ b/tests/ui-fulldeps/polymorphic-drop-glue.rs @@ -6,6 +6,7 @@ //@ ignore-backends: gcc #![feature(rustc_private)] +extern crate rustc_attr_ir; extern crate rustc_driver; extern crate rustc_hir; extern crate rustc_interface; @@ -16,7 +17,7 @@ extern crate rustc_span; use std::process::ExitCode; use rustc_driver::Compilation; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir::def::DefKind; use rustc_interface::interface::Compiler; use rustc_middle::ty::{self, TyCtxt}; diff --git a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs index f449e02baadb8..8b0b92b8a7842 100644 --- a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs +++ b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs @@ -10,7 +10,7 @@ fn foo<'a, T>() where T: Proj<'a, Assoc = fn(::Assoc)>, (): Trait<>::Assoc>, - //~^ ERROR the trait bound `(): Trait fn(>::Assoc))>` is not satisfied + //~^ ERROR overflow evaluating the requirement `(): Trait<>::Assoc>` { } diff --git a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr index 5e8e131addd28..9d1c8c4a10d02 100644 --- a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr +++ b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr @@ -1,14 +1,9 @@ -error[E0277]: the trait bound `(): Trait fn(>::Assoc))>` is not satisfied +error[E0275]: overflow evaluating the requirement `(): Trait<>::Assoc>` --> $DIR/placeholder-assumptions-issue-157840.rs:12:9 | LL | (): Trait<>::Assoc>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait fn(>::Assoc))>` is not implemented for `()` - | -help: consider extending the `where` clause, but there might be an alternative better way to express this requirement - | -LL | (): Trait<>::Assoc>, (): Trait fn(>::Assoc))> - | +++++++++++++++++++++++++++++++++++++++++++++++++ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/feature-gates/feature-gate-macro-metavar-expr-concat.rs b/tests/ui/feature-gates/feature-gate-macro-metavar-expr-concat.rs index e700999ae4bd8..898bc28974c88 100644 --- a/tests/ui/feature-gates/feature-gate-macro-metavar-expr-concat.rs +++ b/tests/ui/feature-gates/feature-gate-macro-metavar-expr-concat.rs @@ -1,7 +1,8 @@ macro_rules! join { ($lhs:ident, $rhs:ident) => { - let ${concat($lhs, $rhs)}: () = (); + let ${concat($lhs, $rhs)}: &'static str = ${concat_str($lhs, $rhs)}; //~^ ERROR the `concat` meta-variable expression is unstable + //~| ERROR the `concat_str` meta-variable expression is unstable }; } diff --git a/tests/ui/feature-gates/feature-gate-macro-metavar-expr-concat.stderr b/tests/ui/feature-gates/feature-gate-macro-metavar-expr-concat.stderr index 5b2589d8c89be..47c09a119298d 100644 --- a/tests/ui/feature-gates/feature-gate-macro-metavar-expr-concat.stderr +++ b/tests/ui/feature-gates/feature-gate-macro-metavar-expr-concat.stderr @@ -1,13 +1,23 @@ error[E0658]: the `concat` meta-variable expression is unstable --> $DIR/feature-gate-macro-metavar-expr-concat.rs:3:14 | -LL | let ${concat($lhs, $rhs)}: () = (); +LL | let ${concat($lhs, $rhs)}: &'static str = ${concat_str($lhs, $rhs)}; | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #124225 for more information = help: add `#![feature(macro_metavar_expr_concat)]` 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: aborting due to 1 previous error +error[E0658]: the `concat_str` meta-variable expression is unstable + --> $DIR/feature-gate-macro-metavar-expr-concat.rs:3:52 + | +LL | let ${concat($lhs, $rhs)}: &'static str = ${concat_str($lhs, $rhs)}; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #124225 for more information + = help: add `#![feature(macro_metavar_expr_concat)]` 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: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/macros/metavar-expressions/concat-allowed-operations.rs b/tests/ui/macros/metavar-expressions/concat-allowed-operations.rs index 5ac50c943d030..cd0c23da1dd4f 100644 --- a/tests/ui/macros/metavar-expressions/concat-allowed-operations.rs +++ b/tests/ui/macros/metavar-expressions/concat-allowed-operations.rs @@ -5,7 +5,7 @@ macro_rules! create_things { ($lhs:ident) => { - struct ${concat($lhs, _separated_idents_in_a_struct)} { + struct ${concat($lhs, _separated_idents_in_a_struct)} { foo: i32, ${concat($lhs, _separated_idents_in_a_field)}: i32, } @@ -20,19 +20,23 @@ macro_rules! create_things { macro_rules! many_idents { ($a:ident, $c:ident) => { + #[allow(dead_code, reason = ${concat_str($a, B, $c, D)})] const ${concat($a, B, $c, D)}: i32 = 1; }; } macro_rules! valid_tts { ($_0:tt, $_1:tt) => { + #[allow(dead_code, reason = ${concat_str($_0, $_1)})] const ${concat($_0, $_1)}: i32 = 1; } } macro_rules! without_dollar_sign_is_an_ident { ($ident:ident) => { + #[allow(dead_code, reason = ${concat_str(VAR, ident)})] const ${concat(VAR, ident)}: i32 = 1; + #[allow(dead_code, reason = ${concat_str(VAR, $ident)})] const ${concat(VAR, $ident)}: i32 = 2; }; } @@ -40,60 +44,103 @@ macro_rules! without_dollar_sign_is_an_ident { macro_rules! combinations { ($ident:ident, $literal:literal, $tt_ident:tt, $tt_literal:tt) => {{ // tt ident + #[allow(dead_code, reason = ${concat_str($tt_ident, b)})] let ${concat($tt_ident, b)} = (); + #[allow(dead_code, reason = ${concat_str($tt_ident, _b)})] let ${concat($tt_ident, _b)} = (); + #[allow(dead_code, reason = ${concat_str($tt_ident, "b")})] let ${concat($tt_ident, "b")} = (); + #[allow(dead_code, reason = ${concat_str($tt_ident, $tt_ident)})] let ${concat($tt_ident, $tt_ident)} = (); + #[allow(dead_code, reason = ${concat_str($tt_ident, $tt_literal)})] let ${concat($tt_ident, $tt_literal)} = (); + #[allow(dead_code, reason = ${concat_str($tt_ident, $ident)})] + let ${concat($tt_ident, $ident)} = (); + #[allow(dead_code, reason = ${concat_str($tt_ident, $ident)})] let ${concat($tt_ident, $ident)} = (); - let ${concat($tt_ident, $literal)} = (); // tt literal + #[allow(dead_code, reason = ${concat_str($tt_literal, b)})] let ${concat($tt_literal, b)} = (); + #[allow(dead_code, reason = ${concat_str($tt_literal, _b)})] let ${concat($tt_literal, _b)} = (); + #[allow(dead_code, reason = ${concat_str($tt_literal, "b")})] let ${concat($tt_literal, "b")} = (); + #[allow(dead_code, reason = ${concat_str($tt_literal, $tt_ident)})] let ${concat($tt_literal, $tt_ident)} = (); + #[allow(dead_code, reason = ${concat_str($tt_literal, $tt_literal)})] let ${concat($tt_literal, $tt_literal)} = (); + #[allow(dead_code, reason = ${concat_str($tt_literal, $ident)})] let ${concat($tt_literal, $ident)} = (); + #[allow(dead_code, reason = ${concat_str($tt_literal, $literal)})] let ${concat($tt_literal, $literal)} = (); // ident (adhoc) + #[allow(dead_code, reason = ${concat_str(_b, b)})] let ${concat(_b, b)} = (); + #[allow(dead_code, reason = ${concat_str(_b, _b)})] let ${concat(_b, _b)} = (); + #[allow(dead_code, reason = ${concat_str(_b, "b")})] let ${concat(_b, "b")} = (); + #[allow(dead_code, reason = ${concat_str(_b, $tt_ident)})] let ${concat(_b, $tt_ident)} = (); + #[allow(dead_code, reason = ${concat_str(_b, $tt_literal)})] let ${concat(_b, $tt_literal)} = (); + #[allow(dead_code, reason = ${concat_str(_b, $ident)})] let ${concat(_b, $ident)} = (); + #[allow(dead_code, reason = ${concat_str(_b, $literal)})] let ${concat(_b, $literal)} = (); // ident (param) + #[allow(dead_code, reason = ${concat_str($ident, b)})] let ${concat($ident, b)} = (); + #[allow(dead_code, reason = ${concat_str($ident, _b)})] let ${concat($ident, _b)} = (); + #[allow(dead_code, reason = ${concat_str($ident, "b")})] let ${concat($ident, "b")} = (); + #[allow(dead_code, reason = ${concat_str($ident, $tt_ident)})] let ${concat($ident, $tt_ident)} = (); + #[allow(dead_code, reason = ${concat_str($ident, $tt_literal)})] let ${concat($ident, $tt_literal)} = (); + #[allow(dead_code, reason = ${concat_str($ident, $ident)})] let ${concat($ident, $ident)} = (); + #[allow(dead_code, reason = ${concat_str($ident, $literal)})] let ${concat($ident, $literal)} = (); // literal (adhoc) + #[allow(dead_code, reason = ${concat_str("a", b)})] let ${concat("a", b)} = (); + #[allow(dead_code, reason = ${concat_str("a", _b)})] let ${concat("a", _b)} = (); + #[allow(dead_code, reason = ${concat_str("a", "b")})] let ${concat("a", "b")} = (); + #[allow(dead_code, reason = ${concat_str("a", $tt_ident)})] let ${concat("a", $tt_ident)} = (); + #[allow(dead_code, reason = ${concat_str("a", $tt_literal)})] let ${concat("a", $tt_literal)} = (); + #[allow(dead_code, reason = ${concat_str("a", $ident)})] let ${concat("a", $ident)} = (); + #[allow(dead_code, reason = ${concat_str("a", $literal)})] let ${concat("a", $literal)} = (); // literal (param) + #[allow(dead_code, reason = ${concat_str($literal, b)})] let ${concat($literal, b)} = (); + #[allow(dead_code, reason = ${concat_str($literal, _b)})] let ${concat($literal, _b)} = (); + #[allow(dead_code, reason = ${concat_str($literal, "b")})] let ${concat($literal, "b")} = (); + #[allow(dead_code, reason = ${concat_str($literal, $tt_ident)})] let ${concat($literal, $tt_ident)} = (); + #[allow(dead_code, reason = ${concat_str($literal, $tt_literal)})] let ${concat($literal, $tt_literal)} = (); + #[allow(dead_code, reason = ${concat_str($literal, $ident)})] let ${concat($literal, $ident)} = (); + #[allow(dead_code, reason = ${concat_str($literal, $literal)})] let ${concat($literal, $literal)} = (); }}; } macro_rules! int_struct { ($n: literal) => { + #[allow(dead_code, reason = ${concat_str(E, $n)})] struct ${concat(E, $n)}; } } diff --git a/tests/ui/macros/metavar-expressions/concat-str-escape.rs b/tests/ui/macros/metavar-expressions/concat-str-escape.rs new file mode 100644 index 0000000000000..612c957b831eb --- /dev/null +++ b/tests/ui/macros/metavar-expressions/concat-str-escape.rs @@ -0,0 +1,20 @@ +//@ run-pass + +#![feature(macro_metavar_expr_concat)] + +macro_rules! escape_literal { + ($literal:literal, $concatted:literal) => { + let lit = ${concat_str("_", "\"foo", $literal)}; + assert_eq!(lit, concat!("_", "\"foo", $literal)); + assert_eq!(lit, $concatted); + + } +} + +fn main(){ + escape_literal!("\u{00BD}", "_\"foo\u{00BD}"); + escape_literal!("\x41", "_\"foo\x41"); + escape_literal!("🤷", "_\"foo🤷"); + escape_literal!("\u{1F980}", "_\"foo🦀"); + escape_literal!("aaa \"bbb\" ccc", "_\"fooaaa \"bbb\" ccc"); +} diff --git a/tests/ui/macros/metavar-expressions/concat-str-horror.rs b/tests/ui/macros/metavar-expressions/concat-str-horror.rs new file mode 100644 index 0000000000000..558e55539e870 --- /dev/null +++ b/tests/ui/macros/metavar-expressions/concat-str-horror.rs @@ -0,0 +1,13 @@ +//@ run-pass +#![feature(macro_metavar_expr_concat)] + +macro_rules! format_horror{ + ($arg1:ident, $arg2:expr, $arg3:expr) => { + format!(${concat_str("horror ", $arg1, " horror {} horror {}")}, $arg2, $arg3) + } +} + +fn main(){ + let x = format_horror!(a, "b", "c"); + assert_eq!(x, "horror a horror b horror c"); +} diff --git a/tests/ui/macros/metavar-expressions/concat-str.rs b/tests/ui/macros/metavar-expressions/concat-str.rs new file mode 100644 index 0000000000000..f04e620d6826e --- /dev/null +++ b/tests/ui/macros/metavar-expressions/concat-str.rs @@ -0,0 +1,20 @@ +#![feature(macro_metavar_expr_concat)] +#![crate_type = "lib"] + +macro_rules! make_stuff { + ($prefix:literal, $name:ident) => { + #[deprecated(since = "1.0.0", note = ${concat_str($prefix, " ", $name, " trait")})] + #[diagnostic::on_unimplemented(message = ${concat_str("please do not the ", $name)})] + pub trait ${concat(New, $name)} {} + } +} + +make_stuff!("blah blah blah", AAAAAA); + +pub fn foo(x: impl NewAAAAAA) {} +//~^ WARN use of deprecated trait `NewAAAAAA`: blah blah blah AAAAAA trait [deprecated] + +fn bar(){ + foo(()); + //~^ ERROR please do not the AAAAAA [E0277] +} diff --git a/tests/ui/macros/metavar-expressions/concat-str.stderr b/tests/ui/macros/metavar-expressions/concat-str.stderr new file mode 100644 index 0000000000000..2e7e8cda4af06 --- /dev/null +++ b/tests/ui/macros/metavar-expressions/concat-str.stderr @@ -0,0 +1,35 @@ +warning: use of deprecated trait `NewAAAAAA`: blah blah blah AAAAAA trait + --> $DIR/concat-str.rs:14:20 + | +LL | pub fn foo(x: impl NewAAAAAA) {} + | ^^^^^^^^^ + | + = note: `#[warn(deprecated)]` on by default + +error[E0277]: please do not the AAAAAA + --> $DIR/concat-str.rs:18:9 + | +LL | macro_rules! make_stuff { +... +LL | foo(()); + | --- ^^ the trait `NewAAAAAA` is not implemented for `()` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/concat-str.rs:8:9 + | +LL | pub trait ${concat(New, $name)} {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | make_stuff!("blah blah blah", AAAAAA); + | ------------------------------------- in this macro invocation +note: required by a bound in `foo` + --> $DIR/concat-str.rs:14:20 + | +LL | pub fn foo(x: impl NewAAAAAA) {} + | ^^^^^^^^^ required by this bound in `foo` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/parser/detect-missing-else-in-let-1.rs b/tests/ui/parser/detect-missing-else-in-let-1.rs new file mode 100644 index 0000000000000..9f9d11e558d4c --- /dev/null +++ b/tests/ui/parser/detect-missing-else-in-let-1.rs @@ -0,0 +1,8 @@ +// detect missing else in let statement. (issue #135857) +fn main() { + let foo = Some(1); + let Some(a) = foo{return;}; + //~^ HELP you might have meant to write a diverging block + //~| HELP escape `return` to use it as an identifier + //~| ERROR expected identifier, found keyword `return` +} diff --git a/tests/ui/parser/detect-missing-else-in-let-1.stderr b/tests/ui/parser/detect-missing-else-in-let-1.stderr new file mode 100644 index 0000000000000..2236bb1671464 --- /dev/null +++ b/tests/ui/parser/detect-missing-else-in-let-1.stderr @@ -0,0 +1,20 @@ +error: expected identifier, found keyword `return` + --> $DIR/detect-missing-else-in-let-1.rs:4:23 + | +LL | let Some(a) = foo{return;}; + | --- ^^^^^^ expected identifier, found keyword + | | + | while parsing this struct + | +help: escape `return` to use it as an identifier + | +LL | let Some(a) = foo{r#return;}; + | ++ +help: you might have meant to write a diverging block on a refutable `let` statement by using `let-else` + for more information, visit + | +LL | let Some(a) = foo else {return;}; + | ++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/detect-missing-else-in-let-2.rs b/tests/ui/parser/detect-missing-else-in-let-2.rs new file mode 100644 index 0000000000000..87a5a750bf9f5 --- /dev/null +++ b/tests/ui/parser/detect-missing-else-in-let-2.rs @@ -0,0 +1,10 @@ +// the compiler currently will suggest the user to add `else` in this case +// it shouldn't because `bar` is an irrefutable pattern, the else block would never be valid/useful +// it is currently unmitigated +fn main(){ + let foo = 12; + let bar = foo{return;}; + //~^ HELP you might have meant to write a diverging block + //~| HELP escape `return` to use it as an identifier + //~| ERROR expected identifier, found keyword `return` +} diff --git a/tests/ui/parser/detect-missing-else-in-let-2.stderr b/tests/ui/parser/detect-missing-else-in-let-2.stderr new file mode 100644 index 0000000000000..5f21c9fe5fa83 --- /dev/null +++ b/tests/ui/parser/detect-missing-else-in-let-2.stderr @@ -0,0 +1,20 @@ +error: expected identifier, found keyword `return` + --> $DIR/detect-missing-else-in-let-2.rs:6:19 + | +LL | let bar = foo{return;}; + | --- ^^^^^^ expected identifier, found keyword + | | + | while parsing this struct + | +help: escape `return` to use it as an identifier + | +LL | let bar = foo{r#return;}; + | ++ +help: you might have meant to write a diverging block on a refutable `let` statement by using `let-else` + for more information, visit + | +LL | let bar = foo else {return;}; + | ++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.rs b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.rs new file mode 100644 index 0000000000000..abbff103bb2be --- /dev/null +++ b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.rs @@ -0,0 +1,5 @@ +// Regression test for https://github.com/rust-lang/rust/issues/160337. + +struct Baz where U : fn(() : bool) +//~^ ERROR expected identifier, found keyword `fn` +//~| ERROR expected `{` after struct name, found `` diff --git a/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.stderr b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.stderr new file mode 100644 index 0000000000000..02ec950b3a365 --- /dev/null +++ b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.stderr @@ -0,0 +1,20 @@ +error: expected identifier, found keyword `fn` + --> $DIR/recover-invalid-fn-trait-bound-pattern.rs:3:22 + | +LL | struct Baz where U : fn(() : bool) + | ^^ + | +help: use `Fn` to refer to the trait (notice the capitalization) + | +LL - struct Baz where U : fn(() : bool) +LL + struct Baz where U : Fn(() : bool) + | + +error: expected `{` after struct name, found `` + --> $DIR/recover-invalid-fn-trait-bound-pattern.rs:3:34 + | +LL | struct Baz where U : fn(() : bool) + | ^ expected `{` after struct name + +error: aborting due to 2 previous errors + diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern.rs b/tests/ui/parser/recover-invalid-function-parameter-pattern.rs new file mode 100644 index 0000000000000..a9e6a5578486f --- /dev/null +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern.rs @@ -0,0 +1,6 @@ +// Regression test for https://github.com/rust-lang/rust/issues/160337. + +fn main(... : ...) +//~^ ERROR unexpected `...` +//~| ERROR unexpected `...` +//~| ERROR expected one of `->`, `where`, or `{`, found `` diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern.stderr b/tests/ui/parser/recover-invalid-function-parameter-pattern.stderr new file mode 100644 index 0000000000000..d4b78db29dba9 --- /dev/null +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern.stderr @@ -0,0 +1,28 @@ +error: unexpected `...` + --> $DIR/recover-invalid-function-parameter-pattern.rs:3:9 + | +LL | fn main(... : ...) + | ^^^ not a valid pattern + | +help: for a rest pattern, use `..` instead of `...` + | +LL - fn main(... : ...) +LL + fn main(.. : ...) + | + +error: unexpected `...` + --> $DIR/recover-invalid-function-parameter-pattern.rs:3:15 + | +LL | fn main(... : ...) + | ^^^ + | + = note: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: expected one of `->`, `where`, or `{`, found `` + --> $DIR/recover-invalid-function-parameter-pattern.rs:3:18 + | +LL | fn main(... : ...) + | ^ expected one of `->`, `where`, or `{` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.current.stderr b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.current.stderr new file mode 100644 index 0000000000000..2c9694cdd419a --- /dev/null +++ b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.current.stderr @@ -0,0 +1,15 @@ +error[E0275]: overflow evaluating the requirement `for<'b> T: Proj<'b>` + --> $DIR/find-param-recursion-issue-152716.rs:15:1 + | +LL | / fn foo() +LL | | +LL | | where +LL | | T: for<'a> Proj<'a, Assoc = for<'b> fn(>::Assoc)>, +LL | | (): Trait<>::Assoc> + | |__________________________________________^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`find_param_recursion_issue_152716`) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.next.stderr b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.next.stderr new file mode 100644 index 0000000000000..c722813ddd663 --- /dev/null +++ b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.next.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `(): Trait<>::Assoc>` + --> $DIR/find-param-recursion-issue-152716.rs:19:9 + | +LL | (): Trait<>::Assoc> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs index 4d088073c3ba6..fb1ac0d8d0298 100644 --- a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs +++ b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs @@ -1,4 +1,6 @@ -//@ compile-flags: -Znext-solver +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver // Regression test for . // @@ -11,10 +13,11 @@ trait Proj<'a> { type Assoc; } fn foo() +//[current]~^ ERROR: overflow evaluating the requirement `for<'b> T: Proj<'b>` where T: for<'a> Proj<'a, Assoc = for<'b> fn(>::Assoc)>, (): Trait<>::Assoc> - //~^ ERROR: the trait bound `(): Trait fn(>::Assoc))>` is not satisfied + //[next]~^ ERROR: overflow evaluating the requirement `(): Trait<>::Assoc>` { } diff --git a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr deleted file mode 100644 index 1408890184a90..0000000000000 --- a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0277]: the trait bound `(): Trait fn(>::Assoc))>` is not satisfied - --> $DIR/find-param-recursion-issue-152716.rs:16:9 - | -LL | (): Trait<>::Assoc> - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait fn(>::Assoc))>` is not implemented for `()` - | -help: consider extending the `where` clause, but there might be an alternative better way to express this requirement - | -LL | (): Trait<>::Assoc>, (): Trait fn(>::Assoc))> - | +++++++++++++++++++++++++++++++++++++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.current.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.current.stderr new file mode 100644 index 0000000000000..230871107a6cf --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.current.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Assoc1 == _` + --> $DIR/recursive-self-normalization-2.rs:16:1 + | +LL | fn test::Assoc2> + Foo2::Assoc1>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.next.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.next.stderr new file mode 100644 index 0000000000000..ea8b5cd51a309 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.next.stderr @@ -0,0 +1,15 @@ +error[E0275]: overflow evaluating the requirement `::Assoc1 == _` + --> $DIR/recursive-self-normalization-2.rs:16:1 + | +LL | fn test::Assoc2> + Foo2::Assoc1>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `::Assoc2 == _` + --> $DIR/recursive-self-normalization-2.rs:16:1 + | +LL | fn test::Assoc2> + Foo2::Assoc1>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs index 8dc27c0da605a..0e08a6b4d7e03 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs @@ -1,4 +1,6 @@ -//@ compile-flags: -Znext-solver +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver trait Foo1 { type Assoc1; @@ -12,8 +14,9 @@ trait Bar {} fn needs_bar() {} fn test::Assoc2> + Foo2::Assoc1>>() { + //~^ ERROR overflow evaluating the requirement `::Assoc1 == _` + //[next]~| ERROR overflow evaluating the requirement `::Assoc2 == _` needs_bar::(); - //~^ ERROR: the trait bound `::Assoc1: Bar` is not satisfied } fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr deleted file mode 100644 index 6f5111a6193ca..0000000000000 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0277]: the trait bound `::Assoc1: Bar` is not satisfied - --> $DIR/recursive-self-normalization-2.rs:15:17 - | -LL | needs_bar::(); - | ^^^^^^^^^ the trait `Bar` is not implemented for `::Assoc1` - | -note: required by a bound in `needs_bar` - --> $DIR/recursive-self-normalization-2.rs:12:17 - | -LL | fn needs_bar() {} - | ^^^ required by this bound in `needs_bar` -help: consider further restricting the associated type - | -LL | fn test::Assoc2> + Foo2::Assoc1>>() where ::Assoc1: Bar { - | ++++++++++++++++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.current.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.current.stderr new file mode 100644 index 0000000000000..4b9be86b9e5a5 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.current.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Assoc == _` + --> $DIR/recursive-self-normalization-simple.rs:15:1 + | +LL | fn test::Assoc>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.next.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.next.stderr new file mode 100644 index 0000000000000..4b9be86b9e5a5 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.next.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Assoc == _` + --> $DIR/recursive-self-normalization-simple.rs:15:1 + | +LL | fn test::Assoc>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.rs new file mode 100644 index 0000000000000..b511dc4a732e3 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-simple.rs @@ -0,0 +1,19 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// A variant of `recursive-self-normalization.rs` which passes if +// we treat inductive cycles as `NoSolution` in the trait solver. + +trait Foo { + type Assoc; +} + +trait Bar {} +fn needs_bar() {} + +fn test::Assoc>>() { + //~^ ERROR overflow evaluating the requirement `::Assoc == _` +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.current.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.current.stderr new file mode 100644 index 0000000000000..6569be7347911 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.current.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Assoc == _` + --> $DIR/recursive-self-normalization.rs:12:1 + | +LL | fn test::Assoc>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.next.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.next.stderr new file mode 100644 index 0000000000000..6569be7347911 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.next.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Assoc == _` + --> $DIR/recursive-self-normalization.rs:12:1 + | +LL | fn test::Assoc>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs index f441ac499f99c..a25d028bd1b52 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs @@ -1,4 +1,6 @@ -//@ compile-flags: -Znext-solver +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver trait Foo { type Assoc; @@ -8,8 +10,8 @@ trait Bar {} fn needs_bar() {} fn test::Assoc>>() { + //~^ ERROR overflow evaluating the requirement `::Assoc == _` needs_bar::(); - //~^ ERROR the trait bound `::Assoc: Bar` is not satisfied } fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr deleted file mode 100644 index c551823468741..0000000000000 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0277]: the trait bound `::Assoc: Bar` is not satisfied - --> $DIR/recursive-self-normalization.rs:11:17 - | -LL | needs_bar::(); - | ^^^^^^^^ the trait `Bar` is not implemented for `::Assoc` - | -note: required by a bound in `needs_bar` - --> $DIR/recursive-self-normalization.rs:8:17 - | -LL | fn needs_bar() {} - | ^^^ required by this bound in `needs_bar` -help: consider further restricting the associated type - | -LL | fn test::Assoc>>() where ::Assoc: Bar { - | ++++++++++++++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`.