diff options
648 files changed, 9396 insertions, 5747 deletions
diff --git a/.gitattributes b/.gitattributes index d29c15fe712..a02c95fbd48 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,8 +4,10 @@ *.cpp rust *.h rust *.rs rust diff=rust -*.fixed linguist-language=Rust -*.mir linguist-language=Rust +*.fixed linguist-language=Rust -merge +*.mir linguist-language=Rust -merge +*.stderr -merge +*.stdout -merge src/etc/installer/gfx/* binary src/vendor/** -text Cargo.lock linguist-generated=false diff --git a/.gitmodules b/.gitmodules index 33ea0f53cf1..07fd44c2b2d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -33,7 +33,7 @@ [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git - branch = rustc/19.1-2024-09-17 + branch = rustc/19.1-2024-12-03 shallow = true [submodule "src/doc/embedded-book"] path = src/doc/embedded-book diff --git a/Cargo.lock b/Cargo.lock index 8ccf05cc5b8..f59dcdcf28d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1878,16 +1878,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] -name = "jemalloc-sys" -version = "0.5.4+5.3.0-patched" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" -dependencies = [ - "cc", - "libc", -] - -[[package]] name = "jobserver" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2287,7 +2277,6 @@ dependencies = [ "ctrlc", "directories", "getrandom", - "jemalloc-sys", "libc", "libffi", "libloading", @@ -2297,6 +2286,7 @@ dependencies = [ "rustc_version", "smallvec", "tempfile", + "tikv-jemalloc-sys", "ui_test", "windows-sys 0.52.0", ] @@ -3151,12 +3141,12 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" name = "rustc-main" version = "0.0.0" dependencies = [ - "jemalloc-sys", "rustc_codegen_ssa", "rustc_driver", "rustc_driver_impl", "rustc_smir", "stable_mir", + "tikv-jemalloc-sys", ] [[package]] @@ -5261,6 +5251,16 @@ name = "tier-check" version = "0.1.0" [[package]] +name = "tikv-jemalloc-sys" +version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" +dependencies = [ + "cc", + "libc", +] + +[[package]] name = "time" version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5803,17 +5803,20 @@ checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-component-ld" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4aa6bd7fbe7cffbed29fe3e236fda74419def1bdef6f80f989ec51137edf44" +checksum = "a2b05c3820968b335f10e703218459e4fd2cc91fdfc8f7936a993f1aacaa0938" dependencies = [ "anyhow", "clap", "lexopt", + "libc", "tempfile", "wasi-preview1-component-adapter-provider", "wasmparser 0.219.1", "wat", + "windows-sys 0.59.0", + "winsplit", "wit-component", "wit-parser", ] @@ -6186,6 +6189,12 @@ dependencies = [ ] [[package]] +name = "winsplit" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab703352da6a72f35c39a533526393725640575bb211f61987a2748323ad956" + +[[package]] name = "wit-component" version = "0.219.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index f85c30ac7ec..d24b630516a 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -20,14 +20,14 @@ rustc_smir = { path = "../rustc_smir" } stable_mir = { path = "../stable_mir" } # tidy-alphabetical-end -[dependencies.jemalloc-sys] -version = "0.5.0" +[dependencies.tikv-jemalloc-sys] +version = "0.6.0" optional = true features = ['unprefixed_malloc_on_supported_platforms'] [features] # tidy-alphabetical-start -jemalloc = ['dep:jemalloc-sys'] +jemalloc = ['dep:tikv-jemalloc-sys'] llvm = ['rustc_driver_impl/llvm'] max_level_info = ['rustc_driver_impl/max_level_info'] rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts'] diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index ccf88d8ff4b..a55a63a7bf1 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -43,6 +43,8 @@ fn main() { { use std::os::raw::{c_int, c_void}; + use tikv_jemalloc_sys as jemalloc_sys; + #[used] static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; #[used] diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 2e51753ede6..15a27c0b6ee 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1215,6 +1215,15 @@ impl Scalar { Scalar::Union { .. } => true, } } + + /// Returns `true` if this is a signed integer scalar + #[inline] + pub fn is_signed(&self) -> bool { + match self.primitive() { + Primitive::Int(_, signed) => signed, + _ => false, + } + } } // NOTE: This struct is generic over the FieldIdx for rust-analyzer usage. @@ -1401,10 +1410,7 @@ impl BackendRepr { #[inline] pub fn is_signed(&self) -> bool { match self { - BackendRepr::Scalar(scal) => match scal.primitive() { - Primitive::Int(_, signed) => signed, - _ => false, - }, + BackendRepr::Scalar(scal) => scal.is_signed(), _ => panic!("`is_signed` on non-scalar ABI {self:?}"), } } @@ -1499,7 +1505,11 @@ impl BackendRepr { #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> { /// Single enum variants, structs/tuples, unions, and all non-ADTs. - Single { index: VariantIdx }, + Single { + /// Always 0 for non-enums/generators. + /// For enums without a variant, this is an invalid index! + index: VariantIdx, + }, /// Enum-likes with more than one variant: each variant comes with /// a *discriminant* (usually the same as the variant index but the user can @@ -1528,14 +1538,22 @@ pub enum TagEncoding<VariantIdx: Idx> { /// The variant `untagged_variant` contains a niche at an arbitrary /// offset (field `tag_field` of the enum), which for a variant with /// discriminant `d` is set to - /// `(d - niche_variants.start).wrapping_add(niche_start)`. + /// `(d - niche_variants.start).wrapping_add(niche_start)` + /// (this is wrapping arithmetic using the type of the niche field). /// /// For example, `Option<(usize, &T)>` is represented such that /// `None` has a null pointer for the second tuple field, and /// `Some` is the identity function (with a non-null reference). + /// + /// Other variants that are not `untagged_variant` and that are outside the `niche_variants` + /// range cannot be represented; they must be uninhabited. Niche { untagged_variant: VariantIdx, + /// This range *may* contain `untagged_variant`; that is then just a "dead value" and + /// not used to encode anything. niche_variants: RangeInclusive<VariantIdx>, + /// This is inbounds of the type of the niche field + /// (not sign-extended, i.e., all bits beyond the niche field size are 0). niche_start: u128, }, } diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 56b20e0ad89..2f55a9eaeda 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -39,9 +39,7 @@ pub use crate::format::*; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter}; use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream}; -use crate::util::parser::{ - AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_RANGE, PREC_UNAMBIGUOUS, -}; +use crate::util::parser::{AssocOp, ExprPrecedence}; /// A "Label" is an identifier of some point in sources, /// e.g. in the following code: @@ -1317,29 +1315,29 @@ impl Expr { Some(P(Ty { kind, id: self.id, span: self.span, tokens: None })) } - pub fn precedence(&self) -> i8 { + pub fn precedence(&self) -> ExprPrecedence { match self.kind { - ExprKind::Closure(..) => PREC_CLOSURE, + ExprKind::Closure(..) => ExprPrecedence::Closure, ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::Yield(..) | ExprKind::Yeet(..) - | ExprKind::Become(..) => PREC_JUMP, + | ExprKind::Become(..) => ExprPrecedence::Jump, // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence // ensures that `pprust` will add parentheses in the right places to get the desired // parse. - ExprKind::Range(..) => PREC_RANGE, + ExprKind::Range(..) => ExprPrecedence::Range, // Binop-like expr kinds, handled by `AssocOp`. - ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8, - ExprKind::Cast(..) => AssocOp::As.precedence() as i8, + ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence(), + ExprKind::Cast(..) => ExprPrecedence::Cast, ExprKind::Assign(..) | - ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8, + ExprKind::AssignOp(..) => ExprPrecedence::Assign, // Unary, prefix ExprKind::AddrOf(..) @@ -1348,7 +1346,7 @@ impl Expr { // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b` // but we need to print `(let _ = a) < b` as-is with parens. | ExprKind::Let(..) - | ExprKind::Unary(..) => PREC_PREFIX, + | ExprKind::Unary(..) => ExprPrecedence::Prefix, // Never need parens ExprKind::Array(_) @@ -1381,7 +1379,7 @@ impl Expr { | ExprKind::Underscore | ExprKind::While(..) | ExprKind::Err(_) - | ExprKind::Dummy => PREC_UNAMBIGUOUS, + | ExprKind::Dummy => ExprPrecedence::Unambiguous, } } @@ -1733,12 +1731,12 @@ pub enum AttrArgs { /// Delimited arguments: `#[attr()/[]/{}]`. Delimited(DelimArgs), /// Arguments of a key-value attribute: `#[attr = "value"]`. - Eq( + Eq { /// Span of the `=` token. - Span, - /// The "value". - AttrArgsEq, - ), + eq_span: Span, + + value: AttrArgsEq, + }, } // The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro @@ -1750,15 +1748,39 @@ pub enum AttrArgsEq { Hir(MetaItemLit), } +impl AttrArgsEq { + pub fn span(&self) -> Span { + match self { + AttrArgsEq::Ast(p) => p.span, + AttrArgsEq::Hir(lit) => lit.span, + } + } + + pub fn unwrap_ast(&self) -> &Expr { + match self { + AttrArgsEq::Ast(p) => p, + AttrArgsEq::Hir(lit) => { + unreachable!("in literal form when getting inner tokens: {lit:?}") + } + } + } + + pub fn unwrap_ast_mut(&mut self) -> &mut P<Expr> { + match self { + AttrArgsEq::Ast(p) => p, + AttrArgsEq::Hir(lit) => { + unreachable!("in literal form when getting inner tokens: {lit:?}") + } + } + } +} + impl AttrArgs { pub fn span(&self) -> Option<Span> { match self { AttrArgs::Empty => None, AttrArgs::Delimited(args) => Some(args.dspan.entire()), - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)), - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when getting span: {:?}", lit); - } + AttrArgs::Eq { eq_span, value } => Some(eq_span.to(value.span())), } } @@ -1768,10 +1790,7 @@ impl AttrArgs { match self { AttrArgs::Empty => TokenStream::default(), AttrArgs::Delimited(args) => args.tokens.clone(), - AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => TokenStream::from_ast(expr), - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when getting inner tokens: {:?}", lit) - } + AttrArgs::Eq { value, .. } => TokenStream::from_ast(value.unwrap_ast()), } } } @@ -1785,10 +1804,10 @@ where match self { AttrArgs::Empty => {} AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher), - AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => { + AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => { unreachable!("hash_stable {:?}", expr); } - AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) => { + AttrArgs::Eq { eq_span, value: AttrArgsEq::Hir(lit) } => { eq_span.hash_stable(ctx, hasher); lit.hash_stable(ctx, hasher); } @@ -2547,6 +2566,18 @@ pub enum SelfKind { Explicit(P<Ty>, Mutability), } +impl SelfKind { + pub fn to_ref_suggestion(&self) -> String { + match self { + SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(), + SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()), + SelfKind::Value(_) | SelfKind::Explicit(_, _) => { + unreachable!("if we had an explicit self, we wouldn't be here") + } + } + } +} + pub type ExplicitSelf = Spanned<SelfKind>; impl Param { diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 888b13efa31..0d79cadef34 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -250,7 +250,7 @@ impl AttrItem { AttrArgs::Delimited(args) if args.delim == Delimiter::Parenthesis => { MetaItemKind::list_from_tokens(args.tokens.clone()) } - AttrArgs::Delimited(_) | AttrArgs::Eq(..) | AttrArgs::Empty => None, + AttrArgs::Delimited(_) | AttrArgs::Eq { .. } | AttrArgs::Empty => None, } } @@ -268,7 +268,7 @@ impl AttrItem { /// ``` fn value_str(&self) -> Option<Symbol> { match &self.args { - AttrArgs::Eq(_, args) => args.value_str(), + AttrArgs::Eq { value, .. } => value.value_str(), AttrArgs::Delimited(_) | AttrArgs::Empty => None, } } @@ -492,7 +492,7 @@ impl MetaItemKind { MetaItemKind::list_from_tokens(tokens.clone()).map(MetaItemKind::List) } AttrArgs::Delimited(..) => None, - AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind { + AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => match expr.kind { ExprKind::Lit(token_lit) => { // Turn failures to `None`, we'll get parse errors elsewhere. MetaItemLit::from_token_lit(token_lit, expr.span) @@ -501,7 +501,9 @@ impl MetaItemKind { } _ => None, }, - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())), + AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => { + Some(MetaItemKind::NameValue(lit.clone())) + } } } } @@ -702,7 +704,7 @@ pub fn mk_attr_name_value_str( tokens: None, }); let path = Path::from_ident(Ident::new(name, span)); - let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr)); + let args = AttrArgs::Eq { eq_span: span, value: AttrArgsEq::Ast(expr) }; mk_attr(g, style, unsafety, path, args, span) } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 0aceed45028..622c260868e 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -451,13 +451,10 @@ fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) { match args { AttrArgs::Empty => {} AttrArgs::Delimited(args) => visit_delim_args(vis, args), - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { - vis.visit_expr(expr); + AttrArgs::Eq { eq_span, value } => { + vis.visit_expr(value.unwrap_ast_mut()); vis.visit_span(eq_span); } - AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when visiting mac args eq: {:?}", lit) - } } } @@ -1628,9 +1625,10 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token visit_thin_exprs(vis, call_args); vis.visit_span(span); } - ExprKind::Binary(_binop, lhs, rhs) => { + ExprKind::Binary(binop, lhs, rhs) => { vis.visit_expr(lhs); vis.visit_expr(rhs); + vis.visit_span(&mut binop.span); } ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), ExprKind::Cast(expr, ty) => { @@ -1788,20 +1786,21 @@ pub fn noop_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Optio pub fn walk_flat_map_stmt<T: MutVisitor>( vis: &mut T, - Stmt { kind, mut span, mut id }: Stmt, + Stmt { kind, span, mut id }: Stmt, ) -> SmallVec<[Stmt; 1]> { vis.visit_id(&mut id); - let stmts: SmallVec<_> = walk_flat_map_stmt_kind(vis, kind) + let mut stmts: SmallVec<[Stmt; 1]> = walk_flat_map_stmt_kind(vis, kind) .into_iter() .map(|kind| Stmt { id, kind, span }) .collect(); - if stmts.len() > 1 { - panic!( + match stmts.len() { + 0 => {} + 1 => vis.visit_span(&mut stmts[0].span), + 2.. => panic!( "cloning statement `NodeId`s is prohibited by default, \ the visitor should implement custom statement visiting" - ); + ), } - vis.visit_span(&mut span); stmts } diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index ed9265d5159..e88bf27021a 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -128,21 +128,21 @@ impl AssocOp { } /// Gets the precedence of this operator - pub fn precedence(&self) -> usize { + pub fn precedence(&self) -> ExprPrecedence { use AssocOp::*; match *self { - As => 14, - Multiply | Divide | Modulus => 13, - Add | Subtract => 12, - ShiftLeft | ShiftRight => 11, - BitAnd => 10, - BitXor => 9, - BitOr => 8, - Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => 7, - LAnd => 6, - LOr => 5, - DotDot | DotDotEq => 4, - Assign | AssignOp(_) => 2, + As => ExprPrecedence::Cast, + Multiply | Divide | Modulus => ExprPrecedence::Product, + Add | Subtract => ExprPrecedence::Sum, + ShiftLeft | ShiftRight => ExprPrecedence::Shift, + BitAnd => ExprPrecedence::BitAnd, + BitXor => ExprPrecedence::BitXor, + BitOr => ExprPrecedence::BitOr, + Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => ExprPrecedence::Compare, + LAnd => ExprPrecedence::LAnd, + LOr => ExprPrecedence::LOr, + DotDot | DotDotEq => ExprPrecedence::Range, + Assign | AssignOp(_) => ExprPrecedence::Assign, } } @@ -229,17 +229,44 @@ impl AssocOp { } } -pub const PREC_CLOSURE: i8 = -40; -pub const PREC_JUMP: i8 = -30; -pub const PREC_RANGE: i8 = -10; -// The range 2..=14 is reserved for AssocOp binary operator precedences. -pub const PREC_PREFIX: i8 = 50; -pub const PREC_UNAMBIGUOUS: i8 = 60; -pub const PREC_FORCE_PAREN: i8 = 100; +#[derive(Clone, Copy, PartialEq, PartialOrd)] +pub enum ExprPrecedence { + Closure, + // return, break, yield + Jump, + // = += -= *= /= %= &= |= ^= <<= >>= + Assign, + // .. ..= + Range, + // || + LOr, + // && + LAnd, + // == != < > <= >= + Compare, + // | + BitOr, + // ^ + BitXor, + // & + BitAnd, + // << >> + Shift, + // + - + Sum, + // * / % + Product, + // as + Cast, + // unary - * ! & &mut + Prefix, + // paths, loops, function calls, array indexing, field expressions, method calls + Unambiguous, +} /// In `let p = e`, operators with precedence `<=` this one requires parentheses in `e`. -pub fn prec_let_scrutinee_needs_par() -> usize { - AssocOp::LAnd.precedence() +pub fn prec_let_scrutinee_needs_par() -> ExprPrecedence { + ExprPrecedence::LAnd } /// Suppose we have `let _ = e` and the `order` of `e`. @@ -247,8 +274,8 @@ pub fn prec_let_scrutinee_needs_par() -> usize { /// /// Conversely, suppose that we have `(let _ = a) OP b` and `order` is that of `OP`. /// Can we print this as `let _ = a OP b`? -pub fn needs_par_as_let_scrutinee(order: i8) -> bool { - order <= prec_let_scrutinee_needs_par() as i8 +pub fn needs_par_as_let_scrutinee(order: ExprPrecedence) -> bool { + order <= prec_let_scrutinee_needs_par() } /// Expressions that syntactically contain an "exterior" struct literal i.e., not surrounded by any diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 718397e8ca0..2f6998783fa 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1273,10 +1273,7 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) - match args { AttrArgs::Empty => {} AttrArgs::Delimited(_args) => {} - AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => try_visit!(visitor.visit_expr(expr)), - AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when walking mac args eq: {:?}", lit) - } + AttrArgs::Eq { value, .. } => try_visit!(visitor.visit_expr(value.unwrap_ast())), } V::Result::output() } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 7ffe4db6e45..bac3f974cca 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -889,7 +889,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // This is an inert key-value attribute - it will never be visible to macros // after it gets lowered to HIR. Therefore, we can extract literals to handle // nonterminals in `#[doc]` (e.g. `#[doc = $e]`). - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { + &AttrArgs::Eq { eq_span, ref value } => { + let expr = value.unwrap_ast(); // In valid code the value always ends up as a single literal. Otherwise, a dummy // literal suffices because the error is handled elsewhere. let lit = if let ExprKind::Lit(token_lit) = expr.kind @@ -905,10 +906,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: DUMMY_SP, } }; - AttrArgs::Eq(*eq_span, AttrArgsEq::Hir(lit)) - } - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when lowering mac args eq: {:?}", lit) + AttrArgs::Eq { eq_span, value: AttrArgsEq::Hir(lit) } } } } @@ -2013,7 +2011,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ExprKind::Underscore => { if self.tcx.features().generic_arg_infer() { let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span)); - self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind }) + self.arena + .alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind }) } else { feature_err( &self.tcx.sess, diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index d81fd53938b..5a0ec865f9d 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -207,8 +207,6 @@ ast_passes_precise_capturing_duplicated = duplicate `use<...>` precise capturing ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc} -ast_passes_show_span = {$msg} - ast_passes_stability_outside_std = stability attributes may not be used outside of the standard library ast_passes_static_without_body = diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index f65056a494b..9b600e3ee92 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -780,14 +780,6 @@ pub(crate) struct IncompatibleFeatures { } #[derive(Diagnostic)] -#[diag(ast_passes_show_span)] -pub(crate) struct ShowSpan { - #[primary_span] - pub span: Span, - pub msg: &'static str, -} - -#[derive(Diagnostic)] #[diag(ast_passes_negative_bound_not_supported)] pub(crate) struct NegativeBoundUnsupported { #[primary_span] diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 8cdc7133cc0..89311516081 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -4,9 +4,9 @@ use rustc_ast::{NodeId, PatKind, attr, token}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features, GateIssue}; use rustc_session::Session; use rustc_session::parse::{feature_err, feature_err_issue, feature_warn}; +use rustc_span::Span; use rustc_span::source_map::Spanned; -use rustc_span::symbol::sym; -use rustc_span::{Span, Symbol}; +use rustc_span::symbol::{Symbol, sym}; use rustc_target::spec::abi; use thin_vec::ThinVec; @@ -516,6 +516,11 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { "async closures are unstable", "to use an async block, remove the `||`: `async {`" ); + gate_all!( + async_trait_bounds, + "`async` trait bounds are unstable", + "use the desugared name of the async trait, such as `AsyncFn`" + ); gate_all!(async_for_loop, "`for await` loops are experimental"); gate_all!( closure_lifetime_binder, @@ -690,6 +695,7 @@ fn check_new_solver_banned_features(sess: &Session, features: &Features) { .find(|feat| feat.gate_name == sym::generic_const_exprs) .map(|feat| feat.attr_sp) { + #[cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))] sess.dcx().emit_err(errors::IncompatibleFeatures { spans: vec![gce_span], f1: Symbol::intern("-Znext-solver=globally"), diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 86752da79ae..b4ed70d83e5 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -1,8 +1,6 @@ //! The `rustc_ast_passes` crate contains passes which validate the AST in `syntax` //! parsed by `rustc_parse` and then lowered, after the passes in this crate, //! by `rustc_ast_lowering`. -//! -//! The crate also contains other misc AST visitors, e.g. `node_count` and `show_span`. // tidy-alphabetical-start #![allow(internal_features)] @@ -18,6 +16,5 @@ pub mod ast_validation; mod errors; pub mod feature_gate; -pub mod show_span; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_ast_passes/src/show_span.rs b/compiler/rustc_ast_passes/src/show_span.rs deleted file mode 100644 index e7ba2e7fc30..00000000000 --- a/compiler/rustc_ast_passes/src/show_span.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! Span debugger -//! -//! This module shows spans for all expressions in the crate -//! to help with compiler debugging. - -use std::str::FromStr; - -use rustc_ast as ast; -use rustc_ast::visit; -use rustc_ast::visit::Visitor; -use rustc_errors::DiagCtxtHandle; - -use crate::errors; - -enum Mode { - Expression, - Pattern, - Type, -} - -impl FromStr for Mode { - type Err = (); - fn from_str(s: &str) -> Result<Mode, ()> { - let mode = match s { - "expr" => Mode::Expression, - "pat" => Mode::Pattern, - "ty" => Mode::Type, - _ => return Err(()), - }; - Ok(mode) - } -} - -struct ShowSpanVisitor<'a> { - dcx: DiagCtxtHandle<'a>, - mode: Mode, -} - -impl<'a> Visitor<'a> for ShowSpanVisitor<'a> { - fn visit_expr(&mut self, e: &'a ast::Expr) { - if let Mode::Expression = self.mode { - self.dcx.emit_warn(errors::ShowSpan { span: e.span, msg: "expression" }); - } - visit::walk_expr(self, e); - } - - fn visit_pat(&mut self, p: &'a ast::Pat) { - if let Mode::Pattern = self.mode { - self.dcx.emit_warn(errors::ShowSpan { span: p.span, msg: "pattern" }); - } - visit::walk_pat(self, p); - } - - fn visit_ty(&mut self, t: &'a ast::Ty) { - if let Mode::Type = self.mode { - self.dcx.emit_warn(errors::ShowSpan { span: t.span, msg: "type" }); - } - visit::walk_ty(self, t); - } -} - -pub fn run(dcx: DiagCtxtHandle<'_>, mode: &str, krate: &ast::Crate) { - let Ok(mode) = mode.parse() else { - return; - }; - let mut v = ShowSpanVisitor { dcx, mode }; - visit::walk_crate(&mut v, krate); -} diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index d7c531f3760..479677b0a5a 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -648,14 +648,14 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere AttrArgs::Empty => { self.print_path(&item.path, false, 0); } - AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => { + AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); let token_str = self.expr_to_string(expr); self.word(token_str); } - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { + AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index e9c49e9f682..c239cb249c3 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -5,7 +5,7 @@ use itertools::{Itertools, Position}; use rustc_ast::ptr::P; use rustc_ast::util::classify; use rustc_ast::util::literal::escape_byte_str_symbol; -use rustc_ast::util::parser::{self, AssocOp, Fixity}; +use rustc_ast::util::parser::{self, AssocOp, ExprPrecedence, Fixity}; use rustc_ast::{ self as ast, BlockCheckMode, FormatAlignment, FormatArgPosition, FormatArgsPiece, FormatCount, FormatDebugHex, FormatSign, FormatTrait, token, @@ -212,9 +212,9 @@ impl<'a> State<'a> { } fn print_expr_call(&mut self, func: &ast::Expr, args: &[P<ast::Expr>], fixup: FixupContext) { - let prec = match func.kind { - ast::ExprKind::Field(..) => parser::PREC_FORCE_PAREN, - _ => parser::PREC_UNAMBIGUOUS, + let needs_paren = match func.kind { + ast::ExprKind::Field(..) => true, + _ => func.precedence() < ExprPrecedence::Unambiguous, }; // Independent of parenthesization related to precedence, we must @@ -233,7 +233,7 @@ impl<'a> State<'a> { // because the latter is valid syntax but with the incorrect meaning. // It's a match-expression followed by tuple-expression, not a function // call. - self.print_expr_cond_paren(func, func.precedence() < prec, fixup.leftmost_subexpression()); + self.print_expr_cond_paren(func, needs_paren, fixup.leftmost_subexpression()); self.print_call_post(args) } @@ -256,7 +256,7 @@ impl<'a> State<'a> { // a statement containing an expression. self.print_expr_cond_paren( receiver, - receiver.precedence() < parser::PREC_UNAMBIGUOUS, + receiver.precedence() < ExprPrecedence::Unambiguous, fixup, ); @@ -276,21 +276,22 @@ impl<'a> State<'a> { fixup: FixupContext, ) { let assoc_op = AssocOp::from_ast_binop(op.node); - let prec = assoc_op.precedence() as i8; - let fixity = assoc_op.fixity(); - - let (left_prec, right_prec) = match fixity { - Fixity::Left => (prec, prec + 1), - Fixity::Right => (prec + 1, prec), - Fixity::None => (prec + 1, prec + 1), + let binop_prec = assoc_op.precedence(); + let left_prec = lhs.precedence(); + let right_prec = rhs.precedence(); + + let (mut left_needs_paren, right_needs_paren) = match assoc_op.fixity() { + Fixity::Left => (left_prec < binop_prec, right_prec <= binop_prec), + Fixity::Right => (left_prec <= binop_prec, right_prec < binop_prec), + Fixity::None => (left_prec <= binop_prec, right_prec <= binop_prec), }; - let left_prec = match (&lhs.kind, op.node) { + match (&lhs.kind, op.node) { // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead // of `(x as i32) < ...`. We need to convince it _not_ to do that. (&ast::ExprKind::Cast { .. }, ast::BinOpKind::Lt | ast::BinOpKind::Shl) => { - parser::PREC_FORCE_PAREN + left_needs_paren = true; } // We are given `(let _ = a) OP b`. // @@ -300,33 +301,23 @@ impl<'a> State<'a> { // - Otherwise, e.g. when we have `(let a = b) < c` in AST, // parens are required since the parser would interpret `let a = b < c` as // `let a = (b < c)`. To achieve this, we force parens. - (&ast::ExprKind::Let { .. }, _) if !parser::needs_par_as_let_scrutinee(prec) => { - parser::PREC_FORCE_PAREN + (&ast::ExprKind::Let { .. }, _) if !parser::needs_par_as_let_scrutinee(binop_prec) => { + left_needs_paren = true; } - _ => left_prec, - }; - - self.print_expr_cond_paren( - lhs, - lhs.precedence() < left_prec, - fixup.leftmost_subexpression(), - ); + _ => {} + } + self.print_expr_cond_paren(lhs, left_needs_paren, fixup.leftmost_subexpression()); self.space(); self.word_space(op.node.as_str()); - - self.print_expr_cond_paren( - rhs, - rhs.precedence() < right_prec, - fixup.subsequent_subexpression(), - ); + self.print_expr_cond_paren(rhs, right_needs_paren, fixup.subsequent_subexpression()); } fn print_expr_unary(&mut self, op: ast::UnOp, expr: &ast::Expr, fixup: FixupContext) { self.word(op.as_str()); self.print_expr_cond_paren( expr, - expr.precedence() < parser::PREC_PREFIX, + expr.precedence() < ExprPrecedence::Prefix, fixup.subsequent_subexpression(), ); } @@ -348,7 +339,7 @@ impl<'a> State<'a> { } self.print_expr_cond_paren( expr, - expr.precedence() < parser::PREC_PREFIX, + expr.precedence() < ExprPrecedence::Prefix, fixup.subsequent_subexpression(), ); } @@ -432,10 +423,9 @@ impl<'a> State<'a> { self.print_token_literal(lit, expr.span) } ast::ExprKind::Cast(expr, ty) => { - let prec = AssocOp::As.precedence() as i8; self.print_expr_cond_paren( expr, - expr.precedence() < prec, + expr.precedence() < ExprPrecedence::Cast, fixup.leftmost_subexpression(), ); self.space(); @@ -512,7 +502,7 @@ impl<'a> State<'a> { MatchKind::Postfix => { self.print_expr_cond_paren( expr, - expr.precedence() < parser::PREC_UNAMBIGUOUS, + expr.precedence() < ExprPrecedence::Unambiguous, fixup, ); self.word_nbsp(".match"); @@ -576,31 +566,31 @@ impl<'a> State<'a> { ast::ExprKind::Await(expr, _) => { self.print_expr_cond_paren( expr, - expr.precedence() < parser::PREC_UNAMBIGUOUS, + expr.precedence() < ExprPrecedence::Unambiguous, fixup, ); self.word(".await"); } ast::ExprKind::Assign(lhs, rhs, _) => { - let prec = AssocOp::Assign.precedence() as i8; self.print_expr_cond_paren( lhs, - lhs.precedence() <= prec, + // Ranges are allowed on the right-hand side of assignment, + // but not the left. `(a..b) = c` needs parentheses. + lhs.precedence() <= ExprPrecedence::Range, fixup.leftmost_subexpression(), ); self.space(); self.word_space("="); self.print_expr_cond_paren( rhs, - rhs.precedence() < prec, + rhs.precedence() < ExprPrecedence::Assign, fixup.subsequent_subexpression(), ); } ast::ExprKind::AssignOp(op, lhs, rhs) => { - let prec = AssocOp::Assign.precedence() as i8; self.print_expr_cond_paren( lhs, - lhs.precedence() <= prec, + lhs.precedence() <= ExprPrecedence::Range, fixup.leftmost_subexpression(), ); self.space(); @@ -608,14 +598,14 @@ impl<'a> State<'a> { self.word_space("="); self.print_expr_cond_paren( rhs, - rhs.precedence() < prec, + rhs.precedence() < ExprPrecedence::Assign, fixup.subsequent_subexpression(), ); } ast::ExprKind::Field(expr, ident) => { self.print_expr_cond_paren( expr, - expr.precedence() < parser::PREC_UNAMBIGUOUS, + expr.precedence() < ExprPrecedence::Unambiguous, fixup, ); self.word("."); @@ -624,7 +614,7 @@ impl<'a> State<'a> { ast::ExprKind::Index(expr, index, _) => { self.print_expr_cond_paren( expr, - expr.precedence() < parser::PREC_UNAMBIGUOUS, + expr.precedence() < ExprPrecedence::Unambiguous, fixup.leftmost_subexpression(), ); self.word("["); @@ -636,7 +626,7 @@ impl<'a> State<'a> { // than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`. // Here we use a fake precedence value so that any child with lower precedence than // a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.) - let fake_prec = AssocOp::LOr.precedence() as i8; + let fake_prec = ExprPrecedence::LOr; if let Some(e) = start { self.print_expr_cond_paren( e, @@ -671,7 +661,7 @@ impl<'a> State<'a> { expr, // Parenthesize if required by precedence, or in the // case of `break 'inner: loop { break 'inner 1 } + 1` - expr.precedence() < parser::PREC_JUMP + expr.precedence() < ExprPrecedence::Jump || (opt_label.is_none() && classify::leading_labeled_expr(expr)), fixup.subsequent_subexpression(), ); @@ -690,7 +680,7 @@ impl<'a> State<'a> { self.word(" "); self.print_expr_cond_paren( expr, - expr.precedence() < parser::PREC_JUMP, + expr.precedence() < ExprPrecedence::Jump, fixup.subsequent_subexpression(), ); } @@ -703,7 +693,7 @@ impl<'a> State<'a> { self.word(" "); self.print_expr_cond_paren( expr, - expr.precedence() < parser::PREC_JUMP, + expr.precedence() < ExprPrecedence::Jump, fixup.subsequent_subexpression(), ); } @@ -713,7 +703,7 @@ impl<'a> State<'a> { self.word(" "); self.print_expr_cond_paren( result, - result.precedence() < parser::PREC_JUMP, + result.precedence() < ExprPrecedence::Jump, fixup.subsequent_subexpression(), ); } @@ -767,13 +757,13 @@ impl<'a> State<'a> { self.space(); self.print_expr_cond_paren( expr, - expr.precedence() < parser::PREC_JUMP, + expr.precedence() < ExprPrecedence::Jump, fixup.subsequent_subexpression(), ); } } ast::ExprKind::Try(e) => { - self.print_expr_cond_paren(e, e.precedence() < parser::PREC_UNAMBIGUOUS, fixup); + self.print_expr_cond_paren(e, e.precedence() < ExprPrecedence::Unambiguous, fixup); self.word("?") } ast::ExprKind::TryBlock(blk) => { diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 99af5500ac6..0eecf98a6ed 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -973,25 +973,20 @@ impl<'tcx> RegionInferenceContext<'tcx> { propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>, ) -> bool { let tcx = infcx.tcx; - - let TypeTest { generic_kind, lower_bound, span: _, verify_bound: _ } = type_test; + let TypeTest { generic_kind, lower_bound, span: blame_span, ref verify_bound } = *type_test; let generic_ty = generic_kind.to_ty(tcx); let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else { return false; }; - debug!("subject = {:?}", subject); - - let r_scc = self.constraint_sccs.scc(*lower_bound); - + let r_scc = self.constraint_sccs.scc(lower_bound); debug!( "lower_bound = {:?} r_scc={:?} universe={:?}", lower_bound, r_scc, self.constraint_sccs.annotation(r_scc).min_universe() ); - // If the type test requires that `T: 'a` where `'a` is a // placeholder from another universe, that effectively requires // `T: 'static`, so we have to propagate that requirement. @@ -1004,7 +999,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { propagated_outlives_requirements.push(ClosureOutlivesRequirement { subject, outlived_free_region: static_r, - blame_span: type_test.span, + blame_span, category: ConstraintCategory::Boring, }); @@ -1031,12 +1026,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { // where `ur` is a local bound -- we are sometimes in a // position to prove things that our caller cannot. See // #53570 for an example. - if self.eval_verify_bound(infcx, generic_ty, ur, &type_test.verify_bound) { + if self.eval_verify_bound(infcx, generic_ty, ur, &verify_bound) { continue; } let non_local_ub = self.universal_region_relations.non_local_upper_bounds(ur); - debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub); + debug!(?non_local_ub); // This is slightly too conservative. To show T: '1, given `'2: '1` // and `'3: '1` we only need to prove that T: '2 *or* T: '3, but to @@ -1049,10 +1044,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { let requirement = ClosureOutlivesRequirement { subject, outlived_free_region: upper_bound, - blame_span: type_test.span, + blame_span, category: ConstraintCategory::Boring, }; - debug!("try_promote_type_test: pushing {:#?}", requirement); + debug!(?requirement, "adding closure requirement"); propagated_outlives_requirements.push(requirement); } } @@ -1063,44 +1058,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// variables in the type `T` with an equal universal region from the /// closure signature. /// This is not always possible, so this is a fallible process. - #[instrument(level = "debug", skip(self, infcx))] + #[instrument(level = "debug", skip(self, infcx), ret)] fn try_promote_type_test_subject( &self, infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>, ) -> Option<ClosureOutlivesSubject<'tcx>> { let tcx = infcx.tcx; - - // Opaque types' args may include useless lifetimes. - // We will replace them with ReStatic. - struct OpaqueFolder<'tcx> { - tcx: TyCtxt<'tcx>, - } - impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for OpaqueFolder<'tcx> { - fn cx(&self) -> TyCtxt<'tcx> { - self.tcx - } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - use ty::TypeSuperFoldable as _; - let tcx = self.tcx; - let &ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = t.kind() else { - return t.super_fold_with(self); - }; - let args = std::iter::zip(args, tcx.variances_of(def_id)).map(|(arg, v)| { - match (arg.unpack(), v) { - (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => { - tcx.lifetimes.re_static.into() - } - _ => arg.fold_with(self), - } - }); - Ty::new_opaque(tcx, def_id, tcx.mk_args_from_iter(args)) - } - } - - let ty = ty.fold_with(&mut OpaqueFolder { tcx }); let mut failed = false; - let ty = fold_regions(tcx, ty, |r, _depth| { let r_vid = self.to_region_vid(r); let r_scc = self.constraint_sccs.scc(r_vid); diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 86a0111db49..bb64d646ff3 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -33,8 +33,8 @@ use rustc_middle::ty::{ TyCtxt, TypeVisitableExt, }; use rustc_middle::{bug, span_bug}; +use rustc_span::ErrorGuaranteed; use rustc_span::symbol::{kw, sym}; -use rustc_span::{ErrorGuaranteed, Symbol}; use tracing::{debug, instrument}; use crate::BorrowckInferCtxt; @@ -524,7 +524,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let reg_vid = self .infcx - .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("c-variadic"))) + .next_nll_region_var(FR, || RegionCtxt::Free(sym::c_dash_variadic)) .as_var(); let region = ty::Region::new_var(self.infcx.tcx, reg_vid); @@ -540,10 +540,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } } - let fr_fn_body = self - .infcx - .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("fn_body"))) - .as_var(); + let fr_fn_body = + self.infcx.next_nll_region_var(FR, || RegionCtxt::Free(sym::fn_body)).as_var(); let num_universals = self.infcx.num_region_vars(); diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 6ebc2fd870c..c05d44cb452 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -94,6 +94,21 @@ builtin_macros_cfg_accessible_indeterminate = cannot determine whether the path builtin_macros_cfg_accessible_literal_path = `cfg_accessible` path cannot be a literal builtin_macros_cfg_accessible_multiple_paths = multiple `cfg_accessible` paths are specified builtin_macros_cfg_accessible_unspecified_path = `cfg_accessible` path is not specified + +builtin_macros_coerce_pointee_requires_maybe_sized = `derive(CoercePointee)` requires `{$name}` to be marked `?Sized` + +builtin_macros_coerce_pointee_requires_one_field = `CoercePointee` can only be derived on `struct`s with at least one field + +builtin_macros_coerce_pointee_requires_one_generic = `CoercePointee` can only be derived on `struct`s that are generic over at least one type + +builtin_macros_coerce_pointee_requires_one_pointee = exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits + +builtin_macros_coerce_pointee_requires_transparent = `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]` + +builtin_macros_coerce_pointee_too_many_pointees = only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits + .label = here another type parameter is marked as `#[pointee]` + + builtin_macros_concat_bytes_array = cannot concatenate doubly nested array .note = byte strings are treated as arrays of bytes .help = try flattening the array diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 8adb9a3f4b0..3bd8f899a4a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -9,6 +9,7 @@ use rustc_ast::{ use rustc_attr as attr; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_macros::Diagnostic; use rustc_span::symbol::{Ident, sym}; use rustc_span::{Span, Symbol}; use thin_vec::{ThinVec, thin_vec}; @@ -38,12 +39,7 @@ pub(crate) fn expand_deriving_coerce_pointee( .any(|r| matches!(r, attr::ReprTransparent)) }); if !is_transparent { - cx.dcx() - .struct_span_err( - span, - "`CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`", - ) - .emit(); + cx.dcx().emit_err(RequireTransparent { span }); return; } if !matches!( @@ -51,22 +47,12 @@ pub(crate) fn expand_deriving_coerce_pointee( VariantData::Struct { fields, recovered: _ } | VariantData::Tuple(fields, _) if !fields.is_empty()) { - cx.dcx() - .struct_span_err( - span, - "`CoercePointee` can only be derived on `struct`s with at least one field", - ) - .emit(); + cx.dcx().emit_err(RequireOneField { span }); return; } (aitem.ident, g) } else { - cx.dcx() - .struct_span_err( - span, - "`CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`", - ) - .emit(); + cx.dcx().emit_err(RequireTransparent { span }); return; }; @@ -95,10 +81,7 @@ pub(crate) fn expand_deriving_coerce_pointee( let pointee_param_idx = if type_params.is_empty() { // `#[derive(CoercePointee)]` requires at least one generic type on the target `struct` - cx.dcx().struct_span_err( - span, - "`CoercePointee` can only be derived on `struct`s that are generic over at least one type", - ).emit(); + cx.dcx().emit_err(RequireOneGeneric { span }); return; } else if type_params.len() == 1 { // Regardless of the only type param being designed as `#[pointee]` or not, we can just use it as such @@ -111,19 +94,11 @@ pub(crate) fn expand_deriving_coerce_pointee( match (pointees.next(), pointees.next()) { (Some((idx, _span)), None) => idx, (None, _) => { - cx.dcx().struct_span_err( - span, - "exactly one generic type parameter must be marked as #[pointee] to derive CoercePointee traits", - ).emit(); + cx.dcx().emit_err(RequireOnePointee { span }); return; } (Some((_, one)), Some((_, another))) => { - cx.dcx() - .struct_span_err( - vec![one, another], - "only one type parameter can be marked as `#[pointee]` when deriving CoercePointee traits", - ) - .emit(); + cx.dcx().emit_err(TooManyPointees { one, another }); return; } } @@ -181,15 +156,10 @@ pub(crate) fn expand_deriving_coerce_pointee( pointee_ty_ident.name, ) { - cx.dcx() - .struct_span_err( - pointee_ty_ident.span, - format!( - "`derive(CoercePointee)` requires {} to be marked `?Sized`", - pointee_ty_ident.name - ), - ) - .emit(); + cx.dcx().emit_err(RequiresMaybeSized { + span: pointee_ty_ident.span, + name: pointee_ty_ident.name.to_ident_string(), + }); return; } let arg = GenericArg::Type(s_ty.clone()); @@ -459,3 +429,48 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for AlwaysErrorOnGenericParam<'a, 'b> } } } + +#[derive(Diagnostic)] +#[diag(builtin_macros_coerce_pointee_requires_transparent)] +struct RequireTransparent { + #[primary_span] + span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_coerce_pointee_requires_one_field)] +struct RequireOneField { + #[primary_span] + span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_coerce_pointee_requires_one_generic)] +struct RequireOneGeneric { + #[primary_span] + span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_coerce_pointee_requires_one_pointee)] +struct RequireOnePointee { + #[primary_span] + span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_coerce_pointee_too_many_pointees)] +struct TooManyPointees { + #[primary_span] + one: Span, + #[label] + another: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_coerce_pointee_requires_maybe_sized)] +struct RequiresMaybeSized { + #[primary_span] + span: Span, + name: String, +} diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index 0d62a13b472..ae9578eeffb 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -74,7 +74,7 @@ fn create_jit_module( jit_builder.symbol("__clif_jit_fn", clif_jit_fn as *const u8); let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false); - let cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, Symbol::intern("dummy_cgu_name")); + let cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, sym::dummy_cgu_name); crate::allocator::codegen(tcx, &mut jit_module); @@ -276,12 +276,7 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> jit_module.module.prepare_for_function_redefine(func_id).unwrap(); - let mut cx = crate::CodegenCx::new( - tcx, - jit_module.isa(), - false, - Symbol::intern("dummy_cgu_name"), - ); + let mut cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, sym::dummy_cgu_name); codegen_and_compile_fn(tcx, &mut cx, &mut Context::new(), jit_module, instance); assert!(cx.global_asm.is_empty()); diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index f787b8a6fd9..e0ebe30752a 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -415,7 +415,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }); } - sym::simd_fma => { + // FIXME: simd_relaxed_fma doesn't relax to non-fused multiply-add + sym::simd_fma | sym::simd_relaxed_fma => { intrinsic_args!(fx, args => (a, b, c); intrinsic); if !a.layout().ty.is_simd() { diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index e6f6ae30581..cac9975f04c 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -189,18 +189,13 @@ impl CodegenBackend for CraneliftCodegenBackend { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] if sess.target.arch == "x86_64" && sess.target.os != "none" { // x86_64 mandates SSE2 support - vec![Symbol::intern("fxsr"), sym::sse, Symbol::intern("sse2")] + vec![sym::fsxr, sym::sse, sym::sse2] } else if sess.target.arch == "aarch64" { match &*sess.target.os { "none" => vec![], // On macOS the aes, sha2 and sha3 features are enabled by default and ring // fails to compile on macOS when they are not present. - "macos" => vec![ - sym::neon, - Symbol::intern("aes"), - Symbol::intern("sha2"), - Symbol::intern("sha3"), - ], + "macos" => vec![sym::neon, sym::aes, sym::sha2, sym::sha3], // AArch64 mandates Neon support _ => vec![sym::neon], } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 604678a9af4..79d1a06dd46 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -772,6 +772,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( sym::simd_flog => "log", sym::simd_floor => "floor", sym::simd_fma => "fma", + sym::simd_relaxed_fma => "fma", // FIXME: this should relax to non-fused multiply-add when necessary sym::simd_fpowi => "__builtin_powi", sym::simd_fpow => "pow", sym::simd_fsin => "sin", diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 48beb9be2b2..f6d2ec24da6 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -148,7 +148,7 @@ fn prepare_lto( // __llvm_profile_counter_bias is pulled in at link time by an undefined reference to // __llvm_profile_runtime, therefore we won't know until link time if this symbol // should have default visibility. - symbols_below_threshold.push(CString::new("__llvm_profile_counter_bias").unwrap()); + symbols_below_threshold.push(c"__llvm_profile_counter_bias".to_owned()); Ok((symbols_below_threshold, upstream_modules)) } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 2744795d998..bde6668929c 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -509,7 +509,7 @@ fn get_pgo_sample_use_path(config: &ModuleConfig) -> Option<CString> { } fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> { - config.instrument_coverage.then(|| CString::new("default_%m_%p.profraw").unwrap()) + config.instrument_coverage.then(|| c"default_%m_%p.profraw".to_owned()) } pub(crate) unsafe fn llvm_optimize( diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index ef16e5bb459..dee67baaee9 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -203,6 +203,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( Stub::Struct, unique_type_id, &ptr_type_debuginfo_name, + None, cx.size_and_align_of(ptr_type), NO_SCOPE_METADATA, DIFlags::FlagZero, @@ -259,6 +260,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( layout.fields.offset(abi::WIDE_PTR_ADDR), DIFlags::FlagZero, data_ptr_type_di_node, + None, ), build_field_di_node( cx, @@ -268,6 +270,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( layout.fields.offset(abi::WIDE_PTR_EXTRA), DIFlags::FlagZero, type_di_node(cx, extra_field.ty), + None, ), ] }, @@ -369,6 +372,7 @@ fn build_dyn_type_di_node<'ll, 'tcx>( Stub::Struct, unique_type_id, &type_name, + None, cx.size_and_align_of(dyn_type), NO_SCOPE_METADATA, DIFlags::FlagZero, @@ -722,6 +726,14 @@ fn build_cpp_f16_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> DINodeCreation // `f16`'s value to be displayed using a Natvis visualiser in `intrinsic.natvis`. let float_ty = cx.tcx.types.f16; let bits_ty = cx.tcx.types.u16; + let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + match float_ty.kind() { + ty::Adt(def, _) => Some(file_metadata_from_def_id(cx, Some(def.did()))), + _ => None, + } + } else { + None + }; type_map::build_type_with_children( cx, type_map::stub( @@ -729,12 +741,21 @@ fn build_cpp_f16_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> DINodeCreation Stub::Struct, UniqueTypeId::for_ty(cx.tcx, float_ty), "f16", + def_location, cx.size_and_align_of(float_ty), NO_SCOPE_METADATA, DIFlags::FlagZero, ), // Fields: |cx, float_di_node| { + let def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + match bits_ty.kind() { + ty::Adt(def, _) => Some(def.did()), + _ => None, + } + } else { + None + }; smallvec![build_field_di_node( cx, float_di_node, @@ -743,6 +764,7 @@ fn build_cpp_f16_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> DINodeCreation Size::ZERO, DIFlags::FlagZero, type_di_node(cx, bits_ty), + def_id, )] }, NO_GENERICS, @@ -839,6 +861,7 @@ fn build_foreign_type_di_node<'ll, 'tcx>( Stub::Struct, unique_type_id, &compute_debuginfo_type_name(cx.tcx, t, false), + None, cx.size_and_align_of(t), Some(get_namespace_for_item(cx, def_id)), DIFlags::FlagZero, @@ -989,15 +1012,22 @@ fn build_field_di_node<'ll, 'tcx>( offset: Size, flags: DIFlags, type_di_node: &'ll DIType, + def_id: Option<DefId>, ) -> &'ll DIType { + let (file_metadata, line_number) = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers + { + file_metadata_from_def_id(cx, def_id) + } else { + (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) + }; unsafe { llvm::LLVMRustDIBuilderCreateMemberType( DIB(cx), owner, name.as_c_char_ptr(), name.len(), - unknown_file_metadata(cx), - UNKNOWN_LINE_NUMBER, + file_metadata, + line_number, size_and_align.0.bits(), size_and_align.1.bits() as u32, offset.bits(), @@ -1041,6 +1071,11 @@ fn build_struct_type_di_node<'ll, 'tcx>( let containing_scope = get_namespace_for_item(cx, adt_def.did()); let struct_type_and_layout = cx.layout_of(struct_type); let variant_def = adt_def.non_enum_variant(); + let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(file_metadata_from_def_id(cx, Some(adt_def.did()))) + } else { + None + }; type_map::build_type_with_children( cx, @@ -1049,6 +1084,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( Stub::Struct, unique_type_id, &compute_debuginfo_type_name(cx.tcx, struct_type, false), + def_location, size_and_align_of(struct_type_and_layout), Some(containing_scope), visibility_di_flags(cx, adt_def.did(), adt_def.did()), @@ -1068,6 +1104,11 @@ fn build_struct_type_di_node<'ll, 'tcx>( Cow::Borrowed(f.name.as_str()) }; let field_layout = struct_type_and_layout.field(cx, i); + let def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(f.did) + } else { + None + }; build_field_di_node( cx, owner, @@ -1076,6 +1117,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( struct_type_and_layout.fields.offset(i), visibility_di_flags(cx, f.did, adt_def.did()), type_di_node(cx, field_layout.ty), + def_id, ) }) .collect() @@ -1125,6 +1167,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>( layout.fields.offset(index), DIFlags::FlagZero, type_di_node(cx, up_var_ty), + None, ) }) .collect() @@ -1150,6 +1193,7 @@ fn build_tuple_type_di_node<'ll, 'tcx>( Stub::Struct, unique_type_id, &type_name, + None, size_and_align_of(tuple_type_and_layout), NO_SCOPE_METADATA, DIFlags::FlagZero, @@ -1168,6 +1212,7 @@ fn build_tuple_type_di_node<'ll, 'tcx>( tuple_type_and_layout.fields.offset(index), DIFlags::FlagZero, type_di_node(cx, component_type), + None, ) }) .collect() @@ -1189,6 +1234,12 @@ fn build_closure_env_di_node<'ll, 'tcx>( let containing_scope = get_namespace_for_item(cx, def_id); let type_name = compute_debuginfo_type_name(cx.tcx, closure_env_type, false); + let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(file_metadata_from_def_id(cx, Some(def_id))) + } else { + None + }; + type_map::build_type_with_children( cx, type_map::stub( @@ -1196,6 +1247,7 @@ fn build_closure_env_di_node<'ll, 'tcx>( Stub::Struct, unique_type_id, &type_name, + def_location, cx.size_and_align_of(closure_env_type), Some(containing_scope), DIFlags::FlagZero, @@ -1219,6 +1271,11 @@ fn build_union_type_di_node<'ll, 'tcx>( let containing_scope = get_namespace_for_item(cx, union_def_id); let union_ty_and_layout = cx.layout_of(union_type); let type_name = compute_debuginfo_type_name(cx.tcx, union_type, false); + let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(file_metadata_from_def_id(cx, Some(union_def_id))) + } else { + None + }; type_map::build_type_with_children( cx, @@ -1227,6 +1284,7 @@ fn build_union_type_di_node<'ll, 'tcx>( Stub::Union, unique_type_id, &type_name, + def_location, size_and_align_of(union_ty_and_layout), Some(containing_scope), DIFlags::FlagZero, @@ -1239,6 +1297,11 @@ fn build_union_type_di_node<'ll, 'tcx>( .enumerate() .map(|(i, f)| { let field_layout = union_ty_and_layout.field(cx, i); + let def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(f.did) + } else { + None + }; build_field_di_node( cx, owner, @@ -1247,6 +1310,7 @@ fn build_union_type_di_node<'ll, 'tcx>( Size::ZERO, DIFlags::FlagZero, type_di_node(cx, field_layout.ty), + def_id, ) }) .collect() @@ -1321,14 +1385,7 @@ pub(crate) fn build_global_var_di_node<'ll>( // We may want to remove the namespace scope if we're in an extern block (see // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952). let var_scope = get_namespace_for_item(cx, def_id); - let span = hygiene::walk_chain_collapsed(tcx.def_span(def_id), DUMMY_SP); - - let (file_metadata, line_number) = if !span.is_dummy() { - let loc = cx.lookup_debug_loc(span.lo()); - (file_metadata(cx, &loc.file), loc.line) - } else { - (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) - }; + let (file_metadata, line_number) = file_metadata_from_def_id(cx, Some(def_id)); let is_local_to_unit = is_node_local_to_unit(cx, def_id); @@ -1418,6 +1475,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>( Stub::VTableTy { vtable_holder }, unique_type_id, &vtable_type_name, + None, (size, pointer_align), NO_SCOPE_METADATA, DIFlags::FlagArtificial, @@ -1455,6 +1513,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>( field_offset, DIFlags::FlagZero, field_type_di_node, + None, )) }) .collect() @@ -1606,3 +1665,20 @@ fn tuple_field_name(field_index: usize) -> Cow<'static, str> { .map(|s| Cow::from(*s)) .unwrap_or_else(|| Cow::from(format!("__{field_index}"))) } + +pub(crate) type DefinitionLocation<'ll> = (&'ll DIFile, c_uint); + +pub(crate) fn file_metadata_from_def_id<'ll>( + cx: &CodegenCx<'ll, '_>, + def_id: Option<DefId>, +) -> DefinitionLocation<'ll> { + if let Some(def_id) = def_id + && let span = hygiene::walk_chain_collapsed(cx.tcx.def_span(def_id), DUMMY_SP) + && !span.is_dummy() + { + let loc = cx.lookup_debug_loc(span.lo()); + (file_metadata(cx, &loc.file), loc.line) + } else { + (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) + } +} diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 100b046cee2..d374767f187 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -4,7 +4,7 @@ use libc::c_uint; use rustc_abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants}; use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name; use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo}; -use rustc_codegen_ssa::traits::ConstCodegenMethods; +use rustc_codegen_ssa::traits::{ConstCodegenMethods, MiscCodegenMethods}; use rustc_index::IndexVec; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; @@ -16,8 +16,8 @@ use crate::debuginfo::metadata::enums::DiscrResult; use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId}; use crate::debuginfo::metadata::{ DINodeCreationResult, NO_GENERICS, NO_SCOPE_METADATA, SmallVec, UNKNOWN_LINE_NUMBER, - build_field_di_node, file_metadata, size_and_align_of, type_di_node, unknown_file_metadata, - visibility_di_flags, + build_field_di_node, file_metadata, file_metadata_from_def_id, size_and_align_of, type_di_node, + unknown_file_metadata, visibility_di_flags, }; use crate::debuginfo::utils::DIB; use crate::llvm::debuginfo::{DIFile, DIFlags, DIType}; @@ -192,6 +192,12 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( assert!(!wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout)); + let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(file_metadata_from_def_id(cx, Some(enum_adt_def.did()))) + } else { + None + }; + type_map::build_type_with_children( cx, type_map::stub( @@ -199,6 +205,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( type_map::Stub::Union, unique_type_id, &enum_type_name, + def_location, cx.size_and_align_of(enum_type), NO_SCOPE_METADATA, visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()), @@ -262,6 +269,14 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>( unique_type_id: UniqueTypeId<'tcx>, ) -> DINodeCreationResult<'ll> { let coroutine_type = unique_type_id.expect_ty(); + let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + let &ty::Coroutine(coroutine_def_id, _) = coroutine_type.kind() else { + bug!("build_coroutine_di_node() called with non-coroutine type: `{:?}`", coroutine_type) + }; + Some(file_metadata_from_def_id(cx, Some(coroutine_def_id))) + } else { + None + }; let coroutine_type_and_layout = cx.layout_of(coroutine_type); let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false); @@ -274,6 +289,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>( type_map::Stub::Union, unique_type_id, &coroutine_type_name, + def_location, size_and_align_of(coroutine_type_and_layout), NO_SCOPE_METADATA, DIFlags::FlagZero, @@ -321,6 +337,12 @@ fn build_single_variant_union_fields<'ll, 'tcx>( let tag_base_type_di_node = type_di_node(cx, tag_base_type); let tag_base_type_align = cx.align_of(tag_base_type); + let enum_adt_def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(enum_adt_def.did()) + } else { + None + }; + let variant_names_type_di_node = build_variant_names_type_di_node( cx, enum_type_di_node, @@ -328,6 +350,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( variant_index, Cow::from(enum_adt_def.variant(variant_index).name.as_str()), )), + enum_adt_def_id, ); let variant_struct_type_wrapper_di_node = build_variant_struct_wrapper_type_di_node( @@ -341,6 +364,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( tag_base_type_di_node, tag_base_type, DiscrResult::NoDiscriminant, + None, ); smallvec![ @@ -354,6 +378,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( Size::ZERO, visibility_flags, variant_struct_type_wrapper_di_node, + None, ), unsafe { llvm::LLVMRustDIBuilderCreateStaticMemberType( @@ -383,6 +408,12 @@ fn build_union_fields_for_enum<'ll, 'tcx>( ) -> SmallVec<&'ll DIType> { let tag_base_type = tag_base_type(cx.tcx, enum_type_and_layout); + let enum_adt_def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(enum_adt_def.did()) + } else { + None + }; + let variant_names_type_di_node = build_variant_names_type_di_node( cx, enum_type_di_node, @@ -390,6 +421,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>( let variant_name = Cow::from(enum_adt_def.variant(variant_index).name.as_str()); (variant_index, variant_name) }), + enum_adt_def_id, ); let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()); @@ -447,6 +479,7 @@ fn build_variant_names_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, containing_scope: &'ll DIType, variants: impl Iterator<Item = (VariantIdx, Cow<'tcx, str>)>, + enum_def_id: Option<rustc_span::def_id::DefId>, ) -> &'ll DIType { // Create an enumerator for each variant. super::build_enumeration_type_di_node( @@ -454,6 +487,7 @@ fn build_variant_names_type_di_node<'ll, 'tcx>( "VariantNames", variant_names_enum_base_type(cx), variants.map(|(variant_index, variant_name)| (variant_name, variant_index.as_u32().into())), + enum_def_id, containing_scope, ) } @@ -469,6 +503,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>( tag_base_type_di_node: &'ll DIType, tag_base_type: Ty<'tcx>, discr: DiscrResult, + source_info: Option<(&'ll DIFile, c_uint)>, ) -> &'ll DIType { type_map::build_type_with_children( cx, @@ -481,6 +516,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>( variant_index, ), &variant_struct_wrapper_type_name(variant_index), + source_info, // NOTE: We use size and align of enum_type, not from variant_layout: size_and_align_of(enum_or_coroutine_type_and_layout), Some(enum_or_coroutine_type_di_node), @@ -530,6 +566,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>( Size::ZERO, DIFlags::FlagZero, variant_struct_type_di_node, + None, )); let build_assoc_const = @@ -684,6 +721,11 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>( variant_range .clone() .map(|variant_index| (variant_index, CoroutineArgs::variant_name(variant_index))), + if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(coroutine_def_id) + } else { + None + }, ); let discriminants: IndexVec<VariantIdx, DiscrResult> = { @@ -776,6 +818,11 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( tag_base_type_di_node, tag_base_type, variant_member_info.discr, + if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + variant_member_info.source_info + } else { + None + }, ); // We use LLVMRustDIBuilderCreateMemberType() member type directly because @@ -831,6 +878,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( lo_offset, di_flags, type_di_node, + None, )); unions_fields.push(build_field_di_node( @@ -841,6 +889,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( hi_offset, DIFlags::FlagZero, type_di_node, + None, )); } else { unions_fields.push(build_field_di_node( @@ -851,6 +900,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( enum_type_and_layout.fields.offset(tag_field), di_flags, tag_base_type_di_node, + None, )); } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index b3d4a6642a1..65ab22ad89e 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -3,6 +3,7 @@ use std::borrow::Cow; use rustc_abi::{FieldIdx, TagEncoding, VariantIdx, Variants}; use rustc_codegen_ssa::debuginfo::type_names::{compute_debuginfo_type_name, cpp_like_debuginfo}; use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo}; +use rustc_codegen_ssa::traits::MiscCodegenMethods; use rustc_hir::def::CtorKind; use rustc_index::IndexSlice; use rustc_middle::bug; @@ -16,8 +17,8 @@ use super::{SmallVec, size_and_align_of}; use crate::common::{AsCCharPtr, CodegenCx}; use crate::debuginfo::metadata::type_map::{self, Stub}; use crate::debuginfo::metadata::{ - UNKNOWN_LINE_NUMBER, build_field_di_node, build_generic_type_param_di_nodes, type_di_node, - unknown_file_metadata, + UNKNOWN_LINE_NUMBER, build_field_di_node, build_generic_type_param_di_nodes, + file_metadata_from_def_id, type_di_node, unknown_file_metadata, }; use crate::debuginfo::utils::{DIB, create_DIArray, get_namespace_for_item}; use crate::llvm::debuginfo::{DIFlags, DIType}; @@ -68,6 +69,11 @@ fn build_c_style_enum_di_node<'ll, 'tcx>( enum_type_and_layout: TyAndLayout<'tcx>, ) -> DINodeCreationResult<'ll> { let containing_scope = get_namespace_for_item(cx, enum_adt_def.did()); + let enum_adt_def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(enum_adt_def.did()) + } else { + None + }; DINodeCreationResult { di_node: build_enumeration_type_di_node( cx, @@ -77,6 +83,7 @@ fn build_c_style_enum_di_node<'ll, 'tcx>( let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str()); (name, discr.val) }), + enum_adt_def_id, containing_scope, ), already_stored_in_typemap: false, @@ -92,6 +99,7 @@ fn build_enumeration_type_di_node<'ll, 'tcx>( type_name: &str, base_type: Ty<'tcx>, enumerators: impl Iterator<Item = (Cow<'tcx, str>, u128)>, + def_id: Option<rustc_span::def_id::DefId>, containing_scope: &'ll DIType, ) -> &'ll DIType { let is_unsigned = match base_type.kind() { @@ -115,14 +123,21 @@ fn build_enumeration_type_di_node<'ll, 'tcx>( }) .collect(); + let (file_metadata, line_number) = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers + { + file_metadata_from_def_id(cx, def_id) + } else { + (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) + }; + unsafe { llvm::LLVMRustDIBuilderCreateEnumerationType( DIB(cx), containing_scope, type_name.as_c_char_ptr(), type_name.len(), - unknown_file_metadata(cx), - UNKNOWN_LINE_NUMBER, + file_metadata, + line_number, size.bits(), align.bits() as u32, create_DIArray(DIB(cx), &enumerator_di_nodes[..]), @@ -193,6 +208,12 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( ) -> &'ll DIType { assert_eq!(variant_layout.ty, enum_type_and_layout.ty); + let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(file_metadata_from_def_id(cx, Some(variant_def.def_id))) + } else { + None + }; + type_map::build_type_with_children( cx, type_map::stub( @@ -204,6 +225,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( variant_index, ), variant_def.name.as_str(), + def_location, // NOTE: We use size and align of enum_type, not from variant_layout: size_and_align_of(enum_type_and_layout), Some(enum_type_di_node), @@ -231,6 +253,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( variant_layout.fields.offset(field_index), di_flags, type_di_node(cx, field_layout.ty), + None, ) }) .collect::<SmallVec<_>>() @@ -286,6 +309,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>( Stub::Struct, unique_type_id, &variant_name, + None, size_and_align_of(coroutine_type_and_layout), Some(coroutine_type_di_node), DIFlags::FlagZero, @@ -312,6 +336,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>( variant_layout.fields.offset(field_index), DIFlags::FlagZero, type_di_node(cx, field_type), + None, ) }) .collect(); @@ -331,6 +356,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>( coroutine_type_and_layout.fields.offset(index), DIFlags::FlagZero, type_di_node(cx, upvar_ty), + None, ) }) .collect(); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index d4006691d37..241bf167a81 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -4,7 +4,7 @@ use libc::c_uint; use rustc_abi::{Size, TagEncoding, VariantIdx, Variants}; use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name; use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo}; -use rustc_codegen_ssa::traits::ConstCodegenMethods; +use rustc_codegen_ssa::traits::{ConstCodegenMethods, MiscCodegenMethods}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self}; @@ -14,7 +14,8 @@ use crate::common::{AsCCharPtr, CodegenCx}; use crate::debuginfo::metadata::type_map::{self, Stub, StubInfo, UniqueTypeId}; use crate::debuginfo::metadata::{ DINodeCreationResult, NO_GENERICS, SmallVec, UNKNOWN_LINE_NUMBER, file_metadata, - size_and_align_of, type_di_node, unknown_file_metadata, visibility_di_flags, + file_metadata_from_def_id, size_and_align_of, type_di_node, unknown_file_metadata, + visibility_di_flags, }; use crate::debuginfo::utils::{DIB, create_DIArray, get_namespace_for_item}; use crate::llvm::debuginfo::{DIFile, DIFlags, DIType}; @@ -55,6 +56,12 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( assert!(!wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout)); + let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(file_metadata_from_def_id(cx, Some(enum_adt_def.did()))) + } else { + None + }; + type_map::build_type_with_children( cx, type_map::stub( @@ -62,6 +69,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( Stub::Struct, unique_type_id, &enum_type_name, + def_location, size_and_align_of(enum_type_and_layout), Some(containing_scope), visibility_flags, @@ -84,14 +92,27 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( enum_type_and_layout.for_variant(cx, variant_index), visibility_flags, ), - source_info: None, + source_info: if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(file_metadata_from_def_id( + cx, + Some(enum_adt_def.variant(variant_index).def_id), + )) + } else { + None + }, }) .collect(); + let enum_adt_def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(enum_adt_def.did()) + } else { + None + }; smallvec![build_enum_variant_part_di_node( cx, enum_type_and_layout, enum_type_di_node, + enum_adt_def_id, &variant_member_infos[..], )] }, @@ -134,6 +155,12 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>( let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false); + let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(file_metadata_from_def_id(cx, Some(coroutine_def_id))) + } else { + None + }; + type_map::build_type_with_children( cx, type_map::stub( @@ -141,6 +168,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>( Stub::Struct, unique_type_id, &coroutine_type_name, + def_location, size_and_align_of(coroutine_type_and_layout), Some(containing_scope), DIFlags::FlagZero, @@ -197,10 +225,16 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>( }) .collect(); + let coroutine_def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { + Some(coroutine_def_id) + } else { + None + }; smallvec![build_enum_variant_part_di_node( cx, coroutine_type_and_layout, coroutine_type_di_node, + coroutine_def_id, &variant_struct_type_di_nodes[..], )] }, @@ -228,6 +262,7 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, enum_type_and_layout: TyAndLayout<'tcx>, enum_type_di_node: &'ll DIType, + enum_type_def_id: Option<rustc_span::def_id::DefId>, variant_member_infos: &[VariantMemberInfo<'_, 'll>], ) -> &'ll DIType { let tag_member_di_node = @@ -236,6 +271,13 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>( let variant_part_unique_type_id = UniqueTypeId::for_enum_variant_part(cx.tcx, enum_type_and_layout.ty); + let (file_metadata, line_number) = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers + { + file_metadata_from_def_id(cx, enum_type_def_id) + } else { + (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) + }; + let stub = StubInfo::new( cx, variant_part_unique_type_id, @@ -246,8 +288,8 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>( enum_type_di_node, variant_part_name.as_c_char_ptr(), variant_part_name.len(), - unknown_file_metadata(cx), - UNKNOWN_LINE_NUMBER, + file_metadata, + line_number, enum_type_and_layout.size.bits(), enum_type_and_layout.align.abi.bits() as u32, DIFlags::FlagZero, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index 4e461476040..a37e719d43f 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -8,7 +8,7 @@ use rustc_macros::HashStable; use rustc_middle::bug; use rustc_middle::ty::{self, PolyExistentialTraitRef, Ty, TyCtxt}; -use super::{SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata}; +use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata}; use crate::common::{AsCCharPtr, CodegenCx}; use crate::debuginfo::utils::{DIB, create_DIArray, debug_context}; use crate::llvm::debuginfo::{DIFlags, DIScope, DIType}; @@ -186,6 +186,7 @@ pub(super) fn stub<'ll, 'tcx>( kind: Stub<'ll>, unique_type_id: UniqueTypeId<'tcx>, name: &str, + def_location: Option<DefinitionLocation<'ll>>, (size, align): (Size, Align), containing_scope: Option<&'ll DIScope>, flags: DIFlags, @@ -193,6 +194,12 @@ pub(super) fn stub<'ll, 'tcx>( let empty_array = create_DIArray(DIB(cx), &[]); let unique_type_id_str = unique_type_id.generate_unique_id_string(cx.tcx); + let (file_metadata, line_number) = if let Some(def_location) = def_location { + (def_location.0, def_location.1) + } else { + (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) + }; + let metadata = match kind { Stub::Struct | Stub::VTableTy { .. } => { let vtable_holder = match kind { @@ -205,8 +212,8 @@ pub(super) fn stub<'ll, 'tcx>( containing_scope, name.as_c_char_ptr(), name.len(), - unknown_file_metadata(cx), - UNKNOWN_LINE_NUMBER, + file_metadata, + line_number, size.bits(), align.bits() as u32, flags, @@ -225,8 +232,8 @@ pub(super) fn stub<'ll, 'tcx>( containing_scope, name.as_c_char_ptr(), name.len(), - unknown_file_metadata(cx), - UNKNOWN_LINE_NUMBER, + file_metadata, + line_number, size.bits(), align.bits() as u32, flags, diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index da7f94e8cf7..d8b055137b3 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1534,6 +1534,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( sym::simd_flog => ("log", bx.type_func(&[vec_ty], vec_ty)), sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)), sym::simd_fma => ("fma", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)), + sym::simd_relaxed_fma => ("fmuladd", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)), sym::simd_fpowi => ("powi", bx.type_func(&[vec_ty, bx.type_i32()], vec_ty)), sym::simd_fpow => ("pow", bx.type_func(&[vec_ty, vec_ty], vec_ty)), sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)), @@ -1572,6 +1573,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( | sym::simd_fpowi | sym::simd_fsin | sym::simd_fsqrt + | sym::simd_relaxed_fma | sym::simd_round | sym::simd_trunc ) { diff --git a/compiler/rustc_codegen_ssa/src/back/apple.rs b/compiler/rustc_codegen_ssa/src/back/apple.rs index 93d90cd16b2..d9c5c3e5af9 100644 --- a/compiler/rustc_codegen_ssa/src/back/apple.rs +++ b/compiler/rustc_codegen_ssa/src/back/apple.rs @@ -97,7 +97,7 @@ fn minimum_deployment_target(target: &Target) -> OSVersion { } /// Name of the environment variable used to fetch the deployment target on the given OS. -fn deployment_target_env_var(os: &str) -> &'static str { +pub fn deployment_target_env_var(os: &str) -> &'static str { match os { "macos" => "MACOSX_DEPLOYMENT_TARGET", "ios" => "IPHONEOS_DEPLOYMENT_TARGET", diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index f93f4d36e45..c31c94495d0 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -110,7 +110,7 @@ const_eval_extern_type_field = `extern type` field does not have a known offset const_eval_fn_ptr_call = function pointers need an RFC before allowed to be called in {const_eval_const_context}s const_eval_for_loop_into_iter_non_const = - cannot convert `{$ty}` into an iterator in {const_eval_const_context}s + cannot use `for` loop on `{$ty}` in {const_eval_const_context}s const_eval_frame_note = {$times -> [0] {const_eval_frame_note_inner} @@ -324,11 +324,11 @@ const_eval_ptr_as_bytes_1 = this code performed an operation that depends on the underlying bytes representing a pointer const_eval_ptr_as_bytes_2 = the absolute address of a pointer is not known at compile-time, so such operations are not supported -const_eval_question_branch_non_const = - `?` cannot determine the branch of `{$ty}` in {const_eval_const_context}s +const_eval_question_branch_non_const = + `?` is not allowed on `{$ty}` in {const_eval_const_context}s const_eval_question_from_residual_non_const = - `?` cannot convert from residual of `{$ty}` in {const_eval_const_context}s + `?` is not allowed on `{$ty}` in {const_eval_const_context}s const_eval_range = in the range {$lo}..={$hi} const_eval_range_lower = greater or equal to {$lo} diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index ab81e60a33f..489bb54a6f9 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -180,8 +180,10 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { }; } - let mut err = match kind { - CallDesugaringKind::ForLoopIntoIter => { + // Don't point at the trait if this is a desugaring... + // FIXME(const_trait_impl): we could perhaps do this for `Iterator`. + match kind { + CallDesugaringKind::ForLoopIntoIter | CallDesugaringKind::ForLoopNext => { error!(NonConstForLoopIntoIter) } CallDesugaringKind::QuestionBranch => { @@ -196,10 +198,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { CallDesugaringKind::Await => { error!(NonConstAwait) } - }; - - diag_trait(&mut err, self_ty, kind.trait_def_id(tcx)); - err + } } CallKind::FnCall { fn_trait_id, self_ty } => { let note = match self_ty.kind() { diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 1271d9d2d0d..3cb77d1dcb5 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -139,12 +139,14 @@ where match error { // Don't emit a new diagnostic for these errors, they are already reported elsewhere or // should remain silent. + err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span), err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { ErrorHandled::TooGeneric(span) } - err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span), err_inval!(Layout(LayoutError::ReferencesError(guar))) => { - ErrorHandled::Reported(ReportedErrorInfo::tainted_by_errors(guar), span) + // This can occur in infallible promoteds e.g. when a non-existent type or field is + // encountered. + ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), span) } // Report remaining errors. _ => { @@ -152,7 +154,12 @@ where let span = span.substitute_dummy(our_span); let err = mk(span, frames); let mut err = tcx.dcx().create_err(err); - let can_be_spurious = matches!(error, InterpErrorKind::ResourceExhaustion(_)); + // We allow invalid programs in infallible promoteds since invalid layouts can occur + // anyway (e.g. due to size overflow). And we allow OOM as that can happen any time. + let allowed_in_infallible = matches!( + error, + InterpErrorKind::ResourceExhaustion(_) | InterpErrorKind::InvalidProgram(_) + ); let msg = error.diagnostic_message(); error.add_args(&mut err); @@ -160,8 +167,8 @@ where // Use *our* span to label the interp error err.span_label(our_span, msg); let g = err.emit(); - let reported = if can_be_spurious { - ReportedErrorInfo::spurious(g) + let reported = if allowed_in_infallible { + ReportedErrorInfo::allowed_in_infallible(g) } else { ReportedErrorInfo::from(g) }; diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 8cbdcd68e13..34f795bda75 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -2,6 +2,7 @@ use rustc_abi::VariantIdx; use rustc_middle::query::{Key, TyCtxtAt}; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, mir}; use tracing::instrument; @@ -85,5 +86,6 @@ pub fn tag_for_variant_provider<'tcx>( crate::const_eval::DummyMachine, ); - ecx.tag_for_variant(ty, variant_index).unwrap().map(|(tag, _tag_field)| tag) + let layout = ecx.layout_of(ty).unwrap(); + ecx.tag_for_variant(layout, variant_index).unwrap().map(|(tag, _tag_field)| tag) } diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index f94d0cbb42b..6faac1582ab 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -1,7 +1,7 @@ //! Functions for reading and writing discriminants of multi-variant layouts (enums and coroutines). use rustc_abi::{self as abi, TagEncoding, VariantIdx, Variants}; -use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt}; +use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::{self, CoroutineArgsExt, ScalarInt, Ty}; use rustc_middle::{mir, span_bug}; use tracing::{instrument, trace}; @@ -21,17 +21,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { variant_index: VariantIdx, dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { - // Layout computation excludes uninhabited variants from consideration - // therefore there's no way to represent those variants in the given layout. - // Essentially, uninhabited variants do not have a tag that corresponds to their - // discriminant, so we cannot do anything here. - // When evaluating we will always error before even getting here, but ConstProp 'executes' - // dead code, so we cannot ICE here. - if dest.layout().for_variant(self, variant_index).is_uninhabited() { - throw_ub!(UninhabitedEnumVariantWritten(variant_index)) - } - - match self.tag_for_variant(dest.layout().ty, variant_index)? { + match self.tag_for_variant(dest.layout(), variant_index)? { Some((tag, tag_field)) => { // No need to validate that the discriminant here because the // `TyAndLayout::for_variant()` call earlier already checks the @@ -80,7 +70,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if ty.is_enum() { // Hilariously, `Single` is used even for 0-variant enums. // (See https://github.com/rust-lang/rust/issues/89765). - if matches!(ty.kind(), ty::Adt(def, ..) if def.variants().is_empty()) { + if ty.ty_adt_def().unwrap().variants().is_empty() { throw_ub!(UninhabitedEnumVariantRead(index)) } // For consistency with `write_discriminant`, and to make sure that @@ -188,6 +178,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let variants = ty.ty_adt_def().expect("tagged layout for non adt").variants(); assert!(variant_index < variants.next_index()); + if variant_index == untagged_variant { + // The untagged variant can be in the niche range, but even then it + // is not a valid encoding. + throw_ub!(InvalidTag(Scalar::from_uint(tag_bits, tag_layout.size))) + } variant_index } else { untagged_variant @@ -236,10 +231,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// given field index. pub(crate) fn tag_for_variant( &self, - ty: Ty<'tcx>, + layout: TyAndLayout<'tcx>, variant_index: VariantIdx, ) -> InterpResult<'tcx, Option<(ScalarInt, usize)>> { - match self.layout_of(ty)?.variants { + // Layout computation excludes uninhabited variants from consideration. + // Therefore, there's no way to represent those variants in the given layout. + // Essentially, uninhabited variants do not have a tag that corresponds to their + // discriminant, so we have to bail out here. + if layout.for_variant(self, variant_index).is_uninhabited() { + throw_ub!(UninhabitedEnumVariantWritten(variant_index)) + } + + match layout.variants { abi::Variants::Single { .. } => { // The tag of a `Single` enum is like the tag of the niched // variant: there's no tag as the discriminant is encoded @@ -260,7 +263,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // raw discriminants for enums are isize or bigger during // their computation, but the in-memory tag is the smallest possible // representation - let discr = self.discriminant_for_variant(ty, variant_index)?; + let discr = self.discriminant_for_variant(layout.ty, variant_index)?; let discr_size = discr.layout.size; let discr_val = discr.to_scalar().to_bits(discr_size)?; let tag_size = tag_layout.size(self); @@ -286,11 +289,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { .. } => { assert!(variant_index != untagged_variant); + // We checked that this variant is inhabited, so it must be in the niche range. + assert!( + niche_variants.contains(&variant_index), + "invalid variant index for this enum" + ); let variants_start = niche_variants.start().as_u32(); - let variant_index_relative = variant_index - .as_u32() - .checked_sub(variants_start) - .expect("overflow computing relative variant idx"); + let variant_index_relative = variant_index.as_u32().strict_sub(variants_start); // We need to use machine arithmetic when taking into account `niche_start`: // tag_val = variant_index_relative + niche_start_val let tag_layout = self.layout_of(tag_layout.primitive().to_int_ty(*self.tcx))?; diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index fe93a48c2f2..241be5e175c 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -268,7 +268,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; // do not continue if typeck errors occurred (can only occur in local crate) if let Some(err) = body.tainted_by_errors { - throw_inval!(AlreadyReported(ReportedErrorInfo::tainted_by_errors(err))); + throw_inval!(AlreadyReported(ReportedErrorInfo::from(err))); } interp_ok(body) } @@ -585,13 +585,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { match err { ErrorHandled::TooGeneric(..) => {}, ErrorHandled::Reported(reported, span) => { - if reported.is_tainted_by_errors() { - // const-eval will return "tainted" errors if e.g. the layout cannot - // be computed as the type references non-existing names. - // See <https://github.com/rust-lang/rust/issues/124348>. - } else if reported.can_be_spurious() { + if reported.is_allowed_in_infallible() { // These errors can just sometimes happen, even when the expression - // is nominally "infallible", e.g. when running out of memory. + // is nominally "infallible", e.g. when running out of memory + // or when some layout could not be computed. } else { // Looks like the const is not captured by `required_consts`, that's bad. span_bug!(span, "interpret const eval failure of {val:?} which is not in required_consts"); diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 2a7408f1c70..b5adf06b300 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -10,6 +10,7 @@ #![feature(never_type)] #![feature(rustdoc_internals)] #![feature(slice_ptr_get)] +#![feature(strict_overflow_ops)] #![feature(trait_alias)] #![feature(try_blocks)] #![feature(unqualified_local_imports)] diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index 34a2464972a..78d69a66edc 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -415,6 +415,10 @@ impl<O: ForestObligation> ObligationForest<O> { .collect() } + pub fn has_pending_obligations(&self) -> bool { + self.nodes.iter().any(|node| node.state.get() == NodeState::Pending) + } + fn insert_into_error_cache(&mut self, index: usize) { let node = &self.nodes[index]; self.error_cache diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 85eaae8a104..b7d64f75bf3 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -418,9 +418,7 @@ fn run_compiler( return early_exit(); } - if sess.opts.unstable_opts.parse_crate_root_only - || sess.opts.unstable_opts.show_span.is_some() - { + if sess.opts.unstable_opts.parse_crate_root_only { return early_exit(); } @@ -867,8 +865,9 @@ fn print_crate_info( DeploymentTarget => { if sess.target.is_like_osx { println_info!( - "deployment_target={}", - apple::pretty_version(apple::deployment_target(sess)) + "{}={}", + apple::deployment_target_env_var(&sess.target.os), + apple::pretty_version(apple::deployment_target(sess)), ) } else { #[allow(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_error_codes/src/error_codes/E0060.md b/compiler/rustc_error_codes/src/error_codes/E0060.md index 54b10c886cc..a6831c881e3 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0060.md +++ b/compiler/rustc_error_codes/src/error_codes/E0060.md @@ -15,7 +15,7 @@ unsafe { printf(); } // error! Using this declaration, it must be called with at least one argument, so simply calling `printf()` is invalid. But the following uses are allowed: -``` +```rust,edition2021 # use std::os::raw::{c_char, c_int}; # #[cfg_attr(all(windows, target_env = "msvc"), # link(name = "legacy_stdio_definitions", @@ -23,16 +23,11 @@ simply calling `printf()` is invalid. But the following uses are allowed: # extern "C" { fn printf(_: *const c_char, ...) -> c_int; } # fn main() { unsafe { - use std::ffi::CString; - - let fmt = CString::new("test\n").unwrap(); - printf(fmt.as_ptr()); + printf(c"test\n".as_ptr()); - let fmt = CString::new("number = %d\n").unwrap(); - printf(fmt.as_ptr(), 3); + printf(c"number = %d\n".as_ptr(), 3); - let fmt = CString::new("%d, %d\n").unwrap(); - printf(fmt.as_ptr(), 10, 5); + printf(c"%d, %d\n".as_ptr(), 10, 5); } # } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0622.md b/compiler/rustc_error_codes/src/error_codes/E0622.md index 5d71ee9949d..4cb605b636d 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0622.md +++ b/compiler/rustc_error_codes/src/error_codes/E0622.md @@ -7,10 +7,11 @@ Erroneous code example: #![allow(internal_features)] extern "rust-intrinsic" { - pub static breakpoint: fn(); // error: intrinsic must be a function + pub static atomic_singlethreadfence_seqcst: fn(); + // error: intrinsic must be a function } -fn main() { unsafe { breakpoint(); } } +fn main() { unsafe { atomic_singlethreadfence_seqcst(); } } ``` An intrinsic is a function available for use in a given programming language @@ -22,8 +23,8 @@ error, just declare a function. Example: #![allow(internal_features)] extern "rust-intrinsic" { - pub fn breakpoint(); // ok! + pub fn atomic_singlethreadfence_seqcst(); // ok! } -fn main() { unsafe { breakpoint(); } } +fn main() { unsafe { atomic_singlethreadfence_seqcst(); } } ``` diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 798668b8bc1..b4510371323 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -6,6 +6,7 @@ use std::path::{Path, PathBuf}; use std::process::ExitStatus; use rustc_abi::TargetDataLayoutErrors; +use rustc_ast::util::parser::ExprPrecedence; use rustc_ast_pretty::pprust; use rustc_macros::Subdiagnostic; use rustc_span::Span; @@ -298,6 +299,12 @@ impl IntoDiagArg for hir::def::Namespace { } } +impl IntoDiagArg for ExprPrecedence { + fn into_diag_arg(self) -> DiagArgValue { + DiagArgValue::Number(self as i32) + } +} + #[derive(Clone)] pub struct DiagSymbolList<S = Symbol>(Vec<S>); diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 19c2d466f7c..e5500c8bba1 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -732,7 +732,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { _ => item.to_tokens(), }; let attr_item = attr.unwrap_normal_item(); - if let AttrArgs::Eq(..) = attr_item.args { + if let AttrArgs::Eq { .. } = attr_item.args { self.cx.dcx().emit_err(UnsupportedKeyValue { span }); } let inner_tokens = attr_item.args.inner_tokens(); diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 69a14bd9f12..8b4f441dafe 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -119,6 +119,13 @@ declare_features! ( (removed, generator_clone, "1.65.0", Some(95360), Some("renamed to `coroutine_clone`")), /// Allows defining generators. (removed, generators, "1.21.0", Some(43122), Some("renamed to `coroutines`")), + /// An extension to the `generic_associated_types` feature, allowing incomplete features. + (removed, generic_associated_types_extended, "CURRENT_RUSTC_VERSION", Some(95451), + Some( + "feature needs overhaul and reimplementation pending \ + better implied higher-ranked implied bounds support" + ) + ), /// Allows `impl Trait` in bindings (`let`, `const`, `static`). (removed, impl_trait_in_bindings, "1.55.0", Some(63065), Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index ec908762da7..abc7200699c 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -394,6 +394,8 @@ declare_features! ( (unstable, async_fn_track_caller, "1.73.0", Some(110011)), /// Allows `for await` loops. (unstable, async_for_loop, "1.77.0", Some(118898)), + /// Allows `async` trait bound modifier. + (unstable, async_trait_bounds, "CURRENT_RUSTC_VERSION", Some(62290)), /// Allows using C-variadics. (unstable, c_variadic, "1.34.0", Some(44930)), /// Allows the use of `#[cfg(<true/false>)]`. @@ -497,8 +499,6 @@ declare_features! ( (unstable, gen_blocks, "1.75.0", Some(117078)), /// Infer generic args for both consts and types. (unstable, generic_arg_infer, "1.55.0", Some(85077)), - /// An extension to the `generic_associated_types` feature, allowing incomplete features. - (incomplete, generic_associated_types_extended, "1.61.0", Some(95451)), /// Allows non-trivial generic constants which have to have wfness manually propagated to callers (incomplete, generic_const_exprs, "1.56.0", Some(76560)), /// Allows generic parameters and where-clauses on free & associated const items. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 97aa88c1de8..a9696627f11 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,7 +1,7 @@ use std::fmt; use rustc_abi::ExternAbi; -use rustc_ast::util::parser::{AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_UNAMBIGUOUS}; +use rustc_ast::util::parser::{AssocOp, ExprPrecedence}; use rustc_ast::{ self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitKind, TraitObjectSyntax, UintTy, @@ -1695,22 +1695,22 @@ pub struct Expr<'hir> { } impl Expr<'_> { - pub fn precedence(&self) -> i8 { + pub fn precedence(&self) -> ExprPrecedence { match self.kind { - ExprKind::Closure { .. } => PREC_CLOSURE, + ExprKind::Closure { .. } => ExprPrecedence::Closure, ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::Yield(..) - | ExprKind::Become(..) => PREC_JUMP, + | ExprKind::Become(..) => ExprPrecedence::Jump, // Binop-like expr kinds, handled by `AssocOp`. - ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8, - ExprKind::Cast(..) => AssocOp::As.precedence() as i8, + ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence(), + ExprKind::Cast(..) => ExprPrecedence::Cast, ExprKind::Assign(..) | - ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8, + ExprKind::AssignOp(..) => ExprPrecedence::Assign, // Unary, prefix ExprKind::AddrOf(..) @@ -1719,7 +1719,7 @@ impl Expr<'_> { // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b` // but we need to print `(let _ = a) < b` as-is with parens. | ExprKind::Let(..) - | ExprKind::Unary(..) => PREC_PREFIX, + | ExprKind::Unary(..) => ExprPrecedence::Prefix, // Never need parens ExprKind::Array(_) @@ -1740,7 +1740,7 @@ impl Expr<'_> { | ExprKind::Struct(..) | ExprKind::Tup(_) | ExprKind::Type(..) - | ExprKind::Err(_) => PREC_UNAMBIGUOUS, + | ExprKind::Err(_) => ExprPrecedence::Unambiguous, ExprKind::DropTemps(ref expr, ..) => expr.precedence(), } diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index cb658111392..070d63b48b7 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -113,8 +113,6 @@ hir_analysis_const_param_ty_impl_on_unsized = the trait `ConstParamTy` may not be implemented for this type .label = type is not `Sized` -hir_analysis_const_specialize = cannot specialize on const impl with non-const impl - hir_analysis_copy_impl_on_non_adt = the trait `Copy` cannot be implemented for this type .label = type is not a structure or enumeration diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index e1f4ccca97e..022a6d457ec 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -103,7 +103,7 @@ fn allowed_union_or_unsafe_field<'tcx>( // Fallback case: allow `ManuallyDrop` and things that are `Copy`, // also no need to report an error if the type is unresolved. ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop()) - || ty.is_copy_modulo_regions(tcx, typing_env) + || tcx.type_is_copy_modulo_regions(typing_env, ty) || ty.references_error() } }; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 3e33120901f..2e6b511412b 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -87,6 +87,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) - | sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid + | sym::breakpoint | sym::size_of | sym::min_align_of | sym::needs_drop @@ -641,7 +642,9 @@ pub fn check_intrinsic_type( | sym::simd_round | sym::simd_trunc => (1, 0, vec![param(0)], param(0)), sym::simd_fpowi => (1, 0, vec![param(0), tcx.types.i32], param(0)), - sym::simd_fma => (1, 0, vec![param(0), param(0), param(0)], param(0)), + sym::simd_fma | sym::simd_relaxed_fma => { + (1, 0, vec![param(0), param(0), param(0)], param(0)) + } sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)), sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)), sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit), diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index b96469f503c..df4da03f0f5 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -178,7 +178,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // Check that the type implements Copy. The only case where this can // possibly fail is for SIMD types which don't #[derive(Copy)]. - if !ty.is_copy_modulo_regions(self.tcx, self.typing_env) { + if !self.tcx.type_is_copy_modulo_regions(self.typing_env, ty) { let msg = "arguments for inline assembly must be copyable"; self.tcx .dcx() diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 8fa797db246..2b33da3c49a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -13,6 +13,7 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_macros::LintDiagnostic; +use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::query::Providers; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::trait_def::TraitSpecializationKind; @@ -116,13 +117,12 @@ where } f(&mut wfcx)?; - let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?; - let errors = wfcx.select_all_or_error(); if !errors.is_empty() { return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); } + let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?; debug!(?assumed_wf_types); let infcx_compat = infcx.fork(); @@ -1170,19 +1170,13 @@ fn check_type_defn<'tcx>( // Explicit `enum` discriminant values must const-evaluate successfully. if let ty::VariantDiscr::Explicit(discr_def_id) = variant.discr { - let cause = traits::ObligationCause::new( - tcx.def_span(discr_def_id), - wfcx.body_def_id, - ObligationCauseCode::Misc, - ); - wfcx.register_obligation(Obligation::new( - tcx, - cause, - wfcx.param_env, - ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable( - ty::Const::from_anon_const(tcx, discr_def_id.expect_local()), - ))), - )); + match tcx.const_eval_poly(discr_def_id) { + Ok(_) => {} + Err(ErrorHandled::Reported(..)) => {} + Err(ErrorHandled::TooGeneric(sp)) => { + span_bug!(sp, "enum variant discr was too generic to eval") + } + } } } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 8d5824130d8..a4636da3f62 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -309,10 +309,10 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { self.tcx.ensure().type_of(param.def_id); if let Some(default) = default { // need to store default and type of default + self.tcx.ensure().const_param_default(param.def_id); if let hir::ConstArgKind::Anon(ac) = default.kind { self.tcx.ensure().type_of(ac.def_id); } - self.tcx.ensure().const_param_default(param.def_id); } } } @@ -1817,7 +1817,6 @@ fn const_param_default<'tcx>( ), }; let icx = ItemCtxt::new(tcx, def_id); - // FIXME(const_generics): investigate which places do and don't need const ty feeding - let ct = icx.lowerer().lower_const_arg(default_ct, FeedConstTy::No); + let ct = icx.lowerer().lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id())); ty::EarlyBinder::bind(ct) } diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 8648a7d1e32..f1022d95753 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -1,6 +1,6 @@ use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::intravisit; -use rustc_middle::hir::nested_filter::OnlyBodies; +use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::sym; @@ -42,7 +42,8 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) { } pub(crate) fn def_parents(tcx: TyCtxt<'_>) { - for did in tcx.hir().body_owners() { + for iid in tcx.hir().items() { + let did = iid.owner_id.def_id; if tcx.has_attr(did, sym::rustc_dump_def_parents) { struct AnonConstFinder<'tcx> { tcx: TyCtxt<'tcx>, @@ -50,7 +51,7 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) { } impl<'tcx> intravisit::Visitor<'tcx> for AnonConstFinder<'tcx> { - type NestedFilter = OnlyBodies; + type NestedFilter = nested_filter::All; fn nested_visit_map(&mut self) -> Self::Map { self.tcx.hir() @@ -62,11 +63,11 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) { } } - // Look for any anon consts inside of this body owner as there is no way to apply + // Look for any anon consts inside of this item as there is no way to apply // the `rustc_dump_def_parents` attribute to the anon const so it would not be possible // to see what its def parent is. let mut anon_ct_finder = AnonConstFinder { tcx, anon_consts: vec![] }; - intravisit::walk_expr(&mut anon_ct_finder, tcx.hir().body_owned_by(did).value); + intravisit::walk_item(&mut anon_ct_finder, tcx.hir().item(iid)); for did in [did].into_iter().chain(anon_ct_finder.anon_consts) { let span = tcx.def_span(did); diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 077696ac1f2..1d9114b0ef3 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -419,7 +419,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { if let Node::ConstBlock(_) = node { own_params.push(ty::GenericParamDef { index: next_index(), - name: Symbol::intern("<const_ty>"), + name: rustc_span::sym::const_ty_placeholder, def_id: def_id.to_def_id(), pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false }, diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index bfee5d33598..ca2597e79fd 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -1,12 +1,13 @@ use std::assert_matches::assert_matches; -use hir::{HirId, Node}; +use hir::Node; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit::{self, Visitor}; -use rustc_middle::ty::{self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, Upcast}; +use rustc_middle::ty::{ + self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitor, Upcast, +}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::{DUMMY_SP, Span}; @@ -305,7 +306,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } if tcx.features().generic_const_exprs() { - predicates.extend(const_evaluatable_predicates_of(tcx, def_id)); + predicates.extend(const_evaluatable_predicates_of(tcx, def_id, &predicates)); } let mut predicates: Vec<_> = predicates.into_iter().collect(); @@ -369,32 +370,48 @@ fn compute_bidirectional_outlives_predicates<'tcx>( } } -fn const_evaluatable_predicates_of( - tcx: TyCtxt<'_>, +#[instrument(level = "debug", skip(tcx, predicates), ret)] +fn const_evaluatable_predicates_of<'tcx>( + tcx: TyCtxt<'tcx>, def_id: LocalDefId, -) -> FxIndexSet<(ty::Clause<'_>, Span)> { + predicates: &FxIndexSet<(ty::Clause<'tcx>, Span)>, +) -> FxIndexSet<(ty::Clause<'tcx>, Span)> { struct ConstCollector<'tcx> { tcx: TyCtxt<'tcx>, preds: FxIndexSet<(ty::Clause<'tcx>, Span)>, } - impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> { - fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) { - let ct = ty::Const::from_anon_const(self.tcx, c.def_id); - if let ty::ConstKind::Unevaluated(_) = ct.kind() { - let span = self.tcx.def_span(c.def_id); - self.preds.insert((ty::ClauseKind::ConstEvaluatable(ct).upcast(self.tcx), span)); - } - } + fn is_const_param_default(tcx: TyCtxt<'_>, def: LocalDefId) -> bool { + let hir_id = tcx.local_def_id_to_hir_id(def); + let (_, parent_node) = tcx + .hir() + .parent_iter(hir_id) + .skip_while(|(_, n)| matches!(n, Node::ConstArg(..))) + .next() + .unwrap(); + matches!( + parent_node, + Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Const { .. }, .. }) + ) + } - fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::ConstArg<'tcx>) { - // Do not look into const param defaults, - // these get checked when they are actually instantiated. - // - // We do not want the following to error: - // - // struct Foo<const N: usize, const M: usize = { N + 1 }>; - // struct Bar<const N: usize>(Foo<N, 3>); + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstCollector<'tcx> { + fn visit_const(&mut self, c: ty::Const<'tcx>) { + if let ty::ConstKind::Unevaluated(uv) = c.kind() { + if is_const_param_default(self.tcx, uv.def.expect_local()) { + // Do not look into const param defaults, + // these get checked when they are actually instantiated. + // + // We do not want the following to error: + // + // struct Foo<const N: usize, const M: usize = { N + 1 }>; + // struct Bar<const N: usize>(Foo<N, 3>); + return; + } + + let span = self.tcx.def_span(uv.def); + self.preds.insert((ty::ClauseKind::ConstEvaluatable(c).upcast(self.tcx), span)); + } } } @@ -402,28 +419,31 @@ fn const_evaluatable_predicates_of( let node = tcx.hir_node(hir_id); let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() }; + + for (clause, _sp) in predicates { + clause.visit_with(&mut collector); + } + if let hir::Node::Item(item) = node - && let hir::ItemKind::Impl(impl_) = item.kind + && let hir::ItemKind::Impl(_) = item.kind { - if let Some(of_trait) = &impl_.of_trait { - debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id); - collector.visit_trait_ref(of_trait); + if let Some(of_trait) = tcx.impl_trait_ref(def_id) { + debug!("visit impl trait_ref"); + of_trait.instantiate_identity().visit_with(&mut collector); } - debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id); - collector.visit_ty(impl_.self_ty); - } - - if let Some(generics) = node.generics() { - debug!("const_evaluatable_predicates_of({:?}): visit_generics", def_id); - collector.visit_generics(generics); + debug!("visit self_ty"); + let self_ty = tcx.type_of(def_id); + self_ty.instantiate_identity().visit_with(&mut collector); } - if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id) { - debug!("const_evaluatable_predicates_of({:?}): visit_fn_decl", def_id); - collector.visit_fn_decl(fn_sig.decl); + if let Some(_) = tcx.hir().fn_sig_by_hir_id(hir_id) { + debug!("visit fn sig"); + let fn_sig = tcx.fn_sig(def_id); + let fn_sig = fn_sig.instantiate_identity(); + debug!(?fn_sig); + fn_sig.visit_with(&mut collector); } - debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.preds); collector.preds } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 7cf99bebd36..72d5b3ac4f5 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -12,7 +12,6 @@ use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableEx use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::{DUMMY_SP, Span}; -use tracing::debug; use super::{ItemCtxt, bad_placeholder}; use crate::errors::TypeofReservedKeywordUsed; @@ -138,252 +137,26 @@ fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span use hir::*; use rustc_middle::ty::Ty; - let parent_node_id = tcx.parent_hir_id(arg_hir_id); - let parent_node = tcx.hir_node(parent_node_id); - - let (generics, arg_idx) = match parent_node { - // Easy case: arrays repeat expressions. + match tcx.parent_hir_node(arg_hir_id) { + // Array length const arguments do not have `type_of` fed as there is never a corresponding + // generic parameter definition. Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. }) | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) if constant.hir_id == arg_hir_id => { return tcx.types.usize; } - Node::GenericParam(&GenericParam { - def_id: param_def_id, - kind: GenericParamKind::Const { default: Some(ct), .. }, - .. - }) if ct.hir_id == arg_hir_id => { - return tcx - .type_of(param_def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"); - } - - // This match arm is for when the def_id appears in a GAT whose - // path can't be resolved without typechecking e.g. - // - // trait Foo { - // type Assoc<const N: usize>; - // fn foo() -> Self::Assoc<3>; - // } - // - // In the above code we would call this query with the def_id of 3 and - // the parent_node we match on would be the hir node for Self::Assoc<3> - // - // `Self::Assoc<3>` cant be resolved without typechecking here as we - // didnt write <Self as Foo>::Assoc<3>. If we did then another match - // arm would handle this. - // - // I believe this match arm is only needed for GAT but I am not 100% sure - BoxyUwU - Node::Ty(hir_ty @ hir::Ty { kind: TyKind::Path(QPath::TypeRelative(ty, segment)), .. }) => { - // Find the Item containing the associated type so we can create an ItemCtxt. - // Using the ItemCtxt lower the HIR for the unresolved assoc type into a - // ty which is a fully resolved projection. - // For the code example above, this would mean lowering `Self::Assoc<3>` - // to a ty::Alias(ty::Projection, `<Self as Foo>::Assoc<3>`). - let item_def_id = tcx.hir().get_parent_item(ty.hir_id).def_id; - let ty = ItemCtxt::new(tcx, item_def_id).lower_ty(hir_ty); - - // Iterate through the generics of the projection to find the one that corresponds to - // the def_id that this query was called with. We filter to only type and const args here - // as a precaution for if it's ever allowed to elide lifetimes in GAT's. It currently isn't - // but it can't hurt to be safe ^^ - if let ty::Alias(ty::Projection | ty::Inherent, projection) = ty.kind() { - let generics = tcx.generics_of(projection.def_id); - - let arg_index = segment - .args - .and_then(|args| { - args.args - .iter() - .filter(|arg| arg.is_ty_or_const()) - .position(|arg| arg.hir_id() == arg_hir_id) - }) - .unwrap_or_else(|| { - bug!("no arg matching AnonConst in segment"); - }); - - (generics, arg_index) - } else { - // I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU - return Ty::new_error_with_message( - tcx, - span, - "unexpected non-GAT usage of an anon const", - ); - } - } - Node::Expr(&Expr { - kind: - ExprKind::MethodCall(segment, ..) | ExprKind::Path(QPath::TypeRelative(_, segment)), - .. - }) => { - let body_owner = tcx.hir().enclosing_body_owner(arg_hir_id); - let tables = tcx.typeck(body_owner); - // This may fail in case the method/path does not actually exist. - // As there is no relevant param for `def_id`, we simply return - // `None` here. - let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else { - return Ty::new_error_with_message( - tcx, - span, - format!("unable to find type-dependent def for {parent_node_id:?}"), - ); - }; - let idx = segment - .args - .and_then(|args| { - args.args - .iter() - .filter(|arg| arg.is_ty_or_const()) - .position(|arg| arg.hir_id() == arg_hir_id) - }) - .unwrap_or_else(|| { - bug!("no arg matching ConstArg in segment"); - }); - - (tcx.generics_of(type_dependent_def), idx) - } - - Node::Ty(&hir::Ty { kind: TyKind::Path(_), .. }) - | Node::Expr(&Expr { kind: ExprKind::Path(_) | ExprKind::Struct(..), .. }) - | Node::TraitRef(..) - | Node::Pat(_) => { - let path = match parent_node { - Node::Ty(&hir::Ty { kind: TyKind::Path(QPath::Resolved(_, path)), .. }) - | Node::TraitRef(&TraitRef { path, .. }) => &*path, - Node::Expr(&Expr { - kind: - ExprKind::Path(QPath::Resolved(_, path)) - | ExprKind::Struct(&QPath::Resolved(_, path), ..), - .. - }) => { - let body_owner = tcx.hir().enclosing_body_owner(arg_hir_id); - let _tables = tcx.typeck(body_owner); - &*path - } - Node::Pat(pat) => { - if let Some(path) = get_path_containing_arg_in_pat(pat, arg_hir_id) { - path - } else { - return Ty::new_error_with_message( - tcx, - span, - format!("unable to find const parent for {arg_hir_id} in pat {pat:?}"), - ); - } - } - _ => { - return Ty::new_error_with_message( - tcx, - span, - format!("unexpected const parent path {parent_node:?}"), - ); - } - }; - - // We've encountered an `AnonConst` in some path, so we need to - // figure out which generic parameter it corresponds to and return - // the relevant type. - let Some((arg_index, segment)) = path.segments.iter().find_map(|seg| { - let args = seg.args?; - args.args - .iter() - .filter(|arg| arg.is_ty_or_const()) - .position(|arg| arg.hir_id() == arg_hir_id) - .map(|index| (index, seg)) - .or_else(|| { - args.constraints - .iter() - .copied() - .filter_map(AssocItemConstraint::ct) - .position(|ct| ct.hir_id == arg_hir_id) - .map(|idx| (idx, seg)) - }) - }) else { - return Ty::new_error_with_message(tcx, span, "no arg matching AnonConst in path"); - }; - - let generics = match tcx.res_generics_def_id(segment.res) { - Some(def_id) => tcx.generics_of(def_id), - None => { - return Ty::new_error_with_message( - tcx, - span, - format!("unexpected anon const res {:?} in path: {:?}", segment.res, path), - ); - } - }; - - (generics, arg_index) - } - _ => { - return Ty::new_error_with_message( - tcx, - span, - format!("unexpected const arg parent in type_of(): {parent_node:?}"), - ); - } - }; - - debug!(?parent_node); - debug!(?generics, ?arg_idx); - if let Some(param_def_id) = generics - .own_params - .iter() - .filter(|param| param.kind.is_ty_or_const()) - .nth(match generics.has_self && generics.parent.is_none() { - true => arg_idx + 1, - false => arg_idx, - }) - .and_then(|param| match param.kind { - ty::GenericParamDefKind::Const { .. } => { - debug!(?param); - Some(param.def_id) - } - _ => None, - }) - { - tcx.type_of(param_def_id).no_bound_vars().expect("const parameter types cannot be generic") - } else { - return Ty::new_error_with_message( + // This is not a `bug!` as const arguments in path segments that did not resolve to anything + // will result in `type_of` never being fed. + _ => Ty::new_error_with_message( tcx, span, - format!("const generic parameter not found in {generics:?} at position {arg_idx:?}"), - ); + "`type_of` called on const argument's anon const before the const argument was lowered", + ), } } -fn get_path_containing_arg_in_pat<'hir>( - pat: &'hir hir::Pat<'hir>, - arg_id: HirId, -) -> Option<&'hir hir::Path<'hir>> { - use hir::*; - - let is_arg_in_path = |p: &hir::Path<'_>| { - p.segments - .iter() - .filter_map(|seg| seg.args) - .flat_map(|args| args.args) - .any(|arg| arg.hir_id() == arg_id) - }; - let mut arg_path = None; - pat.walk(|pat| match pat.kind { - PatKind::Struct(QPath::Resolved(_, path), _, _) - | PatKind::TupleStruct(QPath::Resolved(_, path), _, _) - | PatKind::Path(QPath::Resolved(_, path)) - if is_arg_in_path(path) => - { - arg_path = Some(path); - false - } - _ => true, - }); - arg_path -} - pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, Ty<'_>> { use rustc_hir::*; use rustc_middle::ty::Ty; diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index fcea0052546..66255829dcf 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -226,13 +226,18 @@ impl TaitConstraintLocator<'_> { constrained = true; if !opaque_types_defined_by.contains(&self.def_id) { - self.tcx.dcx().emit_err(TaitForwardCompat { + let guar = self.tcx.dcx().emit_err(TaitForwardCompat { span: hidden_type.span, item_span: self .tcx .def_ident_span(item_def_id) .unwrap_or_else(|| self.tcx.def_span(item_def_id)), }); + // Avoid "opaque type not constrained" errors on the opaque itself. + self.found = Some(ty::OpaqueHiddenType { + span: DUMMY_SP, + ty: Ty::new_error(self.tcx, guar), + }); } let concrete_type = self.tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params( @@ -248,7 +253,7 @@ impl TaitConstraintLocator<'_> { if !constrained { debug!("no constraints in typeck results"); if opaque_types_defined_by.contains(&self.def_id) { - self.tcx.dcx().emit_err(TaitForwardCompat2 { + let guar = self.tcx.dcx().emit_err(TaitForwardCompat2 { span: self .tcx .def_ident_span(item_def_id) @@ -256,6 +261,11 @@ impl TaitConstraintLocator<'_> { opaque_type_span: self.tcx.def_span(self.def_id), opaque_type: self.tcx.def_path_str(self.def_id), }); + // Avoid "opaque type not constrained" errors on the opaque itself. + self.found = Some(ty::OpaqueHiddenType { + span: DUMMY_SP, + ty: Ty::new_error(self.tcx, guar), + }); } return; }; diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 51115b11e86..4142dcff226 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1080,13 +1080,6 @@ pub(crate) struct EmptySpecialization { } #[derive(Diagnostic)] -#[diag(hir_analysis_const_specialize)] -pub(crate) struct ConstSpecialize { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] #[diag(hir_analysis_static_specialize)] pub(crate) struct StaticSpecialize { #[primary_span] diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 9d60759ae48..0404e38a293 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -703,7 +703,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// It might actually be possible that we can already support early-bound generic params /// in such types if we just lifted some more checks in other places, too, for example -/// inside [`ty::Const::from_anon_const`]. However, even if that were the case, we should +/// inside `HirTyLowerer::lower_anon_const`. However, even if that were the case, we should /// probably gate this behind another feature flag. /// /// [^1]: <https://github.com/rust-lang/project-const-generics/issues/28>. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 7b8e95f3434..cb4209116ac 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2089,7 +2089,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { qpath.span(), format!("Const::lower_const_arg: invalid qpath {qpath:?}"), ), - hir::ConstArgKind::Anon(anon) => Const::from_anon_const(tcx, anon.def_id), + hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon.def_id), hir::ConstArgKind::Infer(span) => self.ct_infer(None, span), } } @@ -2177,6 +2177,92 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + /// Literals and const generic parameters are eagerly converted to a constant, everything else + /// becomes `Unevaluated`. + #[instrument(skip(self), level = "debug")] + fn lower_anon_const(&self, def: LocalDefId) -> Const<'tcx> { + let tcx = self.tcx(); + + let body_id = match tcx.hir_node_by_def_id(def) { + hir::Node::AnonConst(ac) => ac.body, + node => span_bug!( + tcx.def_span(def.to_def_id()), + "from_anon_const can only process anonymous constants, not {node:?}" + ), + }; + + let expr = &tcx.hir().body(body_id).value; + debug!(?expr); + + let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic"); + + match self.try_lower_anon_const_lit(ty, expr) { + Some(v) => v, + None => ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst { + def: def.to_def_id(), + args: ty::GenericArgs::identity_for_item(tcx, def.to_def_id()), + }), + } + } + + #[instrument(skip(self), level = "debug")] + fn try_lower_anon_const_lit( + &self, + ty: Ty<'tcx>, + expr: &'tcx hir::Expr<'tcx>, + ) -> Option<Const<'tcx>> { + let tcx = self.tcx(); + + // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments + // currently have to be wrapped in curly brackets, so it's necessary to special-case. + let expr = match &expr.kind { + hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { + block.expr.as_ref().unwrap() + } + _ => expr, + }; + + if let hir::ExprKind::Path(hir::QPath::Resolved( + _, + &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. }, + )) = expr.kind + { + span_bug!( + expr.span, + "try_lower_anon_const_lit: received const param which shouldn't be possible" + ); + }; + + let lit_input = match expr.kind { + hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }), + hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind { + hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }), + _ => None, + }, + _ => None, + }; + + if let Some(lit_input) = lit_input { + // If an error occurred, ignore that it's a literal and leave reporting the error up to + // mir. + match tcx.at(expr.span).lit_to_const(lit_input) { + Ok(c) => return Some(c), + Err(_) if lit_input.ty.has_aliases() => { + // allow the `ty` to be an alias type, though we cannot handle it here + return None; + } + Err(e) => { + tcx.dcx().span_delayed_bug( + expr.span, + format!("try_lower_anon_const_lit: couldn't lit_to_const {e:?}"), + ); + } + } + } + + None + } + fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> { let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); match idx { diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 246643d8074..ee55e1bc21a 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -66,7 +66,6 @@ //! on traits with methods can. use rustc_data_structures::fx::FxHashSet; -use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::outlives::env::OutlivesEnvironment; @@ -134,7 +133,6 @@ fn check_always_applicable( unconstrained_parent_impl_args(tcx, impl2_def_id, impl2_args) }; - res = res.and(check_constness(tcx, impl1_def_id, impl2_node, span)); res = res.and(check_static_lifetimes(tcx, &parent_args, span)); res = res.and(check_duplicate_params(tcx, impl1_args, parent_args, span)); res = res.and(check_predicates(tcx, impl1_def_id, impl1_args, impl2_node, impl2_args, span)); @@ -157,30 +155,6 @@ fn check_has_items( Ok(()) } -/// Check that the specializing impl `impl1` is at least as const as the base -/// impl `impl2` -fn check_constness( - tcx: TyCtxt<'_>, - impl1_def_id: LocalDefId, - impl2_node: Node, - span: Span, -) -> Result<(), ErrorGuaranteed> { - if impl2_node.is_from_trait() { - // This isn't a specialization - return Ok(()); - } - - let impl1_constness = tcx.constness(impl1_def_id.to_def_id()); - let impl2_constness = tcx.constness(impl2_node.def_id()); - - if let hir::Constness::Const = impl2_constness { - if let hir::Constness::NotConst = impl1_constness { - return Err(tcx.dcx().emit_err(errors::ConstSpecialize { span })); - } - } - Ok(()) -} - /// Given a specializing impl `impl1`, and the base impl `impl2`, returns two /// generic parameters `(S1, S2)` that equate their trait references. /// The returned types are expressed in terms of the generics of `impl1`. diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 11864b61a94..0f3dcebc092 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -10,7 +10,7 @@ use std::cell::Cell; use std::vec; use rustc_abi::ExternAbi; -use rustc_ast::util::parser::{self, AssocOp, Fixity}; +use rustc_ast::util::parser::{self, AssocOp, ExprPrecedence, Fixity}; use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; use rustc_ast_pretty::pprust::{Comments, PrintState}; @@ -1125,12 +1125,12 @@ impl<'a> State<'a> { } fn print_expr_call(&mut self, func: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - let prec = match func.kind { - hir::ExprKind::Field(..) => parser::PREC_FORCE_PAREN, - _ => parser::PREC_UNAMBIGUOUS, + let needs_paren = match func.kind { + hir::ExprKind::Field(..) => true, + _ => func.precedence() < ExprPrecedence::Unambiguous, }; - self.print_expr_cond_paren(func, func.precedence() < prec); + self.print_expr_cond_paren(func, needs_paren); self.print_call_post(args) } @@ -1141,7 +1141,7 @@ impl<'a> State<'a> { args: &[hir::Expr<'_>], ) { let base_args = args; - self.print_expr_cond_paren(receiver, receiver.precedence() < parser::PREC_UNAMBIGUOUS); + self.print_expr_cond_paren(receiver, receiver.precedence() < ExprPrecedence::Unambiguous); self.word("."); self.print_ident(segment.ident); @@ -1155,37 +1155,38 @@ impl<'a> State<'a> { fn print_expr_binary(&mut self, op: hir::BinOp, lhs: &hir::Expr<'_>, rhs: &hir::Expr<'_>) { let assoc_op = AssocOp::from_ast_binop(op.node); - let prec = assoc_op.precedence() as i8; - let fixity = assoc_op.fixity(); - - let (left_prec, right_prec) = match fixity { - Fixity::Left => (prec, prec + 1), - Fixity::Right => (prec + 1, prec), - Fixity::None => (prec + 1, prec + 1), + let binop_prec = assoc_op.precedence(); + let left_prec = lhs.precedence(); + let right_prec = rhs.precedence(); + + let (mut left_needs_paren, right_needs_paren) = match assoc_op.fixity() { + Fixity::Left => (left_prec < binop_prec, right_prec <= binop_prec), + Fixity::Right => (left_prec <= binop_prec, right_prec < binop_prec), + Fixity::None => (left_prec <= binop_prec, right_prec <= binop_prec), }; - let left_prec = match (&lhs.kind, op.node) { + match (&lhs.kind, op.node) { // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead // of `(x as i32) < ...`. We need to convince it _not_ to do that. (&hir::ExprKind::Cast { .. }, hir::BinOpKind::Lt | hir::BinOpKind::Shl) => { - parser::PREC_FORCE_PAREN + left_needs_paren = true; } - (&hir::ExprKind::Let { .. }, _) if !parser::needs_par_as_let_scrutinee(prec) => { - parser::PREC_FORCE_PAREN + (&hir::ExprKind::Let { .. }, _) if !parser::needs_par_as_let_scrutinee(binop_prec) => { + left_needs_paren = true; } - _ => left_prec, - }; + _ => {} + } - self.print_expr_cond_paren(lhs, lhs.precedence() < left_prec); + self.print_expr_cond_paren(lhs, left_needs_paren); self.space(); self.word_space(op.node.as_str()); - self.print_expr_cond_paren(rhs, rhs.precedence() < right_prec) + self.print_expr_cond_paren(rhs, right_needs_paren); } fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr<'_>) { self.word(op.as_str()); - self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_PREFIX) + self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Prefix); } fn print_expr_addr_of( @@ -1202,7 +1203,7 @@ impl<'a> State<'a> { self.print_mutability(mutability, true); } } - self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_PREFIX) + self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Prefix); } fn print_literal(&mut self, lit: &hir::Lit) { @@ -1340,8 +1341,7 @@ impl<'a> State<'a> { self.print_literal(lit); } hir::ExprKind::Cast(expr, ty) => { - let prec = AssocOp::As.precedence() as i8; - self.print_expr_cond_paren(expr, expr.precedence() < prec); + self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Cast); self.space(); self.word_space("as"); self.print_type(ty); @@ -1442,27 +1442,25 @@ impl<'a> State<'a> { self.print_block(blk); } hir::ExprKind::Assign(lhs, rhs, _) => { - let prec = AssocOp::Assign.precedence() as i8; - self.print_expr_cond_paren(lhs, lhs.precedence() <= prec); + self.print_expr_cond_paren(lhs, lhs.precedence() <= ExprPrecedence::Assign); self.space(); self.word_space("="); - self.print_expr_cond_paren(rhs, rhs.precedence() < prec); + self.print_expr_cond_paren(rhs, rhs.precedence() < ExprPrecedence::Assign); } hir::ExprKind::AssignOp(op, lhs, rhs) => { - let prec = AssocOp::Assign.precedence() as i8; - self.print_expr_cond_paren(lhs, lhs.precedence() <= prec); + self.print_expr_cond_paren(lhs, lhs.precedence() <= ExprPrecedence::Assign); self.space(); self.word(op.node.as_str()); self.word_space("="); - self.print_expr_cond_paren(rhs, rhs.precedence() < prec); + self.print_expr_cond_paren(rhs, rhs.precedence() < ExprPrecedence::Assign); } hir::ExprKind::Field(expr, ident) => { - self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_UNAMBIGUOUS); + self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Unambiguous); self.word("."); self.print_ident(ident); } hir::ExprKind::Index(expr, index, _) => { - self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_UNAMBIGUOUS); + self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Unambiguous); self.word("["); self.print_expr(index); self.word("]"); @@ -1476,7 +1474,7 @@ impl<'a> State<'a> { } if let Some(expr) = opt_expr { self.space(); - self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_JUMP); + self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Jump); } } hir::ExprKind::Continue(destination) => { @@ -1490,13 +1488,13 @@ impl<'a> State<'a> { self.word("return"); if let Some(expr) = result { self.word(" "); - self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_JUMP); + self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Jump); } } hir::ExprKind::Become(result) => { self.word("become"); self.word(" "); - self.print_expr_cond_paren(result, result.precedence() < parser::PREC_JUMP); + self.print_expr_cond_paren(result, result.precedence() < ExprPrecedence::Jump); } hir::ExprKind::InlineAsm(asm) => { self.word("asm!"); @@ -1521,7 +1519,7 @@ impl<'a> State<'a> { } hir::ExprKind::Yield(expr, _) => { self.word_space("yield"); - self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_JUMP); + self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Jump); } hir::ExprKind::Err(_) => { self.popen(); diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index b0afbab8e01..b430f48965a 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -1,6 +1,6 @@ use std::iter; -use rustc_ast::util::parser::PREC_UNAMBIGUOUS; +use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey}; use rustc_hir::def::{self, CtorKind, Namespace, Res}; use rustc_hir::def_id::DefId; @@ -606,7 +606,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if let Ok(rest_snippet) = rest_snippet { - let sugg = if callee_expr.precedence() >= PREC_UNAMBIGUOUS { + let sugg = if callee_expr.precedence() >= ExprPrecedence::Unambiguous { vec![ (up_to_rcvr_span, "".to_string()), (rest_span, format!(".{}({rest_snippet}", segment.ident)), diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 0c3f21d540d..80b91c21598 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -28,6 +28,7 @@ //! expression, `e as U2` is not necessarily so (in fact it will only be valid if //! `U1` coerces to `U2`). +use rustc_ast::util::parser::ExprPrecedence; use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, ErrorGuaranteed}; @@ -1108,7 +1109,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) { let expr_prec = self.expr.precedence(); - let needs_parens = expr_prec < rustc_ast::util::parser::PREC_UNAMBIGUOUS; + let needs_parens = expr_prec < ExprPrecedence::Unambiguous; let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize)); let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span); diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 2a00530c434..774d00edea0 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -228,7 +228,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) { } fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { - ty.is_copy_modulo_regions(self.0.tcx, self.0.typing_env()) + self.0.type_is_copy_modulo_regions(ty) } fn body_owner_def_id(&self) -> LocalDefId { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 3940d138deb..aacdcf027b6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -307,7 +307,11 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _) if !ty.has_escaping_bound_vars() => { - self.normalize(span, ty).ty_adt_def() + if self.next_trait_solver() { + self.try_structurally_resolve_type(span, ty).ty_adt_def() + } else { + self.normalize(span, ty).ty_adt_def() + } } _ => None, } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index b493a61b9f4..61260dbd16c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2,7 +2,7 @@ use core::cmp::min; use core::iter; use hir::def_id::LocalDefId; -use rustc_ast::util::parser::PREC_UNAMBIGUOUS; +use rustc_ast::util::parser::ExprPrecedence; use rustc_data_structures::packed::Pu128; use rustc_errors::{Applicability, Diag, MultiSpan}; use rustc_hir as hir; @@ -398,7 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // so we remove the user's `clone` call. { vec![(receiver_method.ident.span, conversion_method.name.to_string())] - } else if expr.precedence() < PREC_UNAMBIGUOUS { + } else if expr.precedence() < ExprPrecedence::Unambiguous { vec![ (expr.span.shrink_to_lo(), "(".to_string()), (expr.span.shrink_to_hi(), format!(").{}()", conversion_method.name)), @@ -1376,7 +1376,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let span = expr.span.find_oldest_ancestor_in_same_ctxt(); - let mut sugg = if expr.precedence() >= PREC_UNAMBIGUOUS { + let mut sugg = if expr.precedence() >= ExprPrecedence::Unambiguous { vec![(span.shrink_to_hi(), ".into()".to_owned())] } else { vec![ @@ -3000,7 +3000,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`", ); - let close_paren = if expr.precedence() < PREC_UNAMBIGUOUS { + let close_paren = if expr.precedence() < ExprPrecedence::Unambiguous { sugg.push((expr.span.shrink_to_lo(), "(".to_string())); ")" } else { @@ -3025,7 +3025,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let len = src.trim_end_matches(&checked_ty.to_string()).len(); expr.span.with_lo(expr.span.lo() + BytePos(len as u32)) }, - if expr.precedence() < PREC_UNAMBIGUOUS { + if expr.precedence() < ExprPrecedence::Unambiguous { // Readd `)` format!("{expected_ty})") } else { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index cff2aa68993..6b1a288510a 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -664,7 +664,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| { tcx.is_diagnostic_item(sym::write_macro, def_id) || tcx.is_diagnostic_item(sym::writeln_macro, def_id) - }) && item_name.name == Symbol::intern("write_fmt"); + }) && item_name.name == sym::write_fmt; let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source { self.suggest_missing_writer(rcvr_ty, rcvr_expr) } else { diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index ba1516655b0..51282b900ed 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -84,6 +84,8 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx { self.collect_remaining_errors(infcx) } + fn has_pending_obligations(&self) -> bool; + fn pending_obligations(&self) -> PredicateObligations<'tcx>; /// Among all pending obligations, collect those are stalled on a inference variable which has diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 2905fe688b5..d42915f4110 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -54,10 +54,6 @@ pub(crate) fn parse<'a>(sess: &'a Session) -> Result<ast::Crate> { }) .map_err(|parse_error| parse_error.emit())?; - if let Some(ref s) = sess.opts.unstable_opts.show_span { - rustc_ast_passes::show_span::run(sess.dcx(), s, &krate); - } - if sess.opts.unstable_opts.input_stats { input_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS", "ast-stats-1"); } @@ -830,7 +826,6 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { tcx.ensure().check_mod_attrs(module); tcx.ensure().check_mod_naked_functions(module); tcx.ensure().check_mod_unstable_api_usage(module); - tcx.ensure().check_mod_const_bodies(module); }); }, { diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index c1b2d856252..3c4d9c2e928 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -771,6 +771,7 @@ fn test_unstable_options_tracking_hash() { tracked!(crate_attr, vec!["abc".to_string()]); tracked!(cross_crate_inline_threshold, InliningThreshold::Always); tracked!(debug_info_for_profiling, true); + tracked!(debug_info_type_line_numbers, true); tracked!(default_visibility, Some(rustc_target::spec::SymbolVisibility::Hidden)); tracked!(dep_info_omit_d_target, true); tracked!(direct_access_external_data, Some(true)); @@ -843,7 +844,6 @@ fn test_unstable_options_tracking_hash() { tracked!(sanitizer_recover, SanitizerSet::ADDRESS); tracked!(saturating_float_casts, Some(true)); tracked!(share_generics, Some(true)); - tracked!(show_span, Some(String::from("abc"))); tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc"))); tracked!(small_data_threshold, Some(16)); tracked!(split_lto_unit, Some(true)); diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 4aeaf616816..49e6b763590 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -775,6 +775,9 @@ lint_suspicious_double_ref_clone = lint_suspicious_double_ref_deref = using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type +lint_symbol_intern_string_literal = using `Symbol::intern` on a string literal + .help = consider adding the symbol to `compiler/rustc_span/src/symbol.rs` + lint_trailing_semi_macro = trailing semicolon in macro used in expression position .note1 = macro invocations at the end of a block are treated as expressions .note2 = to ignore the value produced by the macro, add a semicolon after the invocation of `{$name}` @@ -882,6 +885,12 @@ lint_unnameable_test_items = cannot test inner items lint_unnecessary_qualification = unnecessary qualification .suggestion = remove the unnecessary path segments +lint_unpredictable_fn_pointer_comparisons = function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + .note_duplicated_fn = the address of the same function can vary between different codegen units + .note_deduplicated_fn = furthermore, different functions could have the same address after being merged together + .note_visit_fn_addr_eq = for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> + .fn_addr_eq_suggestion = refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + lint_unqualified_local_imports = `use` of a local item without leading `self::`, `super::`, or `crate::` lint_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index e130cfc1d73..ec085198922 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -586,7 +586,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { return; } } - if ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()) { + if cx.type_is_copy_modulo_regions(ty) { return; } if type_implements_negative_copy_modulo_regions(cx.tcx, ty, cx.typing_env()) { diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 7248b192763..44c7888a530 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -710,6 +710,10 @@ impl<'tcx> LateContext<'tcx> { TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env } } + pub fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { + self.tcx.type_is_copy_modulo_regions(self.typing_env(), ty) + } + /// Gets the type-checking results for the current body, /// or `None` if outside a body. pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> { diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 8fe86738658..ce23892508b 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -144,7 +144,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { && let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id) { let arg_ty = cx.typeck_results().expr_ty(arg); - let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()); + let is_copy = cx.type_is_copy_modulo_regions(arg_ty); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); let let_underscore_ignore_sugg = || { if let Some((_, node)) = cx.tcx.hir().parent_iter(expr.hir_id).nth(0) diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 0e874669043..2db229ed133 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -103,8 +103,11 @@ fn expr_parent_is_else(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { } fn expr_parent_is_stmt(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { - let Some((_, hir::Node::Stmt(stmt))) = tcx.hir().parent_iter(hir_id).next() else { - return false; + let mut parents = tcx.hir().parent_iter(hir_id); + let stmt = match parents.next() { + Some((_, hir::Node::Stmt(stmt))) => stmt, + Some((_, hir::Node::Block(_) | hir::Node::Arm(_))) => return true, + _ => return false, }; let (hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr)) = stmt.kind else { return false }; expr.hir_id == hir_id diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 38c38b59bc5..482650e04e8 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -17,8 +17,9 @@ use tracing::debug; use crate::lints::{ BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword, - NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag, TyQualified, - TykindDiag, TykindKind, TypeIrInherentUsage, UntranslatableDiag, + NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag, + SymbolInternStringLiteralDiag, TyQualified, TykindDiag, TykindKind, TypeIrInherentUsage, + UntranslatableDiag, }; use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; @@ -242,17 +243,10 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option<String> { } // Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait. Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => { - if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() { - if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did()) - { - // NOTE: This path is currently unreachable as `Ty<'tcx>` is - // defined as a type alias meaning that `impl<'tcx> Ty<'tcx>` - // is not actually allowed. - // - // I(@lcnr) still kept this branch in so we don't miss this - // if we ever change it in the future. - return Some(format!("{}<{}>", name, args[0])); - } + if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() + && let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did()) + { + return Some(format!("{}<{}>", name, args[0])); } } _ => (), @@ -657,3 +651,33 @@ fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { _ => false, } } + +declare_tool_lint! { + /// The `symbol_intern_string_literal` detects `Symbol::intern` being called on a string literal + pub rustc::SYMBOL_INTERN_STRING_LITERAL, + // rustc_driver crates out of the compiler can't/shouldn't add preinterned symbols; + // bootstrap will deny this manually + Allow, + "Forbid uses of string literals in `Symbol::intern`, suggesting preinterning instead", + report_in_external_macro: true +} + +declare_lint_pass!(SymbolInternStringLiteral => [SYMBOL_INTERN_STRING_LITERAL]); + +impl<'tcx> LateLintPass<'tcx> for SymbolInternStringLiteral { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) { + if let ExprKind::Call(path, [arg]) = expr.kind + && let ExprKind::Path(ref qpath) = path.kind + && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() + && cx.tcx.is_diagnostic_item(sym::SymbolIntern, def_id) + && let ExprKind::Lit(kind) = arg.kind + && let rustc_ast::LitKind::Str(_, _) = kind.node + { + cx.emit_span_lint( + SYMBOL_INTERN_STRING_LITERAL, + kind.span, + SymbolInternStringLiteralDiag, + ); + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 4cf5c7b4ff9..a99c94592b3 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -614,6 +614,8 @@ fn register_internals(store: &mut LintStore) { store.register_late_mod_pass(|_| Box::new(PassByValue)); store.register_lints(&SpanUseEqCtxt::lint_vec()); store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt)); + store.register_lints(&SymbolInternStringLiteral::lint_vec()); + store.register_late_mod_pass(|_| Box::new(SymbolInternStringLiteral)); // FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and // `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and // these lints will trigger all of the time - change this once migration to diagnostic structs diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 3a854796f67..20822f23bf1 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -908,6 +908,11 @@ pub(crate) struct QueryUntracked { pub(crate) struct SpanUseEqCtxtDiag; #[derive(LintDiagnostic)] +#[diag(lint_symbol_intern_string_literal)] +#[help] +pub(crate) struct SymbolInternStringLiteralDiag; + +#[derive(LintDiagnostic)] #[diag(lint_tykind_kind)] pub(crate) struct TykindKind { #[suggestion(code = "ty", applicability = "maybe-incorrect")] @@ -1810,6 +1815,42 @@ pub(crate) enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> { }, } +#[derive(LintDiagnostic)] +pub(crate) enum UnpredictableFunctionPointerComparisons<'a> { + #[diag(lint_unpredictable_fn_pointer_comparisons)] + #[note(lint_note_duplicated_fn)] + #[note(lint_note_deduplicated_fn)] + #[note(lint_note_visit_fn_addr_eq)] + Suggestion { + #[subdiagnostic] + sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a>, + }, + #[diag(lint_unpredictable_fn_pointer_comparisons)] + #[note(lint_note_duplicated_fn)] + #[note(lint_note_deduplicated_fn)] + #[note(lint_note_visit_fn_addr_eq)] + Warn, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + lint_fn_addr_eq_suggestion, + style = "verbose", + applicability = "maybe-incorrect" +)] +pub(crate) struct UnpredictableFunctionPointerComparisonsSuggestion<'a> { + pub ne: &'a str, + pub cast_right: String, + pub deref_left: &'a str, + pub deref_right: &'a str, + #[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")] + pub left: Span, + #[suggestion_part(code = ", {deref_right}")] + pub middle: Span, + #[suggestion_part(code = "{cast_right})")] + pub right: Span, +} + pub(crate) struct ImproperCTypes<'a> { pub ty: Ty<'a>, pub desc: &'a str, diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index b1d7d4ab689..33650be056d 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -23,7 +23,9 @@ use crate::lints::{ AmbiguousWidePointerComparisons, AmbiguousWidePointerComparisonsAddrMetadataSuggestion, AmbiguousWidePointerComparisonsAddrSuggestion, AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, InvalidNanComparisons, - InvalidNanComparisonsSuggestion, UnusedComparisons, VariantSizeDifferencesDiag, + InvalidNanComparisonsSuggestion, UnpredictableFunctionPointerComparisons, + UnpredictableFunctionPointerComparisonsSuggestion, UnusedComparisons, + VariantSizeDifferencesDiag, }; use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent}; @@ -166,6 +168,35 @@ declare_lint! { "detects ambiguous wide pointer comparisons" } +declare_lint! { + /// The `unpredictable_function_pointer_comparisons` lint checks comparison + /// of function pointer as the operands. + /// + /// ### Example + /// + /// ```rust + /// fn a() {} + /// fn b() {} + /// + /// let f: fn() = a; + /// let g: fn() = b; + /// + /// let _ = f == g; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Function pointers comparisons do not produce meaningful result since + /// they are never guaranteed to be unique and could vary between different + /// code generation units. Furthermore, different functions could have the + /// same address after being merged together. + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, + Warn, + "detects unpredictable function pointer comparisons" +} + #[derive(Copy, Clone, Default)] pub(crate) struct TypeLimits { /// Id of the last visited negated expression @@ -178,7 +209,8 @@ impl_lint_pass!(TypeLimits => [ UNUSED_COMPARISONS, OVERFLOWING_LITERALS, INVALID_NAN_COMPARISONS, - AMBIGUOUS_WIDE_POINTER_COMPARISONS + AMBIGUOUS_WIDE_POINTER_COMPARISONS, + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS ]); impl TypeLimits { @@ -255,7 +287,7 @@ fn lint_nan<'tcx>( cx.emit_span_lint(INVALID_NAN_COMPARISONS, e.span, lint); } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Copy, Clone)] enum ComparisonOp { BinOp(hir::BinOpKind), Other, @@ -383,6 +415,100 @@ fn lint_wide_pointer<'tcx>( ); } +fn lint_fn_pointer<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx hir::Expr<'tcx>, + cmpop: ComparisonOp, + l: &'tcx hir::Expr<'tcx>, + r: &'tcx hir::Expr<'tcx>, +) { + let peel_refs = |mut ty: Ty<'tcx>| -> (Ty<'tcx>, usize) { + let mut refs = 0; + + while let ty::Ref(_, inner_ty, _) = ty.kind() { + ty = *inner_ty; + refs += 1; + } + + (ty, refs) + }; + + // Left and right operands can have borrows, remove them + let l = l.peel_borrows(); + let r = r.peel_borrows(); + + let Some(l_ty) = cx.typeck_results().expr_ty_opt(l) else { return }; + let Some(r_ty) = cx.typeck_results().expr_ty_opt(r) else { return }; + + // Remove any references as `==` will deref through them (and count the + // number of references removed, for latter). + let (l_ty, l_ty_refs) = peel_refs(l_ty); + let (r_ty, r_ty_refs) = peel_refs(r_ty); + + if !l_ty.is_fn() || !r_ty.is_fn() { + return; + } + + // Let's try to suggest `ptr::fn_addr_eq` if/when possible. + + let is_eq_ne = matches!(cmpop, ComparisonOp::BinOp(hir::BinOpKind::Eq | hir::BinOpKind::Ne)); + + if !is_eq_ne { + // Neither `==` nor `!=`, we can't suggest `ptr::fn_addr_eq`, just show the warning. + return cx.emit_span_lint( + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, + e.span, + UnpredictableFunctionPointerComparisons::Warn, + ); + } + + let (Some(l_span), Some(r_span)) = + (l.span.find_ancestor_inside(e.span), r.span.find_ancestor_inside(e.span)) + else { + // No appropriate spans for the left and right operands, just show the warning. + return cx.emit_span_lint( + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, + e.span, + UnpredictableFunctionPointerComparisons::Warn, + ); + }; + + let ne = if cmpop == ComparisonOp::BinOp(hir::BinOpKind::Ne) { "!" } else { "" }; + + // `ptr::fn_addr_eq` only works with raw pointer, deref any references. + let deref_left = &*"*".repeat(l_ty_refs); + let deref_right = &*"*".repeat(r_ty_refs); + + let left = e.span.shrink_to_lo().until(l_span.shrink_to_lo()); + let middle = l_span.shrink_to_hi().until(r_span.shrink_to_lo()); + let right = r_span.shrink_to_hi().until(e.span.shrink_to_hi()); + + // We only check for a right cast as `FnDef` == `FnPtr` is not possible, + // only `FnPtr == FnDef` is possible. + let cast_right = if !r_ty.is_fn_ptr() { + let fn_sig = r_ty.fn_sig(cx.tcx); + format!(" as {fn_sig}") + } else { + String::new() + }; + + cx.emit_span_lint( + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, + e.span, + UnpredictableFunctionPointerComparisons::Suggestion { + sugg: UnpredictableFunctionPointerComparisonsSuggestion { + ne, + deref_left, + deref_right, + left, + middle, + right, + cast_right, + }, + }, + ); +} + impl<'tcx> LateLintPass<'tcx> for TypeLimits { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx hir::Expr<'tcx>) { match e.kind { @@ -399,7 +525,9 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons); } else { lint_nan(cx, e, binop, l, r); - lint_wide_pointer(cx, e, ComparisonOp::BinOp(binop.node), l, r); + let cmpop = ComparisonOp::BinOp(binop.node); + lint_wide_pointer(cx, e, cmpop, l, r); + lint_fn_pointer(cx, e, cmpop, l, r); } } } @@ -411,6 +539,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { && let Some(cmpop) = diag_item_cmpop(diag_item) => { lint_wide_pointer(cx, e, cmpop, l, r); + lint_fn_pointer(cx, e, cmpop, l, r); } hir::ExprKind::MethodCall(_, l, [r], _) if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) @@ -418,6 +547,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { && let Some(cmpop) = diag_item_cmpop(diag_item) => { lint_wide_pointer(cx, e, cmpop, l, r); + lint_fn_pointer(cx, e, cmpop, l, r); } _ => {} }; diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index e1a0e1ec579..b775cd37409 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1563,7 +1563,7 @@ impl UnusedImportBraces { } rename.unwrap_or(orig_ident).name } - ast::UseTreeKind::Glob => Symbol::intern("*"), + ast::UseTreeKind::Glob => sym::asterisk, ast::UseTreeKind::Nested { .. } => return, }; diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 3b406c7e161..d2b7ae620e2 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -179,7 +179,7 @@ declare_lint! { Warn, "applying forbid to lint-groups", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, reference: "issue #81670 <https://github.com/rust-lang/rust/issues/81670>", }; } diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index a18c6baec00..29dba2bca61 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -861,8 +861,10 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { // First up we check for global allocators. Look at the crate graph here // and see what's a global allocator, including if we ourselves are a // global allocator. - let mut global_allocator = - self.cstore.has_global_allocator.then(|| Symbol::intern("this crate")); + #[cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))] + let this_crate = Symbol::intern("this crate"); + + let mut global_allocator = self.cstore.has_global_allocator.then_some(this_crate); for (_, data) in self.cstore.iter_crate_data() { if data.has_global_allocator() { match global_allocator { @@ -876,8 +878,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } } } - let mut alloc_error_handler = - self.cstore.has_alloc_error_handler.then(|| Symbol::intern("this crate")); + let mut alloc_error_handler = self.cstore.has_alloc_error_handler.then_some(this_crate); for (_, data) in self.cstore.iter_crate_data() { if data.has_alloc_error_handler() { match alloc_error_handler { diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 56beff5aa64..f3f5af49412 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -872,6 +872,7 @@ impl MetadataBlob { let def_kind = root.tables.def_kind.get(blob, item).unwrap(); let def_key = root.tables.def_keys.get(blob, item).unwrap().decode(blob); + #[cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))] let def_name = if item == CRATE_DEF_INDEX { rustc_span::symbol::kw::Crate } else { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 068a5d31a8e..a34ea18f716 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1389,10 +1389,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // `ConstArgKind::Path`. We never actually access this `DefId` // anywhere so we don't need to encode it for other crates. if def_kind == DefKind::AnonConst - && matches!( - tcx.hir_node_by_def_id(local_id), - hir::Node::ConstArg(hir::ConstArg { kind: hir::ConstArgKind::Path(..), .. }) - ) + && match tcx.hir_node_by_def_id(local_id) { + hir::Node::ConstArg(hir::ConstArg { kind, .. }) => match kind { + // Skip encoding defs for these as they should not have had a `DefId` created + hir::ConstArgKind::Path(..) | hir::ConstArgKind::Infer(..) => true, + hir::ConstArgKind::Anon(..) => false, + }, + _ => false, + } { continue; } diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 9438350ca09..28f406fbc96 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -1,6 +1,5 @@ use rustc_hir::def::CtorOf; use rustc_index::Idx; -use tracing::trace; use crate::rmeta::*; @@ -530,8 +529,6 @@ where { /// Given the metadata, extract out the value at a particular index (if any). pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(&self, metadata: M, i: I) -> T::Value<'tcx> { - trace!("LazyTable::lookup: index={:?} len={:?}", i, self.len); - // Access past the end of the table returns a Default if i.index() >= self.len { return Default::default(); diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 08afa33c6b4..ad5d678178d 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -46,7 +46,7 @@ impl ErrorHandled { pub fn emit_note(&self, tcx: TyCtxt<'_>) { match self { &ErrorHandled::Reported(err, span) => { - if !err.is_tainted_by_errors && !span.is_dummy() { + if !err.allowed_in_infallible && !span.is_dummy() { tcx.dcx().emit_note(error::ErroneousConstant { span }); } } @@ -58,34 +58,26 @@ impl ErrorHandled { #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] pub struct ReportedErrorInfo { error: ErrorGuaranteed, - is_tainted_by_errors: bool, - /// Whether this is the kind of error that can sometimes occur, and sometimes not. - /// Used for resource exhaustion errors. - can_be_spurious: bool, + /// Whether this error is allowed to show up even in otherwise "infallible" promoteds. + /// This is for things like overflows during size computation or resource exhaustion. + allowed_in_infallible: bool, } impl ReportedErrorInfo { #[inline] - pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo { - ReportedErrorInfo { is_tainted_by_errors: true, can_be_spurious: false, error } - } - #[inline] - pub fn spurious(error: ErrorGuaranteed) -> ReportedErrorInfo { - ReportedErrorInfo { can_be_spurious: true, is_tainted_by_errors: false, error } + pub fn allowed_in_infallible(error: ErrorGuaranteed) -> ReportedErrorInfo { + ReportedErrorInfo { allowed_in_infallible: true, error } } - pub fn is_tainted_by_errors(&self) -> bool { - self.is_tainted_by_errors - } - pub fn can_be_spurious(&self) -> bool { - self.can_be_spurious + pub fn is_allowed_in_infallible(&self) -> bool { + self.allowed_in_infallible } } impl From<ErrorGuaranteed> for ReportedErrorInfo { #[inline] fn from(error: ErrorGuaranteed) -> ReportedErrorInfo { - ReportedErrorInfo { is_tainted_by_errors: false, can_be_spurious: false, error } + ReportedErrorInfo { allowed_in_infallible: false, error } } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index a17aa9ecc04..df110fdc20a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -958,11 +958,6 @@ rustc_queries! { desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) } } - /// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`). - query check_mod_const_bodies(key: LocalModDefId) { - desc { |tcx| "checking consts in {}", describe_as_module(key, tcx) } - } - /// Checks the loops in the module. query check_mod_loops(key: LocalModDefId) { desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) } @@ -1086,6 +1081,8 @@ rustc_queries! { } /// Computes the tag (if any) for a given type and variant. + /// `None` means that the variant doesn't need a tag (because it is niched). + /// Will panic for uninhabited variants. query tag_for_variant( key: (Ty<'tcx>, abi::VariantIdx) ) -> Option<ty::ScalarInt> { diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index d27205e26ab..31055276422 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -2,15 +2,11 @@ use std::borrow::Cow; use rustc_data_structures::intern::Interned; use rustc_error_messages::MultiSpan; -use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::LocalDefId; -use rustc_hir::{self as hir}; use rustc_macros::HashStable; use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo}; -use tracing::{debug, instrument}; -use crate::mir::interpret::{LitToConstInput, Scalar}; -use crate::ty::{self, GenericArgs, Ty, TyCtxt, TypeVisitableExt}; +use crate::mir::interpret::Scalar; +use crate::ty::{self, Ty, TyCtxt}; mod int; mod kind; @@ -181,82 +177,6 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> { } impl<'tcx> Const<'tcx> { - // FIXME: move this and try_from_lit to hir_ty_lowering like lower_const_arg/from_const_arg - /// Literals and const generic parameters are eagerly converted to a constant, everything else - /// becomes `Unevaluated`. - #[instrument(skip(tcx), level = "debug")] - pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self { - let body_id = match tcx.hir_node_by_def_id(def) { - hir::Node::AnonConst(ac) => ac.body, - node => span_bug!( - tcx.def_span(def.to_def_id()), - "from_anon_const can only process anonymous constants, not {node:?}" - ), - }; - - let expr = &tcx.hir().body(body_id).value; - debug!(?expr); - - let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic"); - - match Self::try_from_lit(tcx, ty, expr) { - Some(v) => v, - None => ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst { - def: def.to_def_id(), - args: GenericArgs::identity_for_item(tcx, def.to_def_id()), - }), - } - } - - #[instrument(skip(tcx), level = "debug")] - fn try_from_lit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) -> Option<Self> { - // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments - // currently have to be wrapped in curly brackets, so it's necessary to special-case. - let expr = match &expr.kind { - hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { - block.expr.as_ref().unwrap() - } - _ => expr, - }; - - if let hir::ExprKind::Path(hir::QPath::Resolved( - _, - &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. }, - )) = expr.kind - { - span_bug!(expr.span, "try_from_lit: received const param which shouldn't be possible"); - }; - - let lit_input = match expr.kind { - hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }), - hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind { - hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }), - _ => None, - }, - _ => None, - }; - - if let Some(lit_input) = lit_input { - // If an error occurred, ignore that it's a literal and leave reporting the error up to - // mir. - match tcx.at(expr.span).lit_to_const(lit_input) { - Ok(c) => return Some(c), - Err(_) if lit_input.ty.has_aliases() => { - // allow the `ty` to be an alias type, though we cannot handle it here - return None; - } - Err(e) => { - tcx.dcx().span_delayed_bug( - expr.span, - format!("Const::try_from_lit: couldn't lit_to_const {e:?}"), - ); - } - } - } - - None - } - /// Creates a constant with the given integer value and interns it. #[inline] pub fn from_bits( diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 797ac9685b1..57054bd1a0b 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -172,6 +172,24 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Checks whether `ty: Copy` holds while ignoring region constraints. + /// + /// This impacts whether values of `ty` are *moved* or *copied* + /// when referenced. This means that we may generate MIR which + /// does copies even when the type actually doesn't satisfy the + /// full requirements for the `Copy` trait (cc #29149) -- this + /// winds up being reported as an error during NLL borrow check. + /// + /// This function should not be used if there is an `InferCtxt` available. + /// Use `InferCtxt::type_is_copy_modulo_regions` instead. + pub fn type_is_copy_modulo_regions( + self, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, + ) -> bool { + ty.is_trivially_pure_clone_copy() || self.is_copy_raw(typing_env.as_query_input(ty)) + } + /// Returns the deeply last field of nested structures, or the same type if /// not a structure at all. Corresponds to the only possible unsized field, /// and its type can be used to determine unsizing strategy. @@ -1174,21 +1192,6 @@ impl<'tcx> Ty<'tcx> { .map(|(min, _)| ty::Const::from_bits(tcx, min, typing_env, self)) } - /// Checks whether values of this type `T` are *moved* or *copied* - /// when referenced -- this amounts to a check for whether `T: - /// Copy`, but note that we **don't** consider lifetimes when - /// doing this check. This means that we may generate MIR which - /// does copies even when the type actually doesn't satisfy the - /// full requirements for the `Copy` trait (cc #29149) -- this - /// winds up being reported as an error during NLL borrow check. - pub fn is_copy_modulo_regions( - self, - tcx: TyCtxt<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - ) -> bool { - self.is_trivially_pure_clone_copy() || tcx.is_copy_raw(typing_env.as_query_input(self)) - } - /// Checks whether values of this type `T` have a size known at /// compile time (i.e., whether `T: Sized`). Lifetimes are ignored /// for the purposes of this check, so it can be an diff --git a/compiler/rustc_middle/src/util/call_kind.rs b/compiler/rustc_middle/src/util/call_kind.rs index acfb78b3f6e..df5b73ac1bd 100644 --- a/compiler/rustc_middle/src/util/call_kind.rs +++ b/compiler/rustc_middle/src/util/call_kind.rs @@ -14,6 +14,8 @@ use crate::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, Typing pub enum CallDesugaringKind { /// for _ in x {} calls x.into_iter() ForLoopIntoIter, + /// for _ in x {} calls iter.next() + ForLoopNext, /// x? calls x.branch() QuestionBranch, /// x? calls type_of(x)::from_residual() @@ -28,6 +30,7 @@ impl CallDesugaringKind { pub fn trait_def_id(self, tcx: TyCtxt<'_>) -> DefId { match self { Self::ForLoopIntoIter => tcx.get_diagnostic_item(sym::IntoIterator).unwrap(), + Self::ForLoopNext => tcx.require_lang_item(LangItem::Iterator, None), Self::QuestionBranch | Self::TryBlockFromOutput => { tcx.require_lang_item(LangItem::Try, None) } @@ -121,6 +124,10 @@ pub fn call_kind<'tcx>( && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) { Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0))) + } else if tcx.is_lang_item(method_did, LangItem::IteratorNext) + && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) + { + Some((CallDesugaringKind::ForLoopNext, method_args.type_at(0))) } else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) { if tcx.is_lang_item(method_did, LangItem::TryTraitBranch) { Some((CallDesugaringKind::QuestionBranch, method_args.type_at(0))) diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index f28cf84fa69..f647486f62a 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -84,12 +84,17 @@ mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable -mir_build_const_param_in_pattern = const parameters cannot be referenced in patterns +mir_build_const_defined_here = constant defined here -mir_build_const_pattern_depends_on_generic_parameter = - constant pattern depends on a generic parameter +mir_build_const_param_in_pattern = constant parameters cannot be referenced in patterns + .label = can't be used in patterns +mir_build_const_param_in_pattern_def = constant defined here + +mir_build_const_pattern_depends_on_generic_parameter = constant pattern cannot depend on generic parameters + .label = `const` depends on a generic parameter mir_build_could_not_eval_const_pattern = could not evaluate constant pattern + .label = could not evaluate constant mir_build_deref_raw_pointer_requires_unsafe = dereference of raw pointer is unsafe and requires unsafe block @@ -147,7 +152,8 @@ mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = mir_build_interpreted_as_const = introduce a variable instead -mir_build_invalid_pattern = `{$non_sm_ty}` cannot be used in patterns +mir_build_invalid_pattern = {$prefix} `{$non_sm_ty}` cannot be used in patterns + .label = {$prefix} can't be used in patterns mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count -> [one] pattern @@ -244,10 +250,12 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa .label = mutation of layout constrained field mir_build_nan_pattern = cannot use NaN in patterns + .label = evaluates to `NaN`, which is not allowed in patterns .note = NaNs compare inequal to everything, even themselves, so this pattern would never match .help = try using the `is_nan` method instead mir_build_non_const_path = runtime values cannot be referenced in patterns + .label = references a runtime value mir_build_non_empty_never_pattern = mismatched types @@ -265,13 +273,15 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type .suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown .help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern -mir_build_non_partial_eq_match = - to use a constant of type `{$non_peq_ty}` in a pattern, the type must implement `PartialEq` +mir_build_non_partial_eq_match = constant of non-structural type `{$ty}` in a pattern + .label = constant of non-structural type mir_build_pattern_not_covered = refutable pattern in {$origin} .pattern_ty = the matched value is of type `{$pattern_ty}` -mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon + .label = can't be used in patterns + .note = see https://github.com/rust-lang/rust/issues/70861 for details mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future @@ -283,6 +293,8 @@ mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly .missing_box = `#[rustc_box]` requires the `owned_box` lang item mir_build_static_in_pattern = statics cannot be referenced in patterns + .label = can't be used in patterns +mir_build_static_in_pattern_def = `static` defined here mir_build_suggest_attempted_int_lit = alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits @@ -310,12 +322,12 @@ mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count -> *[other] them } into the body -mir_build_type_not_structural = - to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]` - +mir_build_type_not_structural = constant of non-structural type `{$ty}` in a pattern + .label = constant of non-structural type +mir_build_type_not_structural_def = `{$ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns mir_build_type_not_structural_more_info = see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -mir_build_type_not_structural_tip = the traits must be derived, manual `impl`s are not sufficient +mir_build_type_not_structural_tip = + the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details mir_build_unconditional_recursion = function cannot return without recursing .label = cannot return without recursing @@ -334,6 +346,7 @@ mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = .label = access to union field mir_build_union_pattern = cannot use unions in constant patterns + .label = can't use a `union` here mir_build_unreachable_making_this_unreachable = collectively making this unreachable diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index 0cab853196b..777ff9e68f0 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -176,7 +176,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let ty = expr.ty; if !ty.is_sized(tcx, this.typing_env()) { // !sized means !copy, so this is an unsized move - assert!(!ty.is_copy_modulo_regions(tcx, this.typing_env())); + assert!(!tcx.type_is_copy_modulo_regions(this.typing_env(), ty)); // As described above, detect the case where we are passing a value of unsized // type, and that value is coming from the deref of a box. diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 58487a48184..3632da943e1 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -631,20 +631,27 @@ pub(crate) struct NonExhaustiveMatchAllArmsGuarded; #[diag(mir_build_static_in_pattern, code = E0158)] pub(crate) struct StaticInPattern { #[primary_span] + #[label] pub(crate) span: Span, + #[label(mir_build_static_in_pattern_def)] + pub(crate) static_span: Span, } #[derive(Diagnostic)] #[diag(mir_build_const_param_in_pattern, code = E0158)] pub(crate) struct ConstParamInPattern { #[primary_span] + #[label] pub(crate) span: Span, + #[label(mir_build_const_param_in_pattern_def)] + pub(crate) const_span: Span, } #[derive(Diagnostic)] #[diag(mir_build_non_const_path, code = E0080)] pub(crate) struct NonConstPath { #[primary_span] + #[label] pub(crate) span: Span, } @@ -695,6 +702,7 @@ pub(crate) struct WantedConstant { #[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)] pub(crate) struct ConstPatternDependsOnGenericParameter { #[primary_span] + #[label] pub(crate) span: Span, } @@ -702,6 +710,7 @@ pub(crate) struct ConstPatternDependsOnGenericParameter { #[diag(mir_build_could_not_eval_const_pattern)] pub(crate) struct CouldNotEvalConstPattern { #[primary_span] + #[label] pub(crate) span: Span, } @@ -867,33 +876,43 @@ pub(crate) enum Conflict { #[diag(mir_build_union_pattern)] pub(crate) struct UnionPattern { #[primary_span] + #[label] pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_type_not_structural)] -#[note(mir_build_type_not_structural_tip)] -#[note(mir_build_type_not_structural_more_info)] pub(crate) struct TypeNotStructural<'tcx> { #[primary_span] + #[label] pub(crate) span: Span, - pub(crate) non_sm_ty: Ty<'tcx>, + #[label(mir_build_type_not_structural_def)] + pub(crate) ty_def_span: Span, + pub(crate) ty: Ty<'tcx>, + #[note(mir_build_type_not_structural_tip)] + pub(crate) manual_partialeq_impl_span: Option<Span>, + #[note(mir_build_type_not_structural_more_info)] + pub(crate) manual_partialeq_impl_note: bool, } #[derive(Diagnostic)] #[diag(mir_build_non_partial_eq_match)] +#[note(mir_build_type_not_structural_more_info)] pub(crate) struct TypeNotPartialEq<'tcx> { #[primary_span] + #[label] pub(crate) span: Span, - pub(crate) non_peq_ty: Ty<'tcx>, + pub(crate) ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_invalid_pattern)] pub(crate) struct InvalidPattern<'tcx> { #[primary_span] + #[label] pub(crate) span: Span, pub(crate) non_sm_ty: Ty<'tcx>, + pub(crate) prefix: String, } #[derive(Diagnostic)] @@ -910,13 +929,16 @@ pub(crate) struct UnsizedPattern<'tcx> { #[help] pub(crate) struct NaNPattern { #[primary_span] + #[label] pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_pointer_pattern)] +#[note] pub(crate) struct PointerPattern { #[primary_span] + #[label] pub(crate) span: Span, } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index e55cd35e243..a13b00e1921 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -780,7 +780,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: return; }; - let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env); + let is_binding_by_move = |ty: Ty<'tcx>| !cx.tcx.type_is_copy_modulo_regions(cx.typing_env, ty); let sess = cx.tcx.sess; diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 5db08f01fdb..aed00aecefc 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,14 +1,17 @@ use rustc_abi::{FieldIdx, VariantIdx}; use rustc_apfloat::Float; +use rustc_data_structures::fx::FxHashSet; +use rustc_errors::Diag; use rustc_hir as hir; use rustc_index::Idx; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::Obligation; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::thir::{FieldPat, Pat, PatKind}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, ValTree}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeVisitor, ValTree}; use rustc_middle::{mir, span_bug}; -use rustc_span::Span; +use rustc_span::def_id::DefId; +use rustc_span::{Span, sym}; use rustc_trait_selection::traits::ObligationCause; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use tracing::{debug, instrument, trace}; @@ -35,7 +38,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { id: hir::HirId, span: Span, ) -> Box<Pat<'tcx>> { - let mut convert = ConstToPat::new(self, id, span); + let mut convert = ConstToPat::new(self, id, span, c); match c.kind() { ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty), @@ -49,21 +52,26 @@ struct ConstToPat<'tcx> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, span: Span, + id: hir::HirId, treat_byte_string_as_slice: bool, + + c: ty::Const<'tcx>, } impl<'tcx> ConstToPat<'tcx> { - fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span) -> Self { + fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self { trace!(?pat_ctxt.typeck_results.hir_owner); ConstToPat { tcx: pat_ctxt.tcx, typing_env: pat_ctxt.typing_env, span, + id, treat_byte_string_as_slice: pat_ctxt .typeck_results .treat_byte_string_as_slice .contains(&id.local_id), + c, } } @@ -71,13 +79,32 @@ impl<'tcx> ConstToPat<'tcx> { ty.is_structural_eq_shallow(self.tcx) } + /// We errored. Signal that in the pattern, so that follow up errors can be silenced. + fn mk_err(&self, mut err: Diag<'_>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> { + if let ty::ConstKind::Unevaluated(uv) = self.c.kind() { + let def_kind = self.tcx.def_kind(uv.def); + if let hir::def::DefKind::AssocConst = def_kind + && let Some(def_id) = uv.def.as_local() + { + // Include the container item in the output. + err.span_label(self.tcx.def_span(self.tcx.local_parent(def_id)), ""); + } + if let hir::def::DefKind::Const | hir::def::DefKind::AssocConst = def_kind { + err.span_label( + self.tcx.def_span(uv.def), + crate::fluent_generated::mir_build_const_defined_here, + ); + } + } + Box::new(Pat { span: self.span, ty, kind: PatKind::Error(err.emit()) }) + } + fn unevaluated_to_pat( &mut self, uv: ty::UnevaluatedConst<'tcx>, ty: Ty<'tcx>, ) -> Box<Pat<'tcx>> { trace!(self.treat_byte_string_as_slice); - let pat_from_kind = |kind| Box::new(Pat { span: self.span, ty, kind }); // It's not *technically* correct to be revealing opaque types here as borrowcheck has // not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even @@ -96,32 +123,60 @@ impl<'tcx> ConstToPat<'tcx> { Ok(Ok(c)) => c, Err(ErrorHandled::Reported(_, _)) => { // Let's tell the use where this failing const occurs. - let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span: self.span }); - return pat_from_kind(PatKind::Error(e)); + let mut err = + self.tcx.dcx().create_err(CouldNotEvalConstPattern { span: self.span }); + // We've emitted an error on the original const, it would be redundant to complain + // on its use as well. + if let ty::ConstKind::Unevaluated(uv) = self.c.kind() + && let hir::def::DefKind::Const | hir::def::DefKind::AssocConst = + self.tcx.def_kind(uv.def) + { + err.downgrade_to_delayed_bug(); + } + return self.mk_err(err, ty); } Err(ErrorHandled::TooGeneric(_)) => { - let e = self + let mut e = self .tcx .dcx() - .emit_err(ConstPatternDependsOnGenericParameter { span: self.span }); - return pat_from_kind(PatKind::Error(e)); + .create_err(ConstPatternDependsOnGenericParameter { span: self.span }); + for arg in uv.args { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Param(param_ty) = ty.kind() + { + let def_id = self.tcx.hir().enclosing_body_owner(self.id); + let generics = self.tcx.generics_of(def_id); + let param = generics.type_param(*param_ty, self.tcx); + let span = self.tcx.def_span(param.def_id); + e.span_label(span, "constant depends on this generic parameter"); + if let Some(ident) = self.tcx.def_ident_span(def_id) + && self.tcx.sess.source_map().is_multiline(ident.between(span)) + { + // Display the `fn` name as well in the diagnostic, as the generic isn't + // in the same line and it could be confusing otherwise. + e.span_label(ident, ""); + } + } + } + return self.mk_err(e, ty); } Ok(Err(bad_ty)) => { // The pattern cannot be turned into a valtree. let e = match bad_ty.kind() { ty::Adt(def, ..) => { assert!(def.is_union()); - self.tcx.dcx().emit_err(UnionPattern { span: self.span }) + self.tcx.dcx().create_err(UnionPattern { span: self.span }) } ty::FnPtr(..) | ty::RawPtr(..) => { - self.tcx.dcx().emit_err(PointerPattern { span: self.span }) + self.tcx.dcx().create_err(PointerPattern { span: self.span }) } - _ => self - .tcx - .dcx() - .emit_err(InvalidPattern { span: self.span, non_sm_ty: bad_ty }), + _ => self.tcx.dcx().create_err(InvalidPattern { + span: self.span, + non_sm_ty: bad_ty, + prefix: bad_ty.prefix_string(self.tcx).to_string(), + }), }; - return pat_from_kind(PatKind::Error(e)); + return self.mk_err(e, ty); } }; @@ -130,42 +185,16 @@ impl<'tcx> ConstToPat<'tcx> { if !inlined_const_as_pat.references_error() { // Always check for `PartialEq` if we had no other errors yet. - if !self.type_has_partial_eq_impl(ty) { - let err = TypeNotPartialEq { span: self.span, non_peq_ty: ty }; - let e = self.tcx.dcx().emit_err(err); - return pat_from_kind(PatKind::Error(e)); + if !type_has_partial_eq_impl(self.tcx, typing_env, ty).0 { + let mut err = self.tcx.dcx().create_err(TypeNotPartialEq { span: self.span, ty }); + extend_type_not_partial_eq(self.tcx, typing_env, ty, &mut err); + return self.mk_err(err, ty); } } inlined_const_as_pat } - #[instrument(level = "trace", skip(self), ret)] - fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool { - let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env); - // double-check there even *is* a semantic `PartialEq` to dispatch to. - // - // (If there isn't, then we can safely issue a hard - // error, because that's never worked, due to compiler - // using `PartialEq::eq` in this scenario in the past.) - let partial_eq_trait_id = - self.tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span)); - let partial_eq_obligation = Obligation::new( - self.tcx, - ObligationCause::dummy(), - param_env, - ty::TraitRef::new(self.tcx, partial_eq_trait_id, [ty, ty]), - ); - - // This *could* accept a type that isn't actually `PartialEq`, because region bounds get - // ignored. However that should be pretty much impossible since consts that do not depend on - // generics can only mention the `'static` lifetime, and how would one have a type that's - // `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem - // we'll need to leave some sort of trace of this requirement in the MIR so that borrowck - // can ensure that the type really implements `PartialEq`. - infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation) - } - fn field_pats( &self, vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>, @@ -190,10 +219,25 @@ impl<'tcx> ConstToPat<'tcx> { // Extremely important check for all ADTs! Make sure they opted-in to be used in // patterns. debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty); - let err = TypeNotStructural { span, non_sm_ty: ty }; - let e = tcx.dcx().emit_err(err); - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) + let (_impls_partial_eq, derived, structural, impl_def_id) = + type_has_partial_eq_impl(self.tcx, self.typing_env, ty); + let (manual_partialeq_impl_span, manual_partialeq_impl_note) = + match (structural, impl_def_id) { + (true, _) => (None, false), + (_, Some(def_id)) if def_id.is_local() && !derived => { + (Some(tcx.def_span(def_id)), false) + } + _ => (None, true), + }; + let ty_def_span = tcx.def_span(adt_def.did()); + let err = TypeNotStructural { + span, + ty, + ty_def_span, + manual_partialeq_impl_span, + manual_partialeq_impl_note, + }; + return self.mk_err(tcx.dcx().create_err(err), ty); } ty::Adt(adt_def, args) if adt_def.is_enum() => { let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap(); @@ -207,7 +251,7 @@ impl<'tcx> ConstToPat<'tcx> { adt_def.variants()[variant_index] .fields .iter() - .map(|field| field.ty(self.tcx, args)), + .map(|field| field.ty(tcx, args)), ), ), } @@ -216,7 +260,7 @@ impl<'tcx> ConstToPat<'tcx> { assert!(!def.is_union()); // Valtree construction would never succeed for unions. PatKind::Leaf { subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip( - def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx, args)), + def.non_enum_variant().fields.iter().map(|field| field.ty(tcx, args)), )), } } @@ -252,10 +296,10 @@ impl<'tcx> ConstToPat<'tcx> { // deref pattern. _ => { if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() { - let err = UnsizedPattern { span, non_sm_ty: *pointee_ty }; - let e = tcx.dcx().emit_err(err); - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) + return self.mk_err( + tcx.dcx().create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty }), + ty, + ); } else { // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when // matching against references, you can only use byte string literals. @@ -286,8 +330,7 @@ impl<'tcx> ConstToPat<'tcx> { if is_nan { // NaNs are not ever equal to anything so they make no sense as patterns. // Also see <https://github.com/rust-lang/rfcs/pull/3535>. - let e = tcx.dcx().emit_err(NaNPattern { span }); - PatKind::Error(e) + return self.mk_err(tcx.dcx().create_err(NaNPattern { span }), ty); } else { PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), @@ -305,13 +348,153 @@ impl<'tcx> ConstToPat<'tcx> { ) } _ => { - let err = InvalidPattern { span, non_sm_ty: ty }; - let e = tcx.dcx().emit_err(err); - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) + let err = InvalidPattern { + span, + non_sm_ty: ty, + prefix: ty.prefix_string(tcx).to_string(), + }; + return self.mk_err(tcx.dcx().create_err(err), ty); } }; Box::new(Pat { span, ty, kind }) } } + +/// Given a type with type parameters, visit every ADT looking for types that need to +/// `#[derive(PartialEq)]` for it to be a structural type. +fn extend_type_not_partial_eq<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, + err: &mut Diag<'_>, +) { + /// Collect all types that need to be `StructuralPartialEq`. + struct UsedParamsNeedInstantiationVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + /// The user has written `impl PartialEq for Ty` which means it's non-structual. + adts_with_manual_partialeq: FxHashSet<Span>, + /// The type has no `PartialEq` implementation, neither manual or derived. + adts_without_partialeq: FxHashSet<Span>, + /// The user has written `impl PartialEq for Ty` which means it's non-structual, + /// but we don't have a span to point at, so we'll just add them as a `note`. + manual: Vec<Ty<'tcx>>, + /// The type has no `PartialEq` implementation, neither manual or derived, but + /// we don't have a span to point at, so we'll just add them as a `note`. + without: Vec<Ty<'tcx>>, + } + + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> { + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + if let ty::Adt(def, _args) = ty.kind() { + let ty_def_id = def.did(); + let ty_def_span = self.tcx.def_span(ty_def_id); + let (impls_partial_eq, derived, structural, impl_def_id) = + type_has_partial_eq_impl(self.tcx, self.typing_env, ty); + match (impls_partial_eq, derived, structural, impl_def_id) { + (_, _, true, _) => {} + (true, false, _, Some(def_id)) if def_id.is_local() => { + self.adts_with_manual_partialeq.insert(self.tcx.def_span(def_id)); + } + (true, false, _, _) if ty_def_id.is_local() => { + self.adts_with_manual_partialeq.insert(ty_def_span); + } + (false, _, _, _) if ty_def_id.is_local() => { + self.adts_without_partialeq.insert(ty_def_span); + } + (true, false, _, _) => { + self.manual.push(ty); + } + (false, _, _, _) => { + self.without.push(ty); + } + _ => {} + }; + } + use rustc_middle::ty::TypeSuperVisitable; + ty.super_visit_with(self) + } + } + let mut v = UsedParamsNeedInstantiationVisitor { + tcx, + typing_env, + adts_with_manual_partialeq: FxHashSet::default(), + adts_without_partialeq: FxHashSet::default(), + manual: vec![], + without: vec![], + }; + v.visit_ty(ty); + #[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering + for span in v.adts_with_manual_partialeq { + err.span_note(span, "the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details"); + } + #[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering + for span in v.adts_without_partialeq { + err.span_label( + span, + "must be annotated with `#[derive(PartialEq)]` to be usable in patterns", + ); + } + for ty in v.manual { + err.note(format!( + "`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details" + )); + } + for ty in v.without { + err.note(format!( + "`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns" + )); + } +} + +#[instrument(level = "trace", skip(tcx), ret)] +fn type_has_partial_eq_impl<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, +) -> ( + /* has impl */ bool, + /* is derived */ bool, + /* structural partial eq */ bool, + /* non-blanket impl */ Option<DefId>, +) { + let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); + // double-check there even *is* a semantic `PartialEq` to dispatch to. + // + // (If there isn't, then we can safely issue a hard + // error, because that's never worked, due to compiler + // using `PartialEq::eq` in this scenario in the past.) + let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None); + let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None); + + let partial_eq_obligation = Obligation::new( + tcx, + ObligationCause::dummy(), + param_env, + ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]), + ); + + let mut automatically_derived = false; + let mut structural_peq = false; + let mut impl_def_id = None; + for def_id in tcx.non_blanket_impls_for_ty(partial_eq_trait_id, ty) { + automatically_derived = tcx.has_attr(def_id, sym::automatically_derived); + impl_def_id = Some(def_id); + } + for _ in tcx.non_blanket_impls_for_ty(structural_partial_eq_trait_id, ty) { + structural_peq = true; + } + // This *could* accept a type that isn't actually `PartialEq`, because region bounds get + // ignored. However that should be pretty much impossible since consts that do not depend on + // generics can only mention the `'static` lifetime, and how would one have a type that's + // `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem + // we'll need to leave some sort of trace of this requirement in the MIR so that borrowck + // can ensure that the type really implements `PartialEq`. + ( + infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation), + automatically_derived, + structural_peq, + impl_def_id, + ) +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 08c6b4abd3b..3ac53fa6272 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -528,11 +528,17 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { | Res::SelfCtor(..) => PatKind::Leaf { subpatterns }, _ => { let e = match res { - Res::Def(DefKind::ConstParam, _) => { - self.tcx.dcx().emit_err(ConstParamInPattern { span }) + Res::Def(DefKind::ConstParam, def_id) => { + self.tcx.dcx().emit_err(ConstParamInPattern { + span, + const_span: self.tcx().def_span(def_id), + }) } - Res::Def(DefKind::Static { .. }, _) => { - self.tcx.dcx().emit_err(StaticInPattern { span }) + Res::Def(DefKind::Static { .. }, def_id) => { + self.tcx.dcx().emit_err(StaticInPattern { + span, + static_span: self.tcx().def_span(def_id), + }) } _ => self.tcx.dcx().emit_err(NonConstPath { span }), }; diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs index 11cf8c3e898..4a9bcdaddb3 100644 --- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs @@ -15,7 +15,6 @@ pub enum ResultsHandle<'a, 'tcx, A> where A: Analysis<'tcx>, { - Borrowed(&'a Results<'tcx, A>), BorrowedMut(&'a mut Results<'tcx, A>), Owned(Results<'tcx, A>), } @@ -28,7 +27,6 @@ where fn deref(&self) -> &Results<'tcx, A> { match self { - ResultsHandle::Borrowed(borrowed) => borrowed, ResultsHandle::BorrowedMut(borrowed) => borrowed, ResultsHandle::Owned(owned) => owned, } @@ -41,9 +39,6 @@ where { fn deref_mut(&mut self) -> &mut Results<'tcx, A> { match self { - ResultsHandle::Borrowed(_borrowed) => { - panic!("tried to deref_mut a `ResultsHandle::Borrowed") - } ResultsHandle::BorrowedMut(borrowed) => borrowed, ResultsHandle::Owned(owned) => owned, } diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index 6e4994af8b4..561229cf725 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -47,7 +47,7 @@ where { pub(crate) fn new( body: &'mir Body<'tcx>, - results: &'mir Results<'tcx, A>, + results: &'mir mut Results<'tcx, A>, style: OutputStyle, ) -> Self { let reachable = mir::traversal::reachable_as_bitset(body); diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index f1ea94e1689..b9407882ec5 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -281,10 +281,10 @@ pub trait Analysis<'tcx> { ); } - let results = Results { analysis: self, entry_sets }; + let mut results = Results { analysis: self, entry_sets }; if tcx.sess.opts.unstable_opts.dump_mir_dataflow { - let res = write_graphviz_results(tcx, body, &results, pass_name); + let res = write_graphviz_results(tcx, body, &mut results, pass_name); if let Err(e) = res { error!("Failed to write graphviz dataflow results: {}", e); } diff --git a/compiler/rustc_mir_dataflow/src/framework/results.rs b/compiler/rustc_mir_dataflow/src/framework/results.rs index 8493a7aa44b..c4321c454e6 100644 --- a/compiler/rustc_mir_dataflow/src/framework/results.rs +++ b/compiler/rustc_mir_dataflow/src/framework/results.rs @@ -37,18 +37,9 @@ impl<'tcx, A> Results<'tcx, A> where A: Analysis<'tcx>, { - /// Creates a `ResultsCursor` that can inspect these `Results`. Immutably borrows the `Results`, - /// which is appropriate when the `Results` is used outside the cursor. + /// Creates a `ResultsCursor` that mutably borrows the `Results`, which is appropriate when the + /// `Results` is also used outside the cursor. pub fn as_results_cursor<'mir>( - &'mir self, - body: &'mir mir::Body<'tcx>, - ) -> ResultsCursor<'mir, 'tcx, A> { - ResultsCursor::new(body, ResultsHandle::Borrowed(self)) - } - - /// Creates a `ResultsCursor` that can mutate these `Results`. Mutably borrows the `Results`, - /// which is appropriate when the `Results` is used outside the cursor. - pub fn as_results_cursor_mut<'mir>( &'mir mut self, body: &'mir mir::Body<'tcx>, ) -> ResultsCursor<'mir, 'tcx, A> { @@ -95,7 +86,7 @@ where pub(super) fn write_graphviz_results<'tcx, A>( tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>, - results: &Results<'tcx, A>, + results: &mut Results<'tcx, A>, pass_name: Option<&'static str>, ) -> std::io::Result<()> where diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 9b9aeccf890..858752a3f01 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -680,7 +680,7 @@ fn locals_live_across_suspend_points<'tcx>( let mut requires_storage_results = MaybeRequiresStorage::new(borrowed_locals_results.into_results_cursor(body)) .iterate_to_fixpoint(tcx, body, None); - let mut requires_storage_cursor = requires_storage_results.as_results_cursor_mut(body); + let mut requires_storage_cursor = requires_storage_results.as_results_cursor(body); // Calculate the liveness of MIR locals ignoring borrows. let mut liveness = diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index cf9f6981c5a..46efdd16ee8 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -1,3 +1,4 @@ +use std::cmp::Ordering; use std::fmt::{self, Debug}; use rustc_data_structures::captures::Captures; @@ -10,9 +11,12 @@ use tracing::{debug, debug_span, instrument}; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverageGraphWithLoops}; +#[cfg(test)] +mod tests; + /// The coverage counter or counter expression associated with a particular /// BCB node or BCB edge. -#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] enum BcbCounter { Counter { id: CounterId }, Expression { id: ExpressionId }, @@ -43,8 +47,9 @@ struct BcbExpression { rhs: BcbCounter, } -#[derive(Debug)] -pub(super) enum CounterIncrementSite { +/// Enum representing either a node or an edge in the coverage graph. +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub(super) enum Site { Node { bcb: BasicCoverageBlock }, Edge { from_bcb: BasicCoverageBlock, to_bcb: BasicCoverageBlock }, } @@ -54,16 +59,10 @@ pub(super) enum CounterIncrementSite { pub(super) struct CoverageCounters { /// List of places where a counter-increment statement should be injected /// into MIR, each with its corresponding counter ID. - counter_increment_sites: IndexVec<CounterId, CounterIncrementSite>, + counter_increment_sites: IndexVec<CounterId, Site>, /// Coverage counters/expressions that are associated with individual BCBs. node_counters: IndexVec<BasicCoverageBlock, Option<BcbCounter>>, - /// Coverage counters/expressions that are associated with the control-flow - /// edge between two BCBs. - /// - /// We currently don't iterate over this map, but if we do in the future, - /// switch it back to `FxIndexMap` to avoid query stability hazards. - edge_counters: FxHashMap<(BasicCoverageBlock, BasicCoverageBlock), BcbCounter>, /// Table of expression data, associating each expression ID with its /// corresponding operator (+ or -) and its LHS/RHS operands. @@ -83,93 +82,30 @@ impl CoverageCounters { let mut builder = CountersBuilder::new(graph, bcb_needs_counter); builder.make_bcb_counters(); - builder.counters + builder.into_coverage_counters() } fn with_num_bcbs(num_bcbs: usize) -> Self { Self { counter_increment_sites: IndexVec::new(), node_counters: IndexVec::from_elem_n(None, num_bcbs), - edge_counters: FxHashMap::default(), expressions: IndexVec::new(), expressions_memo: FxHashMap::default(), } } - /// Shared helper used by [`Self::make_phys_node_counter`] and - /// [`Self::make_phys_edge_counter`]. Don't call this directly. - fn make_counter_inner(&mut self, site: CounterIncrementSite) -> BcbCounter { + /// Creates a new physical counter for a BCB node or edge. + fn make_phys_counter(&mut self, site: Site) -> BcbCounter { let id = self.counter_increment_sites.push(site); BcbCounter::Counter { id } } - /// Creates a new physical counter for a BCB node. - fn make_phys_node_counter(&mut self, bcb: BasicCoverageBlock) -> BcbCounter { - self.make_counter_inner(CounterIncrementSite::Node { bcb }) - } - - /// Creates a new physical counter for a BCB edge. - fn make_phys_edge_counter( - &mut self, - from_bcb: BasicCoverageBlock, - to_bcb: BasicCoverageBlock, - ) -> BcbCounter { - self.make_counter_inner(CounterIncrementSite::Edge { from_bcb, to_bcb }) - } - fn make_expression(&mut self, lhs: BcbCounter, op: Op, rhs: BcbCounter) -> BcbCounter { let new_expr = BcbExpression { lhs, op, rhs }; - *self - .expressions_memo - .entry(new_expr) - .or_insert_with(|| Self::make_expression_inner(&mut self.expressions, new_expr)) - } - - /// This is an associated function so that we can call it while borrowing - /// `&mut self.expressions_memo`. - fn make_expression_inner( - expressions: &mut IndexVec<ExpressionId, BcbExpression>, - new_expr: BcbExpression, - ) -> BcbCounter { - // Simplify expressions using basic algebra. - // - // Some of these cases might not actually occur in practice, depending - // on the details of how the instrumentor builds expressions. - let BcbExpression { lhs, op, rhs } = new_expr; - - if let BcbCounter::Expression { id } = lhs { - let lhs_expr = &expressions[id]; - - // Simplify `(a - b) + b` to `a`. - if lhs_expr.op == Op::Subtract && op == Op::Add && lhs_expr.rhs == rhs { - return lhs_expr.lhs; - } - // Simplify `(a + b) - b` to `a`. - if lhs_expr.op == Op::Add && op == Op::Subtract && lhs_expr.rhs == rhs { - return lhs_expr.lhs; - } - // Simplify `(a + b) - a` to `b`. - if lhs_expr.op == Op::Add && op == Op::Subtract && lhs_expr.lhs == rhs { - return lhs_expr.rhs; - } - } - - if let BcbCounter::Expression { id } = rhs { - let rhs_expr = &expressions[id]; - - // Simplify `a + (b - a)` to `b`. - if op == Op::Add && rhs_expr.op == Op::Subtract && lhs == rhs_expr.rhs { - return rhs_expr.lhs; - } - // Simplify `a - (a - b)` to `b`. - if op == Op::Subtract && rhs_expr.op == Op::Subtract && lhs == rhs_expr.lhs { - return rhs_expr.rhs; - } - } - - // Simplification failed, so actually create the new expression. - let id = expressions.push(new_expr); - BcbCounter::Expression { id } + *self.expressions_memo.entry(new_expr).or_insert_with(|| { + let id = self.expressions.push(new_expr); + BcbCounter::Expression { id } + }) } /// Creates a counter that is the sum of the given counters. @@ -182,6 +118,12 @@ impl CoverageCounters { .reduce(|accum, counter| self.make_expression(accum, Op::Add, counter)) } + /// Creates a counter whose value is `lhs - SUM(rhs)`. + fn make_subtracted_sum(&mut self, lhs: BcbCounter, rhs: &[BcbCounter]) -> BcbCounter { + let Some(rhs_sum) = self.make_sum(rhs) else { return lhs }; + self.make_expression(lhs, Op::Subtract, rhs_sum) + } + pub(super) fn num_counters(&self) -> usize { self.counter_increment_sites.len() } @@ -195,20 +137,6 @@ impl CoverageCounters { counter } - fn set_edge_counter( - &mut self, - from_bcb: BasicCoverageBlock, - to_bcb: BasicCoverageBlock, - counter: BcbCounter, - ) -> BcbCounter { - let existing = self.edge_counters.insert((from_bcb, to_bcb), counter); - assert!( - existing.is_none(), - "edge ({from_bcb:?} -> {to_bcb:?}) already has a counter: {existing:?} => {counter:?}" - ); - counter - } - pub(super) fn term_for_bcb(&self, bcb: BasicCoverageBlock) -> Option<CovTerm> { self.node_counters[bcb].map(|counter| counter.as_term()) } @@ -218,8 +146,8 @@ impl CoverageCounters { /// each site's corresponding counter ID. pub(super) fn counter_increment_sites( &self, - ) -> impl Iterator<Item = (CounterId, &CounterIncrementSite)> { - self.counter_increment_sites.iter_enumerated() + ) -> impl Iterator<Item = (CounterId, Site)> + Captures<'_> { + self.counter_increment_sites.iter_enumerated().map(|(id, &site)| (id, site)) } /// Returns an iterator over the subset of BCB nodes that have been associated @@ -254,22 +182,53 @@ impl CoverageCounters { } } +/// Symbolic representation of the coverage counter to be used for a particular +/// node or edge in the coverage graph. The same site counter can be used for +/// multiple sites, if they have been determined to have the same count. +#[derive(Clone, Copy, Debug)] +enum SiteCounter { + /// A physical counter at some node/edge. + Phys { site: Site }, + /// A counter expression for a node that takes the sum of all its in-edge + /// counters. + NodeSumExpr { bcb: BasicCoverageBlock }, + /// A counter expression for an edge that takes the counter of its source + /// node, and subtracts the counters of all its sibling out-edges. + EdgeDiffExpr { from_bcb: BasicCoverageBlock, to_bcb: BasicCoverageBlock }, +} + +/// Yields the graph successors of `from_bcb` that aren't `to_bcb`. This is +/// used when creating a counter expression for [`SiteCounter::EdgeDiffExpr`]. +/// +/// For example, in this diagram the sibling out-edge targets of edge `AC` are +/// the nodes `B` and `D`. +/// +/// ```text +/// A +/// / | \ +/// B C D +/// ``` +fn sibling_out_edge_targets( + graph: &CoverageGraph, + from_bcb: BasicCoverageBlock, + to_bcb: BasicCoverageBlock, +) -> impl Iterator<Item = BasicCoverageBlock> + Captures<'_> { + graph.successors[from_bcb].iter().copied().filter(move |&t| t != to_bcb) +} + /// Helper struct that allows counter creation to inspect the BCB graph, and /// the set of nodes that need counters. struct CountersBuilder<'a> { - counters: CoverageCounters, graph: &'a CoverageGraph, bcb_needs_counter: &'a BitSet<BasicCoverageBlock>, + + site_counters: FxHashMap<Site, SiteCounter>, } impl<'a> CountersBuilder<'a> { fn new(graph: &'a CoverageGraph, bcb_needs_counter: &'a BitSet<BasicCoverageBlock>) -> Self { assert_eq!(graph.num_nodes(), bcb_needs_counter.domain_size()); - Self { - counters: CoverageCounters::with_num_bcbs(graph.num_nodes()), - graph, - bcb_needs_counter, - } + Self { graph, bcb_needs_counter, site_counters: FxHashMap::default() } } fn make_bcb_counters(&mut self) { @@ -302,9 +261,7 @@ impl<'a> CountersBuilder<'a> { fn make_node_counter_and_out_edge_counters(&mut self, from_bcb: BasicCoverageBlock) { // First, ensure that this node has a counter of some kind. // We might also use that counter to compute one of the out-edge counters. - let node_counter = self.get_or_make_node_counter(from_bcb); - - let successors = self.graph.successors[from_bcb].as_slice(); + self.get_or_make_node_counter(from_bcb); // If this node's out-edges won't sum to the node's counter, // then there's no reason to create edge counters here. @@ -315,11 +272,11 @@ impl<'a> CountersBuilder<'a> { // When choosing which out-edge should be given a counter expression, ignore edges that // already have counters, or could use the existing counter of their target node. let out_edge_has_counter = |to_bcb| { - if self.counters.edge_counters.contains_key(&(from_bcb, to_bcb)) { + if self.site_counters.contains_key(&Site::Edge { from_bcb, to_bcb }) { return true; } self.graph.sole_predecessor(to_bcb) == Some(from_bcb) - && self.counters.node_counters[to_bcb].is_some() + && self.site_counters.contains_key(&Site::Node { bcb: to_bcb }) }; // Determine the set of out-edges that could benefit from being given an expression. @@ -332,51 +289,41 @@ impl<'a> CountersBuilder<'a> { // If there are out-edges without counters, choose one to be given an expression // (computed from this node and the other out-edges) instead of a physical counter. - let Some(target_bcb) = self.choose_out_edge_for_expression(from_bcb, &candidate_successors) + let Some(to_bcb) = self.choose_out_edge_for_expression(from_bcb, &candidate_successors) else { return; }; // For each out-edge other than the one that was chosen to get an expression, - // ensure that it has a counter (existing counter/expression or a new counter), - // and accumulate the corresponding counters into a single sum expression. - let other_out_edge_counters = successors - .iter() - .copied() - // Skip the chosen edge, since we'll calculate its count from this sum. - .filter(|&edge_target_bcb| edge_target_bcb != target_bcb) - .map(|to_bcb| self.get_or_make_edge_counter(from_bcb, to_bcb)) - .collect::<Vec<_>>(); - let Some(sum_of_all_other_out_edges) = self.counters.make_sum(&other_out_edge_counters) - else { - return; - }; + // ensure that it has a counter (existing counter/expression or a new counter). + for target in sibling_out_edge_targets(self.graph, from_bcb, to_bcb) { + self.get_or_make_edge_counter(from_bcb, target); + } // Now create an expression for the chosen edge, by taking the counter // for its source node and subtracting the sum of its sibling out-edges. - let expression = - self.counters.make_expression(node_counter, Op::Subtract, sum_of_all_other_out_edges); - - debug!("{target_bcb:?} gets an expression: {expression:?}"); - self.counters.set_edge_counter(from_bcb, target_bcb, expression); + let counter = SiteCounter::EdgeDiffExpr { from_bcb, to_bcb }; + self.site_counters.insert(Site::Edge { from_bcb, to_bcb }, counter); } #[instrument(level = "debug", skip(self))] - fn get_or_make_node_counter(&mut self, bcb: BasicCoverageBlock) -> BcbCounter { + fn get_or_make_node_counter(&mut self, bcb: BasicCoverageBlock) -> SiteCounter { // If the BCB already has a counter, return it. - if let Some(counter) = self.counters.node_counters[bcb] { + if let Some(&counter) = self.site_counters.get(&Site::Node { bcb }) { debug!("{bcb:?} already has a counter: {counter:?}"); return counter; } let counter = self.make_node_counter_inner(bcb); - self.counters.set_node_counter(bcb, counter) + self.site_counters.insert(Site::Node { bcb }, counter); + counter } - fn make_node_counter_inner(&mut self, bcb: BasicCoverageBlock) -> BcbCounter { + fn make_node_counter_inner(&mut self, bcb: BasicCoverageBlock) -> SiteCounter { // If the node's sole in-edge already has a counter, use that. if let Some(sole_pred) = self.graph.sole_predecessor(bcb) - && let Some(&edge_counter) = self.counters.edge_counters.get(&(sole_pred, bcb)) + && let Some(&edge_counter) = + self.site_counters.get(&Site::Edge { from_bcb: sole_pred, to_bcb: bcb }) { return edge_counter; } @@ -390,20 +337,17 @@ impl<'a> CountersBuilder<'a> { // leading to infinite recursion. if predecessors.len() <= 1 || predecessors.contains(&bcb) { debug!(?bcb, ?predecessors, "node has <=1 predecessors or is its own predecessor"); - let counter = self.counters.make_phys_node_counter(bcb); + let counter = SiteCounter::Phys { site: Site::Node { bcb } }; debug!(?bcb, ?counter, "node gets a physical counter"); return counter; } // A BCB with multiple incoming edges can compute its count by ensuring that counters // exist for each of those edges, and then adding them up to get a total count. - let in_edge_counters = predecessors - .iter() - .copied() - .map(|from_bcb| self.get_or_make_edge_counter(from_bcb, bcb)) - .collect::<Vec<_>>(); - let sum_of_in_edges: BcbCounter = - self.counters.make_sum(&in_edge_counters).expect("there must be at least one in-edge"); + for &from_bcb in predecessors { + self.get_or_make_edge_counter(from_bcb, bcb); + } + let sum_of_in_edges = SiteCounter::NodeSumExpr { bcb }; debug!("{bcb:?} gets a new counter (sum of predecessor counters): {sum_of_in_edges:?}"); sum_of_in_edges @@ -414,22 +358,23 @@ impl<'a> CountersBuilder<'a> { &mut self, from_bcb: BasicCoverageBlock, to_bcb: BasicCoverageBlock, - ) -> BcbCounter { + ) -> SiteCounter { // If the edge already has a counter, return it. - if let Some(&counter) = self.counters.edge_counters.get(&(from_bcb, to_bcb)) { + if let Some(&counter) = self.site_counters.get(&Site::Edge { from_bcb, to_bcb }) { debug!("Edge {from_bcb:?}->{to_bcb:?} already has a counter: {counter:?}"); return counter; } let counter = self.make_edge_counter_inner(from_bcb, to_bcb); - self.counters.set_edge_counter(from_bcb, to_bcb, counter) + self.site_counters.insert(Site::Edge { from_bcb, to_bcb }, counter); + counter } fn make_edge_counter_inner( &mut self, from_bcb: BasicCoverageBlock, to_bcb: BasicCoverageBlock, - ) -> BcbCounter { + ) -> SiteCounter { // If the target node has exactly one in-edge (i.e. this one), then just // use the node's counter, since it will have the same value. if let Some(sole_pred) = self.graph.sole_predecessor(to_bcb) { @@ -447,7 +392,7 @@ impl<'a> CountersBuilder<'a> { } // Make a new counter to count this edge. - let counter = self.counters.make_phys_edge_counter(from_bcb, to_bcb); + let counter = SiteCounter::Phys { site: Site::Edge { from_bcb, to_bcb } }; debug!(?from_bcb, ?to_bcb, ?counter, "edge gets a physical counter"); counter } @@ -510,4 +455,145 @@ impl<'a> CountersBuilder<'a> { None } + + fn into_coverage_counters(self) -> CoverageCounters { + Transcriber::new(&self).transcribe_counters() + } +} + +/// Helper struct for converting `CountersBuilder` into a final `CoverageCounters`. +struct Transcriber<'a> { + old: &'a CountersBuilder<'a>, + new: CoverageCounters, + phys_counter_for_site: FxHashMap<Site, BcbCounter>, +} + +impl<'a> Transcriber<'a> { + fn new(old: &'a CountersBuilder<'a>) -> Self { + Self { + old, + new: CoverageCounters::with_num_bcbs(old.graph.num_nodes()), + phys_counter_for_site: FxHashMap::default(), + } + } + + fn transcribe_counters(mut self) -> CoverageCounters { + for bcb in self.old.bcb_needs_counter.iter() { + let site = Site::Node { bcb }; + let site_counter = self.site_counter(site); + + // Resolve the site counter into flat lists of nodes/edges whose + // physical counts contribute to the counter for this node. + // Distinguish between counts that will be added vs subtracted. + let mut pos = vec![]; + let mut neg = vec![]; + self.push_resolved_sites(site_counter, &mut pos, &mut neg); + + // Simplify by cancelling out sites that appear on both sides. + let (mut pos, mut neg) = sort_and_cancel(pos, neg); + + if pos.is_empty() { + // If we somehow end up with no positive terms after cancellation, + // fall back to creating a physical counter. There's no known way + // for this to happen, but it's hard to confidently rule it out. + debug_assert!(false, "{site:?} has no positive counter terms"); + pos = vec![Some(site)]; + neg = vec![]; + } + + let mut new_counters_for_sites = |sites: Vec<Option<Site>>| { + sites + .into_iter() + .filter_map(|id| try { self.ensure_phys_counter(id?) }) + .collect::<Vec<_>>() + }; + let mut pos = new_counters_for_sites(pos); + let mut neg = new_counters_for_sites(neg); + + pos.sort(); + neg.sort(); + + let pos_counter = self.new.make_sum(&pos).expect("`pos` should not be empty"); + let new_counter = self.new.make_subtracted_sum(pos_counter, &neg); + self.new.set_node_counter(bcb, new_counter); + } + + self.new + } + + fn site_counter(&self, site: Site) -> SiteCounter { + self.old.site_counters.get(&site).copied().unwrap_or_else(|| { + // We should have already created all necessary site counters. + // But if we somehow didn't, avoid crashing in release builds, + // and just use an extra physical counter instead. + debug_assert!(false, "{site:?} should have a counter"); + SiteCounter::Phys { site } + }) + } + + fn ensure_phys_counter(&mut self, site: Site) -> BcbCounter { + *self.phys_counter_for_site.entry(site).or_insert_with(|| self.new.make_phys_counter(site)) + } + + /// Resolves the given counter into flat lists of nodes/edges, whose counters + /// will then be added and subtracted to form a counter expression. + fn push_resolved_sites(&self, counter: SiteCounter, pos: &mut Vec<Site>, neg: &mut Vec<Site>) { + match counter { + SiteCounter::Phys { site } => pos.push(site), + SiteCounter::NodeSumExpr { bcb } => { + for &from_bcb in &self.old.graph.predecessors[bcb] { + let edge_counter = self.site_counter(Site::Edge { from_bcb, to_bcb: bcb }); + self.push_resolved_sites(edge_counter, pos, neg); + } + } + SiteCounter::EdgeDiffExpr { from_bcb, to_bcb } => { + // First, add the count for `from_bcb`. + let node_counter = self.site_counter(Site::Node { bcb: from_bcb }); + self.push_resolved_sites(node_counter, pos, neg); + + // Then subtract the counts for the other out-edges. + for target in sibling_out_edge_targets(self.old.graph, from_bcb, to_bcb) { + let edge_counter = self.site_counter(Site::Edge { from_bcb, to_bcb: target }); + // Swap `neg` and `pos` so that the counter is subtracted. + self.push_resolved_sites(edge_counter, neg, pos); + } + } + } + } +} + +/// Given two lists: +/// - Sorts each list. +/// - Converts each list to `Vec<Option<T>>`. +/// - Scans for values that appear in both lists, and cancels them out by +/// replacing matching pairs of values with `None`. +fn sort_and_cancel<T: Ord>(mut pos: Vec<T>, mut neg: Vec<T>) -> (Vec<Option<T>>, Vec<Option<T>>) { + pos.sort(); + neg.sort(); + + // Convert to `Vec<Option<T>>`. If `T` has a niche, this should be zero-cost. + let mut pos = pos.into_iter().map(Some).collect::<Vec<_>>(); + let mut neg = neg.into_iter().map(Some).collect::<Vec<_>>(); + + // Scan through the lists using two cursors. When either cursor reaches the + // end of its list, there can be no more equal pairs, so stop. + let mut p = 0; + let mut n = 0; + while p < pos.len() && n < neg.len() { + // If the values are equal, remove them and advance both cursors. + // Otherwise, advance whichever cursor points to the lesser value. + // (Choosing which cursor to advance relies on both lists being sorted.) + match pos[p].cmp(&neg[n]) { + Ordering::Less => p += 1, + Ordering::Equal => { + pos[p] = None; + neg[n] = None; + p += 1; + n += 1; + } + Ordering::Greater => n += 1, + } + } + + (pos, neg) } diff --git a/compiler/rustc_mir_transform/src/coverage/counters/tests.rs b/compiler/rustc_mir_transform/src/coverage/counters/tests.rs new file mode 100644 index 00000000000..794d4358f82 --- /dev/null +++ b/compiler/rustc_mir_transform/src/coverage/counters/tests.rs @@ -0,0 +1,41 @@ +use std::fmt::Debug; + +use super::sort_and_cancel; + +fn flatten<T>(input: Vec<Option<T>>) -> Vec<T> { + input.into_iter().flatten().collect() +} + +fn sort_and_cancel_and_flatten<T: Clone + Ord>(pos: Vec<T>, neg: Vec<T>) -> (Vec<T>, Vec<T>) { + let (pos_actual, neg_actual) = sort_and_cancel(pos, neg); + (flatten(pos_actual), flatten(neg_actual)) +} + +#[track_caller] +fn check_test_case<T: Clone + Debug + Ord>( + pos: Vec<T>, + neg: Vec<T>, + pos_expected: Vec<T>, + neg_expected: Vec<T>, +) { + eprintln!("pos = {pos:?}; neg = {neg:?}"); + let output = sort_and_cancel_and_flatten(pos, neg); + assert_eq!(output, (pos_expected, neg_expected)); +} + +#[test] +fn cancellation() { + let cases: &[(Vec<u32>, Vec<u32>, Vec<u32>, Vec<u32>)] = &[ + (vec![], vec![], vec![], vec![]), + (vec![4, 2, 1, 5, 3], vec![], vec![1, 2, 3, 4, 5], vec![]), + (vec![5, 5, 5, 5, 5], vec![5], vec![5, 5, 5, 5], vec![]), + (vec![1, 1, 2, 2, 3, 3], vec![1, 2, 3], vec![1, 2, 3], vec![]), + (vec![1, 1, 2, 2, 3, 3], vec![2, 4, 2], vec![1, 1, 3, 3], vec![4]), + ]; + + for (pos, neg, pos_expected, neg_expected) in cases { + check_test_case(pos.to_vec(), neg.to_vec(), pos_expected.to_vec(), neg_expected.to_vec()); + // Same test case, but with its inputs flipped and its outputs flipped. + check_test_case(neg.to_vec(), pos.to_vec(), neg_expected.to_vec(), pos_expected.to_vec()); + } +} diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index e8b3d80be02..241c3c79114 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -25,7 +25,7 @@ use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, Pos, SourceFile, Span}; use tracing::{debug, debug_span, trace}; -use crate::coverage::counters::{CounterIncrementSite, CoverageCounters}; +use crate::coverage::counters::{CoverageCounters, Site}; use crate::coverage::graph::CoverageGraph; use crate::coverage::mappings::ExtractedMappings; @@ -265,13 +265,13 @@ fn inject_coverage_statements<'tcx>( coverage_counters: &CoverageCounters, ) { // Inject counter-increment statements into MIR. - for (id, counter_increment_site) in coverage_counters.counter_increment_sites() { + for (id, site) in coverage_counters.counter_increment_sites() { // Determine the block to inject a counter-increment statement into. // For BCB nodes this is just their first block, but for edges we need // to create a new block between the two BCBs, and inject into that. - let target_bb = match *counter_increment_site { - CounterIncrementSite::Node { bcb } => basic_coverage_blocks[bcb].leader_bb(), - CounterIncrementSite::Edge { from_bcb, to_bcb } => { + let target_bb = match site { + Site::Node { bcb } => basic_coverage_blocks[bcb].leader_bb(), + Site::Edge { from_bcb, to_bcb } => { // Create a new block between the last block of `from_bcb` and // the first block of `to_bcb`. let from_bb = basic_coverage_blocks[from_bcb].last_bb(); diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 0878fa26a92..79c38b50459 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -220,15 +220,7 @@ impl<'tcx> Inliner<'tcx> { // Normally, this shouldn't be required, but trait normalization failure can create a // validation ICE. - if !validate_types( - self.tcx, - MirPhase::Runtime(RuntimePhase::Optimized), - self.typing_env, - &callee_body, - &caller_body, - ) - .is_empty() - { + if !validate_types(self.tcx, self.typing_env, &callee_body, &caller_body).is_empty() { return Err("failed to validate callee body"); } diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index 779e7f22101..8a45ce0762d 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -292,7 +292,7 @@ fn run_passes_inner<'tcx>( } pub(super) fn validate_body<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when: String) { - validate::Validator { when, mir_phase: body.phase }.run_pass(tcx, body); + validate::Validator { when }.run_pass(tcx, body); } fn dump_mir_for_pass<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, pass_name: &str, is_after: bool) { diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 51e5c49cea1..404fbb6b839 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -29,12 +29,6 @@ enum EdgeKind { pub(super) struct Validator { /// Describes at which point in the pipeline this validation is happening. pub when: String, - /// The phase for which we are upholding the dialect. If the given phase forbids a specific - /// element, this validator will now emit errors if that specific element is encountered. - /// Note that phases that change the dialect cause all *following* phases to check the - /// invariants of the new dialect. A phase that changes dialects never checks the new invariants - /// itself. - pub mir_phase: MirPhase, } impl<'tcx> crate::MirPass<'tcx> for Validator { @@ -46,11 +40,9 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { if matches!(body.source.instance, InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..)) { return; } - debug_assert_eq!(self.mir_phase, body.phase); let def_id = body.source.def_id(); - let mir_phase = body.phase; let typing_env = body.typing_env(tcx); - let can_unwind = if mir_phase <= MirPhase::Runtime(RuntimePhase::Initial) { + let can_unwind = if body.phase <= MirPhase::Runtime(RuntimePhase::Initial) { // In this case `AbortUnwindingCalls` haven't yet been executed. true } else if !tcx.def_kind(def_id).is_fn_like() { @@ -64,9 +56,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { ty::Coroutine(..) => ExternAbi::Rust, // No need to do MIR validation on error bodies ty::Error(_) => return, - _ => { - span_bug!(body.span, "unexpected body ty: {:?} phase {:?}", body_ty, mir_phase) - } + _ => span_bug!(body.span, "unexpected body ty: {body_ty:?}"), }; ty::layout::fn_can_unwind(tcx, Some(def_id), body_abi) @@ -76,7 +66,6 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { when: &self.when, body, tcx, - mir_phase, unwind_edge_count: 0, reachable_blocks: traversal::reachable_as_bitset(body), value_cache: FxHashSet::default(), @@ -86,7 +75,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { cfg_checker.check_cleanup_control_flow(); // Also run the TypeChecker. - for (location, msg) in validate_types(tcx, self.mir_phase, typing_env, body, body) { + for (location, msg) in validate_types(tcx, typing_env, body, body) { cfg_checker.fail(location, msg); } @@ -107,7 +96,6 @@ struct CfgChecker<'a, 'tcx> { when: &'a str, body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, - mir_phase: MirPhase, unwind_edge_count: usize, reachable_blocks: BitSet<BasicBlock>, value_cache: FxHashSet<u128>, @@ -294,7 +282,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { match &statement.kind { StatementKind::AscribeUserType(..) => { - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( location, "`AscribeUserType` should have been removed after drop lowering phase", @@ -302,7 +290,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { } } StatementKind::FakeRead(..) => { - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( location, "`FakeRead` should have been removed after drop lowering phase", @@ -310,17 +298,17 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { } } StatementKind::SetDiscriminant { .. } => { - if self.mir_phase < MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) { self.fail(location, "`SetDiscriminant`is not allowed until deaggregation"); } } StatementKind::Deinit(..) => { - if self.mir_phase < MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) { self.fail(location, "`Deinit`is not allowed until deaggregation"); } } StatementKind::Retag(kind, _) => { - // FIXME(JakobDegen) The validator should check that `self.mir_phase < + // FIXME(JakobDegen) The validator should check that `self.body.phase < // DropsLowered`. However, this causes ICEs with generation of drop shims, which // seem to fail to set their `MirPhase` correctly. if matches!(kind, RetagKind::TwoPhase) { @@ -328,7 +316,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { } } StatementKind::Coverage(kind) => { - if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) + if self.body.phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) && let CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. } = kind { self.fail( @@ -391,7 +379,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { // the return edge from the call. FIXME(tmiasko): Since this is a strictly code // generation concern, the code generation should be responsible for handling // it. - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Optimized) + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Optimized) && self.is_critical_call_edge(target, unwind) { self.fail( @@ -440,7 +428,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { if self.body.coroutine.is_none() { self.fail(location, "`Yield` cannot appear outside coroutine bodies"); } - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail(location, "`Yield` should have been replaced by coroutine lowering"); } self.check_edge(location, *resume, EdgeKind::Normal); @@ -449,7 +437,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { } } TerminatorKind::FalseEdge { real_target, imaginary_target } => { - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( location, "`FalseEdge` should have been removed after drop elaboration", @@ -459,7 +447,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { self.check_edge(location, *imaginary_target, EdgeKind::Normal); } TerminatorKind::FalseUnwind { real_target, unwind } => { - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( location, "`FalseUnwind` should have been removed after drop elaboration", @@ -478,7 +466,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { if self.body.coroutine.is_none() { self.fail(location, "`CoroutineDrop` cannot appear outside coroutine bodies"); } - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( location, "`CoroutineDrop` should have been replaced by coroutine lowering", @@ -532,13 +520,11 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { /// `optimized_mir` is available. pub(super) fn validate_types<'tcx>( tcx: TyCtxt<'tcx>, - mir_phase: MirPhase, typing_env: ty::TypingEnv<'tcx>, body: &Body<'tcx>, caller_body: &Body<'tcx>, ) -> Vec<(Location, String)> { - let mut type_checker = - TypeChecker { body, caller_body, tcx, typing_env, mir_phase, failures: Vec::new() }; + let mut type_checker = TypeChecker { body, caller_body, tcx, typing_env, failures: Vec::new() }; type_checker.visit_body(body); type_checker.failures } @@ -548,7 +534,6 @@ struct TypeChecker<'a, 'tcx> { caller_body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, - mir_phase: MirPhase, failures: Vec<(Location, String)>, } @@ -577,7 +562,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // After borrowck subtyping should be fully explicit via // `Subtype` projections. - let variance = if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + let variance = if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { Variance::Invariant } else { Variance::Covariant @@ -618,13 +603,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { // This check is somewhat expensive, so only run it when -Zvalidate-mir is passed. if self.tcx.sess.opts.unstable_opts.validate_mir - && self.mir_phase < MirPhase::Runtime(RuntimePhase::Initial) + && self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) { // `Operand::Copy` is only supposed to be used with `Copy` types. if let Operand::Copy(place) = operand { let ty = place.ty(&self.body.local_decls, self.tcx).ty; - if !ty.is_copy_modulo_regions(self.tcx, self.typing_env) { + if !self.tcx.type_is_copy_modulo_regions(self.typing_env, ty) { self.fail(location, format!("`Operand::Copy` with non-`Copy` type {ty}")); } } @@ -642,7 +627,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ) { match elem { ProjectionElem::OpaqueCast(ty) - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) => + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) => { self.fail( location, @@ -656,7 +641,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } ProjectionElem::Deref - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::PostCleanup) => + if self.body.phase >= MirPhase::Runtime(RuntimePhase::PostCleanup) => { let base_ty = place_ref.ty(&self.body.local_decls, self.tcx).ty; @@ -856,7 +841,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // Set off any `bug!`s in the type computation code let _ = place.ty(&self.body.local_decls, self.tcx); - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) && place.projection.len() > 1 && cntxt != PlaceContext::NonUse(NonUseContext::VarDebugInfo) && place.projection[1..].contains(&ProjectionElem::Deref) @@ -974,7 +959,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } AggregateKind::RawPtr(pointee_ty, mutability) => { - if !matches!(self.mir_phase, MirPhase::Runtime(_)) { + if !matches!(self.body.phase, MirPhase::Runtime(_)) { // It would probably be fine to support this in earlier phases, but at the // time of writing it's only ever introduced from intrinsic lowering, so // earlier things just `bug!` on it. @@ -1016,7 +1001,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } }, Rvalue::Ref(_, BorrowKind::Fake(_), _) => { - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( location, "`Assign` statement with a `Fake` borrow should have been removed in runtime MIR", @@ -1130,7 +1115,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } UnOp::PtrMetadata => { - if !matches!(self.mir_phase, MirPhase::Runtime(_)) { + if !matches!(self.body.phase, MirPhase::Runtime(_)) { // It would probably be fine to support this in earlier phases, but at // the time of writing it's only ever introduced from intrinsic // lowering or other runtime-phase optimization passes, so earlier @@ -1206,7 +1191,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { "CastKind::{kind:?} output must be a raw const pointer, not {:?}", ty::RawPtr(_, Mutability::Not) ); - if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) { + if self.body.phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) { self.fail(location, format!("After borrowck, MIR disallows {kind:?}")); } } @@ -1222,7 +1207,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { "CastKind::{kind:?} output must be a raw pointer, not {:?}", ty::RawPtr(..) ); - if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) { + if self.body.phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) { self.fail(location, format!("After borrowck, MIR disallows {kind:?}")); } } @@ -1288,7 +1273,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } CastKind::Transmute => { - if let MirPhase::Runtime(..) = self.mir_phase { + if let MirPhase::Runtime(..) = self.body.phase { // Unlike `mem::transmute`, a MIR `Transmute` is well-formed // for any two `Sized` types, just potentially UB to run. @@ -1317,7 +1302,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { location, format!( "Transmute is not supported in non-runtime phase {:?}.", - self.mir_phase + self.body.phase ), ); } @@ -1404,7 +1389,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } StatementKind::AscribeUserType(..) => { - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( location, "`AscribeUserType` should have been removed after drop lowering phase", @@ -1412,7 +1397,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } StatementKind::FakeRead(..) => { - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( location, "`FakeRead` should have been removed after drop lowering phase", @@ -1463,7 +1448,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } StatementKind::SetDiscriminant { place, .. } => { - if self.mir_phase < MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) { self.fail(location, "`SetDiscriminant`is not allowed until deaggregation"); } let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind(); @@ -1477,12 +1462,12 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } StatementKind::Deinit(..) => { - if self.mir_phase < MirPhase::Runtime(RuntimePhase::Initial) { + if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) { self.fail(location, "`Deinit`is not allowed until deaggregation"); } } StatementKind::Retag(kind, _) => { - // FIXME(JakobDegen) The validator should check that `self.mir_phase < + // FIXME(JakobDegen) The validator should check that `self.body.phase < // DropsLowered`. However, this causes ICEs with generation of drop shims, which // seem to fail to set their `MirPhase` correctly. if matches!(kind, RetagKind::TwoPhase) { diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index b9a325eddd8..e5cd4622dae 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -343,6 +343,9 @@ parse_incorrect_semicolon = .suggestion = remove this semicolon .help = {$name} declarations are not followed by a semicolon +parse_incorrect_type_on_self = type not allowed for shorthand `self` parameter + .suggestion = move the modifiers on `self` to the type + parse_incorrect_use_of_await = incorrect use of `await` .parentheses_suggestion = `await` is not a method call, remove the parentheses diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 91e8ba2e1f9..14f2dd32e92 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -3,6 +3,7 @@ use std::borrow::Cow; use rustc_ast::token::Token; +use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::{Path, Visibility}; use rustc_errors::codes::*; use rustc_errors::{ @@ -2686,7 +2687,7 @@ pub(crate) struct UnexpectedExpressionInPattern { /// Was a `RangePatternBound` expected? pub is_bound: bool, /// The unexpected expr's precedence (used in match arm guard suggestions). - pub expr_precedence: i8, + pub expr_precedence: ExprPrecedence, } #[derive(Subdiagnostic)] @@ -3408,3 +3409,22 @@ pub(crate) struct PolarityAndModifiers { pub polarity: &'static str, pub modifiers_concatenated: String, } + +#[derive(Diagnostic)] +#[diag(parse_incorrect_type_on_self)] +pub(crate) struct IncorrectTypeOnSelf { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub move_self_modifier: MoveSelfModifier, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +pub(crate) struct MoveSelfModifier { + #[suggestion_part(code = "")] + pub removal_span: Span, + #[suggestion_part(code = "{modifier}")] + pub insertion_span: Span, + pub modifier: String, +} diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 4430d2d1431..8d16d44b0a2 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1,7 +1,7 @@ // ignore-tidy-filelength use core::mem; -use core::ops::ControlFlow; +use core::ops::{Bound, ControlFlow}; use ast::mut_visit::{self, MutVisitor}; use ast::token::IdentIsRaw; @@ -10,7 +10,7 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::util::classify; -use rustc_ast::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par}; +use rustc_ast::util::parser::{AssocOp, ExprPrecedence, Fixity, prec_let_scrutinee_needs_par}; use rustc_ast::visit::{Visitor, walk_expr}; use rustc_ast::{ self as ast, AnonConst, Arm, AttrStyle, AttrVec, BinOp, BinOpKind, BlockCheckMode, CaptureBy, @@ -120,7 +120,7 @@ impl<'a> Parser<'a> { r: Restrictions, attrs: AttrWrapper, ) -> PResult<'a, (P<Expr>, bool)> { - self.with_res(r, |this| this.parse_expr_assoc_with(0, attrs)) + self.with_res(r, |this| this.parse_expr_assoc_with(Bound::Unbounded, attrs)) } /// Parses an associative expression with operators of at least `min_prec` precedence. @@ -128,7 +128,7 @@ impl<'a> Parser<'a> { /// followed by a subexpression (e.g. `1 + 2`). pub(super) fn parse_expr_assoc_with( &mut self, - min_prec: usize, + min_prec: Bound<ExprPrecedence>, attrs: AttrWrapper, ) -> PResult<'a, (P<Expr>, bool)> { let lhs = if self.token.is_range_separator() { @@ -144,7 +144,7 @@ impl<'a> Parser<'a> { /// was actually parsed. pub(super) fn parse_expr_assoc_rest_with( &mut self, - min_prec: usize, + min_prec: Bound<ExprPrecedence>, starts_stmt: bool, mut lhs: P<Expr>, ) -> PResult<'a, (P<Expr>, bool)> { @@ -163,7 +163,11 @@ impl<'a> Parser<'a> { self.restrictions }; let prec = op.node.precedence(); - if prec < min_prec { + if match min_prec { + Bound::Included(min_prec) => prec < min_prec, + Bound::Excluded(min_prec) => prec <= min_prec, + Bound::Unbounded => false, + } { break; } // Check for deprecated `...` syntax @@ -276,16 +280,16 @@ impl<'a> Parser<'a> { } let fixity = op.fixity(); - let prec_adjustment = match fixity { - Fixity::Right => 0, - Fixity::Left => 1, + let min_prec = match fixity { + Fixity::Right => Bound::Included(prec), + Fixity::Left => Bound::Excluded(prec), // We currently have no non-associative operators that are not handled above by // the special cases. The code is here only for future convenience. - Fixity::None => 1, + Fixity::None => Bound::Excluded(prec), }; let (rhs, _) = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| { let attrs = this.parse_outer_attributes()?; - this.parse_expr_assoc_with(prec + prec_adjustment, attrs) + this.parse_expr_assoc_with(min_prec, attrs) })?; let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span); @@ -451,7 +455,7 @@ impl<'a> Parser<'a> { /// The other two variants are handled in `parse_prefix_range_expr` below. fn parse_expr_range( &mut self, - prec: usize, + prec: ExprPrecedence, lhs: P<Expr>, op: AssocOp, cur_op_span: Span, @@ -460,7 +464,7 @@ impl<'a> Parser<'a> { let maybe_lt = self.token.clone(); let attrs = self.parse_outer_attributes()?; Some( - self.parse_expr_assoc_with(prec + 1, attrs) + self.parse_expr_assoc_with(Bound::Excluded(prec), attrs) .map_err(|err| self.maybe_err_dotdotlt_syntax(maybe_lt, err))? .0, ) @@ -518,7 +522,7 @@ impl<'a> Parser<'a> { let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() { // RHS must be parsed with more associativity than the dots. let attrs = this.parse_outer_attributes()?; - this.parse_expr_assoc_with(op.unwrap().precedence() + 1, attrs) + this.parse_expr_assoc_with(Bound::Excluded(op.unwrap().precedence()), attrs) .map(|(x, _)| (lo.to(x.span), Some(x))) .map_err(|err| this.maybe_err_dotdotlt_syntax(maybe_lt, err))? } else { @@ -2643,7 +2647,8 @@ impl<'a> Parser<'a> { self.expect(&token::Eq)?; } let attrs = self.parse_outer_attributes()?; - let (expr, _) = self.parse_expr_assoc_with(1 + prec_let_scrutinee_needs_par(), attrs)?; + let (expr, _) = + self.parse_expr_assoc_with(Bound::Excluded(prec_let_scrutinee_needs_par()), attrs)?; let span = lo.to(expr.span); Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span, recovered))) } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 26e81b7676b..475cd09147f 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2941,6 +2941,32 @@ impl<'a> Parser<'a> { }; Ok((eself, eself_ident, eself_hi)) }; + let expect_self_ident_not_typed = + |this: &mut Self, modifier: &SelfKind, modifier_span: Span| { + let eself_ident = expect_self_ident(this); + + // Recover `: Type` after a qualified self + if this.may_recover() && this.eat_noexpect(&token::Colon) { + let snap = this.create_snapshot_for_diagnostic(); + match this.parse_ty() { + Ok(ty) => { + this.dcx().emit_err(errors::IncorrectTypeOnSelf { + span: ty.span, + move_self_modifier: errors::MoveSelfModifier { + removal_span: modifier_span, + insertion_span: ty.span.shrink_to_lo(), + modifier: modifier.to_ref_suggestion(), + }, + }); + } + Err(diag) => { + diag.cancel(); + this.restore_snapshot(snap); + } + } + } + eself_ident + }; // Recover for the grammar `*self`, `*const self`, and `*mut self`. let recover_self_ptr = |this: &mut Self| { this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span }); @@ -2978,7 +3004,9 @@ impl<'a> Parser<'a> { // `¬_self` return Ok(None); }; - (eself, expect_self_ident(self), self.prev_token.span) + let hi = self.token.span; + let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi)); + (eself, self_ident, hi) } // `*self` token::BinOp(token::Star) if is_isolated_self(self, 1) => { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 0ed8d152d2d..37556c064d8 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1376,7 +1376,7 @@ impl<'a> Parser<'a> { AttrArgs::Delimited(args) } else if self.eat(&token::Eq) { let eq_span = self.prev_token.span; - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(self.parse_expr_force_collect()?)) + AttrArgs::Eq { eq_span, value: AttrArgsEq::Ast(self.parse_expr_force_collect()?) } } else { AttrArgs::Empty }) diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index bb976e092bf..e08b925f008 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -1,12 +1,13 @@ +use std::ops::Bound; + use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::ptr::P; use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token}; -use rustc_ast::util::parser::AssocOp; +use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{ - self as ast, Arm, AttrVec, BinOpKind, BindingMode, ByRef, Expr, ExprKind, LocalKind, MacCall, - Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt, - StmtKind, + self as ast, Arm, AttrVec, BindingMode, ByRef, Expr, ExprKind, LocalKind, MacCall, Mutability, + Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt, StmtKind, }; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey}; @@ -435,8 +436,9 @@ impl<'a> Parser<'a> { // Parse an associative expression such as `+ expr`, `% expr`, ... // Assignments, ranges and `|` are disabled by [`Restrictions::IS_PAT`]. - let Ok((expr, _)) = - snapshot.parse_expr_assoc_rest_with(0, false, expr).map_err(|err| err.cancel()) + let Ok((expr, _)) = snapshot + .parse_expr_assoc_rest_with(Bound::Unbounded, false, expr) + .map_err(|err| err.cancel()) else { // We got a trailing method/operator, but that wasn't an expression. return None; @@ -545,10 +547,7 @@ impl<'a> Parser<'a> { // HACK: a neater way would be preferable. let expr = match &err.args["expr_precedence"] { DiagArgValue::Number(expr_precedence) => { - if *expr_precedence - <= AssocOp::from_ast_binop(BinOpKind::Eq).precedence() - as i32 - { + if *expr_precedence <= ExprPrecedence::Compare as i32 { format!("({expr})") } else { format!("{expr}") @@ -570,9 +569,7 @@ impl<'a> Parser<'a> { } Some(guard) => { // Are parentheses required around the old guard? - let wrap_guard = guard.precedence() - <= AssocOp::from_ast_binop(BinOpKind::And).precedence() - as i8; + let wrap_guard = guard.precedence() <= ExprPrecedence::LAnd; err.subdiagnostic( UnexpectedExpressionInPatternSugg::UpdateGuard { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 190cd9ed061..5fa2e01fc86 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; use std::mem; +use std::ops::Bound; use ast::Label; use rustc_ast as ast; @@ -207,7 +208,7 @@ impl<'a> Parser<'a> { // Perform this outside of the `collect_tokens` closure, since our // outer attributes do not apply to this part of the expression. let (expr, _) = self.with_res(Restrictions::STMT_EXPR, |this| { - this.parse_expr_assoc_rest_with(0, true, expr) + this.parse_expr_assoc_rest_with(Bound::Unbounded, true, expr) })?; Ok(self.mk_stmt(lo.to(self.prev_token.span), StmtKind::Expr(expr))) } else { @@ -240,7 +241,7 @@ impl<'a> Parser<'a> { let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac)); let e = self.maybe_recover_from_bad_qpath(e)?; let e = self.parse_expr_dot_or_call_with(attrs, e, lo)?; - let (e, _) = self.parse_expr_assoc_rest_with(0, false, e)?; + let (e, _) = self.parse_expr_assoc_rest_with(Bound::Unbounded, false, e)?; StmtKind::Expr(e) }; Ok(self.mk_stmt(lo.to(hi), kind)) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 505586e74f1..8cff23c2e32 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -9,7 +9,7 @@ use rustc_ast::{ }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{Ident, kw, sym}; -use rustc_span::{ErrorGuaranteed, Span, Symbol}; +use rustc_span::{ErrorGuaranteed, Span}; use thin_vec::{ThinVec, thin_vec}; use super::{Parser, PathStyle, SeqSep, TokenType, Trailing}; @@ -940,7 +940,7 @@ impl<'a> Parser<'a> { let asyncness = if self.token.uninterpolated_span().at_least_rust_2018() && self.eat_keyword(kw::Async) { - self.psess.gated_spans.gate(sym::async_closure, self.prev_token.span); + self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span); BoundAsyncness::Async(self.prev_token.span) } else if self.may_recover() && self.token.uninterpolated_span().is_rust_2015() @@ -951,7 +951,7 @@ impl<'a> Parser<'a> { span: self.prev_token.span, help: HelpUseLatestEdition::new(), }); - self.psess.gated_spans.gate(sym::async_closure, self.prev_token.span); + self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span); BoundAsyncness::Async(self.prev_token.span) } else { BoundAsyncness::Normal @@ -1136,7 +1136,7 @@ impl<'a> Parser<'a> { Some(ast::Path { span: fn_token_span.to(self.prev_token.span), segments: thin_vec![ast::PathSegment { - ident: Ident::new(Symbol::intern("Fn"), fn_token_span), + ident: Ident::new(sym::Fn, fn_token_span), id: DUMMY_NODE_ID, args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs { span: args_lo.to(self.prev_token.span), diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index f3174e7dea2..aab3f10bc66 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -43,7 +43,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { } } _ => { - if let AttrArgs::Eq(..) = attr_item.args { + if let AttrArgs::Eq { .. } = attr_item.args { // All key-value attributes are restricted to meta-item syntax. match parse_meta(psess, attr) { Ok(_) => {} @@ -70,7 +70,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met parse_in(psess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?; MetaItemKind::List(nmis) } - AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => { + AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => { if let ast::ExprKind::Lit(token_lit) = expr.kind { let res = ast::MetaItemLit::from_token_lit(token_lit, expr.span); let res = match res { @@ -116,7 +116,9 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met return Err(err); } } - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()), + AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => { + MetaItemKind::NameValue(lit.clone()) + } }, }) } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 0712af422ad..7a0a518bb51 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -709,8 +709,6 @@ passes_should_be_applied_to_trait = attribute should be applied to a trait .label = not a trait -passes_skipping_const_checks = skipping const checks - passes_stability_promotable = attribute cannot be applied to an expression diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs deleted file mode 100644 index f5ece513956..00000000000 --- a/compiler/rustc_passes/src/check_const.rs +++ /dev/null @@ -1,236 +0,0 @@ -//! This pass checks HIR bodies that may be evaluated at compile-time (e.g., `const`, `static`, -//! `const fn`) for structured control flow (e.g. `if`, `while`), which is forbidden in a const -//! context. -//! -//! By the time the MIR const-checker runs, these high-level constructs have been lowered to -//! control-flow primitives (e.g., `Goto`, `SwitchInt`), making it tough to properly attribute -//! errors. We still look for those primitives in the MIR const-checker to ensure nothing slips -//! through, but errors for structured control flow in a `const` should be emitted here. - -use rustc_hir::def_id::{LocalDefId, LocalModDefId}; -use rustc_hir::intravisit::{self, Visitor}; -use rustc_middle::hir::nested_filter; -use rustc_middle::query::Providers; -use rustc_middle::span_bug; -use rustc_middle::ty::TyCtxt; -use rustc_session::parse::feature_err; -use rustc_span::{Span, Symbol, sym}; -use {rustc_attr as attr, rustc_hir as hir}; - -use crate::errors::SkippingConstChecks; - -/// An expression that is not *always* legal in a const context. -#[derive(Clone, Copy)] -enum NonConstExpr { - Loop(hir::LoopSource), - Match(hir::MatchSource), -} - -impl NonConstExpr { - fn name(self) -> String { - match self { - Self::Loop(src) => format!("`{}`", src.name()), - Self::Match(src) => format!("`{}`", src.name()), - } - } - - fn required_feature_gates(self) -> Option<&'static [Symbol]> { - use hir::LoopSource::*; - use hir::MatchSource::*; - - let gates: &[_] = match self { - Self::Match(AwaitDesugar) => { - return None; - } - - Self::Loop(ForLoop) | Self::Match(ForLoopDesugar) => &[sym::const_for], - - Self::Match(TryDesugar(_)) => &[sym::const_try], - - // All other expressions are allowed. - Self::Loop(Loop | While) | Self::Match(Normal | Postfix | FormatArgs) => &[], - }; - - Some(gates) - } -} - -fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { - let mut vis = CheckConstVisitor::new(tcx); - tcx.hir().visit_item_likes_in_module(module_def_id, &mut vis); -} - -pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { check_mod_const_bodies, ..*providers }; -} - -#[derive(Copy, Clone)] -struct CheckConstVisitor<'tcx> { - tcx: TyCtxt<'tcx>, - const_kind: Option<hir::ConstContext>, - def_id: Option<LocalDefId>, -} - -impl<'tcx> CheckConstVisitor<'tcx> { - fn new(tcx: TyCtxt<'tcx>) -> Self { - CheckConstVisitor { tcx, const_kind: None, def_id: None } - } - - /// Emits an error when an unsupported expression is found in a const context. - #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable - fn const_check_violated(&self, expr: NonConstExpr, span: Span) { - let Self { tcx, def_id, const_kind } = *self; - - let features = tcx.features(); - let required_gates = expr.required_feature_gates(); - - let is_feature_allowed = |feature_gate| { - // All features require that the corresponding gate be enabled, - // even if the function has `#[rustc_allow_const_fn_unstable(the_gate)]`. - if !tcx.features().enabled(feature_gate) { - return false; - } - - // If `def_id` is `None`, we don't need to consider stability attributes. - let def_id = match def_id { - Some(x) => x, - None => return true, - }; - - // If the function belongs to a trait, then it must enable the const_trait_impl - // feature to use that trait function (with a const default body). - if tcx.trait_of_item(def_id.to_def_id()).is_some() { - return true; - } - - // If this crate is not using stability attributes, or this function is not claiming to be a - // stable `const fn`, that is all that is required. - if !tcx.features().staged_api() || tcx.has_attr(def_id, sym::rustc_const_unstable) { - return true; - } - - // However, we cannot allow stable `const fn`s to use unstable features without an explicit - // opt-in via `rustc_allow_const_fn_unstable`. - let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(def_id)); - attr::rustc_allow_const_fn_unstable(tcx.sess, attrs).any(|name| name == feature_gate) - }; - - match required_gates { - // Don't emit an error if the user has enabled the requisite feature gates. - Some(gates) if gates.iter().copied().all(is_feature_allowed) => return, - - // `-Zunleash-the-miri-inside-of-you` only works for expressions that don't have a - // corresponding feature gate. This encourages nightly users to use feature gates when - // possible. - None if tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you => { - tcx.dcx().emit_warn(SkippingConstChecks { span }); - return; - } - - _ => {} - } - - let const_kind = - const_kind.expect("`const_check_violated` may only be called inside a const context"); - - let required_gates = required_gates.unwrap_or(&[]); - let missing_gates: Vec<_> = - required_gates.iter().copied().filter(|&g| !features.enabled(g)).collect(); - - match missing_gates.as_slice() { - [] => { - span_bug!( - span, - "we should not have reached this point, since `.await` is denied earlier" - ); - } - - [missing_primary, ref missing_secondary @ ..] => { - let msg = - format!("{} is not allowed in a `{}`", expr.name(), const_kind.keyword_name()); - let mut err = feature_err(&tcx.sess, *missing_primary, span, msg); - - // If multiple feature gates would be required to enable this expression, include - // them as help messages. Don't emit a separate error for each missing feature gate. - // - // FIXME(ecstaticmorse): Maybe this could be incorporated into `feature_err`? This - // is a pretty narrow case, however. - tcx.disabled_nightly_features( - &mut err, - def_id.map(|id| tcx.local_def_id_to_hir_id(id)), - missing_secondary.into_iter().map(|gate| (String::new(), *gate)), - ); - - err.emit(); - } - } - } - - /// Saves the parent `const_kind` before calling `f` and restores it afterwards. - fn recurse_into( - &mut self, - kind: Option<hir::ConstContext>, - def_id: Option<LocalDefId>, - f: impl FnOnce(&mut Self), - ) { - let parent_def_id = self.def_id; - let parent_kind = self.const_kind; - self.def_id = def_id; - self.const_kind = kind; - f(self); - self.def_id = parent_def_id; - self.const_kind = parent_kind; - } -} - -impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { - type NestedFilter = nested_filter::OnlyBodies; - - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() - } - - fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) { - let kind = Some(hir::ConstContext::Const { inline: false }); - self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon)); - } - - fn visit_inline_const(&mut self, block: &'tcx hir::ConstBlock) { - let kind = Some(hir::ConstContext::Const { inline: true }); - self.recurse_into(kind, None, |this| intravisit::walk_inline_const(this, block)); - } - - fn visit_body(&mut self, body: &hir::Body<'tcx>) { - let owner = self.tcx.hir().body_owner_def_id(body.id()); - let kind = self.tcx.hir().body_const_context(owner); - self.recurse_into(kind, Some(owner), |this| intravisit::walk_body(this, body)); - } - - fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) { - match &e.kind { - // Skip the following checks if we are not currently in a const context. - _ if self.const_kind.is_none() => {} - - hir::ExprKind::Loop(_, _, source, _) => { - self.const_check_violated(NonConstExpr::Loop(*source), e.span); - } - - hir::ExprKind::Match(_, _, source) => { - let non_const_expr = match source { - // These are handled by `ExprKind::Loop` above. - hir::MatchSource::ForLoopDesugar => None, - - _ => Some(NonConstExpr::Match(*source)), - }; - - if let Some(expr) = non_const_expr { - self.const_check_violated(expr, e.span); - } - } - - _ => {} - } - - intravisit::walk_expr(self, e); - } -} diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index fbf25cb476a..fdc7e1bba2f 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1670,13 +1670,6 @@ pub(crate) struct ProcMacroBadSig { pub kind: ProcMacroKind, } -#[derive(Diagnostic)] -#[diag(passes_skipping_const_checks)] -pub(crate) struct SkippingConstChecks { - #[primary_span] - pub span: Span, -} - #[derive(LintDiagnostic)] #[diag(passes_unreachable_due_to_uninhabited)] pub(crate) struct UnreachableDueToUninhabited<'desc, 'tcx> { diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 8f53b71319d..1aa077ad2bb 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -19,7 +19,6 @@ use rustc_middle::query::Providers; pub mod abi_test; mod check_attr; -mod check_const; pub mod dead; mod debugger_visualizer; mod diagnostic_items; @@ -43,7 +42,6 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" } pub fn provide(providers: &mut Providers) { check_attr::provide(providers); - check_const::provide(providers); dead::provide(providers); debugger_visualizer::provide(providers); diagnostic_items::provide(providers); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 663c3ac0045..09f3e848766 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3113,6 +3113,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } + #[cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))] let existing_name = match &in_scope_lifetimes[..] { [] => Symbol::intern("'a"), [(existing, _)] => existing.name, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 094871ad268..ca4adce37ce 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2257,7 +2257,7 @@ fn module_to_string(module: Module<'_>) -> Option<String> { collect_mod(names, parent); } } else { - names.push(Symbol::intern("<opaque>")); + names.push(sym::opaque_module_name_placeholder); collect_mod(names, module.parent.unwrap()); } } diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 02e255d7726..65128ceb866 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -220,9 +220,9 @@ pub fn attrs_to_doc_fragments<'a>( fn span_for_value(attr: &ast::Attribute) -> Span { if let ast::AttrKind::Normal(normal) = &attr.kind - && let ast::AttrArgs::Eq(_, ast::AttrArgsEq::Hir(meta)) = &normal.item.args + && let ast::AttrArgs::Eq { value, .. } = &normal.item.args { - meta.span.with_ctxt(attr.span.ctxt()) + value.span().with_ctxt(attr.span.ctxt()) } else { attr.span } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 25f75ae12e8..2c0302bbb2b 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1702,6 +1702,8 @@ options! { "threshold to allow cross crate inlining of functions"), debug_info_for_profiling: bool = (false, parse_bool, [TRACKED], "emit discriminators and other data necessary for AutoFDO"), + debug_info_type_line_numbers: bool = (false, parse_bool, [TRACKED], + "emit type and line information for additional data types (default: no)"), debuginfo_compression: DebugInfoCompression = (DebugInfoCompression::None, parse_debuginfo_compression, [TRACKED], "compress debug info sections (none, zlib, zstd, default: none)"), deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED], @@ -2036,8 +2038,6 @@ written to standard error output)"), "make the current crate share its generic instantiations"), shell_argfiles: bool = (false, parse_bool, [UNTRACKED], "allow argument files to be specified with POSIX \"shell-style\" argument quoting"), - show_span: Option<String> = (None, parse_opt_string, [TRACKED], - "show spans in the crate root file, for compiler debugging (expr|pat|ty)"), simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], "simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \ to rust's source base directory. only meant for testing purposes"), diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index 357d746c184..2b2ba50d3fb 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -87,7 +87,7 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol { } } - Symbol::intern("rust_out") + sym::rust_out } pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index f585410adb9..120ae9946ea 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1358,6 +1358,12 @@ pub struct EarlyDiagCtxt { dcx: DiagCtxt, } +impl Default for EarlyDiagCtxt { + fn default() -> Self { + Self::new(ErrorOutputType::default()) + } +} + impl EarlyDiagCtxt { pub fn new(output: ErrorOutputType) -> Self { let emitter = mk_emitter(output); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index e94c0a5ea6e..47ceab750cf 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -298,6 +298,7 @@ symbols! { Return, Right, Rust, + RustaceansAreAwesome, RustcDecodable, RustcEncodable, RwLock, @@ -316,6 +317,7 @@ symbols! { StructuralPartialEq, SubdiagMessage, Subdiagnostic, + SymbolIntern, Sync, SyncUnsafeCell, T, @@ -377,6 +379,7 @@ symbols! { adt_const_params, advanced_slice_patterns, adx_target_feature, + aes, aggregate_raw_ptr, alias, align, @@ -440,6 +443,7 @@ symbols! { associated_types, assume, assume_init, + asterisk: "*", async_await, async_call, async_call_mut, @@ -468,6 +472,7 @@ symbols! { async_for_loop, async_iterator, async_iterator_poll_next, + async_trait_bounds, atomic, atomic_mod, atomics, @@ -520,6 +525,7 @@ symbols! { btreeset_iter, builtin_syntax, c, + c_dash_variadic, c_str, c_str_literals, c_unwind, @@ -650,6 +656,7 @@ symbols! { const_trait_bound_opt_out, const_trait_impl, const_try, + const_ty_placeholder: "<const_ty>", constant, constructor, convert_identity, @@ -779,6 +786,7 @@ symbols! { drop_types_in_const, dropck_eyepatch, dropck_parametricity, + dummy_cgu_name, dylib, dyn_compatible_for_dispatch, dyn_metadata, @@ -922,6 +930,7 @@ symbols! { fmuladdf32, fmuladdf64, fn_align, + fn_body, fn_delegation, fn_must_use, fn_mut, @@ -962,6 +971,7 @@ symbols! { fs_create_dir, fsub_algebraic, fsub_fast, + fsxr, full, fundamental, fused_iterator, @@ -1385,6 +1395,7 @@ symbols! { on, on_unimplemented, opaque, + opaque_module_name_placeholder: "<opaque>", open_options_new, ops, opt_out_copy, @@ -1654,6 +1665,7 @@ symbols! { rust_eh_catch_typeinfo, rust_eh_personality, rust_logo, + rust_out, rustc, rustc_abi, rustc_allocator, @@ -1776,6 +1788,8 @@ symbols! { self_in_typedefs, self_struct_ctor, semitransparent, + sha2, + sha3, sha512_sm_x86, shadow_call_stack, shallow, @@ -1844,6 +1858,7 @@ symbols! { simd_reduce_mul_unordered, simd_reduce_or, simd_reduce_xor, + simd_relaxed_fma, simd_rem, simd_round, simd_saturating_add, @@ -1889,6 +1904,7 @@ symbols! { sreg, sreg_low16, sse, + sse2, sse4a_target_feature, stable, staged_api, @@ -2176,6 +2192,7 @@ symbols! { wrapping_sub, wreg, write_bytes, + write_fmt, write_macro, write_str, write_via_move, @@ -2405,6 +2422,7 @@ impl Symbol { } /// Maps a string to its interned representation. + #[rustc_diagnostic_item = "SymbolIntern"] pub fn intern(string: &str) -> Self { with_session_globals(|session_globals| session_globals.symbol_interner.intern(string)) } diff --git a/compiler/rustc_target/src/spec/base/aix.rs b/compiler/rustc_target/src/spec/base/aix.rs index 1869369b9e3..fe37d313294 100644 --- a/compiler/rustc_target/src/spec/base/aix.rs +++ b/compiler/rustc_target/src/spec/base/aix.rs @@ -4,7 +4,7 @@ use crate::spec::{Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, cr pub(crate) fn opts() -> TargetOptions { TargetOptions { abi: "vec-extabi".into(), - code_model: Some(CodeModel::Small), + code_model: Some(CodeModel::Large), cpu: "pwr7".into(), os: "aix".into(), vendor: "ibm".into(), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 9b969dd3e43..90b18253629 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -794,7 +794,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { closure_def_id, found_kind, expected_kind, - "async ", + "Async", ); self.note_obligation_cause(&mut err, &obligation); self.point_at_returns_when_relevant(&mut err, &obligation); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 7f42c932fcf..f10314c1c9e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -1,7 +1,7 @@ use std::iter; use std::path::PathBuf; -use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, MetaItemInner}; +use rustc_ast::{AttrArgs, AttrKind, Attribute, MetaItemInner}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::codes::*; use rustc_errors::{ErrorGuaranteed, struct_span_code_err}; @@ -639,8 +639,7 @@ impl<'tcx> OnUnimplementedDirective { let report_span = match &item.args { AttrArgs::Empty => item.path.span, AttrArgs::Delimited(args) => args.dspan.entire(), - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => eq_span.to(expr.span), - AttrArgs::Eq(span, AttrArgsEq::Hir(expr)) => span.to(expr.span), + AttrArgs::Eq { eq_span, value } => eq_span.to(value.span()), }; if let Some(item_def_id) = item_def_id.as_local() { diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 43244eb5dcb..ee708564a80 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -35,7 +35,7 @@ impl<'tcx> InferCtxt<'tcx> { // FIXME(#132279): This should be removed as it causes us to incorrectly // handle opaques in their defining scope. if !(param_env, ty).has_infer() { - return ty.is_copy_modulo_regions(self.tcx, self.typing_env(param_env)); + return self.tcx.type_is_copy_modulo_regions(self.typing_env(param_env), ty); } let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, None); diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 0f90c45d032..2b2623a050e 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -199,6 +199,10 @@ where errors } + fn has_pending_obligations(&self) -> bool { + !self.obligations.pending.is_empty() || !self.obligations.overflowed.is_empty() + } + fn pending_obligations(&self) -> PredicateObligations<'tcx> { self.obligations.clone_pending() } diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index e0a9ddf1876..c9297027519 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -18,7 +18,6 @@ use rustc_middle::ty::{ TypeVisitableExt, TypeVisitor, TypingMode, Upcast, }; use rustc_span::Span; -use rustc_span::symbol::Symbol; use smallvec::SmallVec; use tracing::{debug, instrument}; @@ -329,10 +328,7 @@ pub fn dyn_compatibility_violations_for_assoc_item( .collect(), // Associated types can only be dyn-compatible if they have `Self: Sized` bounds. ty::AssocKind::Type => { - if !tcx.features().generic_associated_types_extended() - && !tcx.generics_of(item.def_id).is_own_empty() - && !item.is_impl_trait_in_trait() - { + if !tcx.generics_of(item.def_id).is_own_empty() && !item.is_impl_trait_in_trait() { vec![DynCompatibilityViolation::GAT(item.name, item.ident(tcx).span)] } else { // We will permit associated types if they are explicitly mentioned in the trait object. @@ -679,7 +675,7 @@ fn receiver_is_dispatchable<'tcx>( // FIXME(mikeyhew) this is a total hack. Once dyn_compatible_for_dispatch is stabilized, we can // replace this with `dyn Trait` let unsized_self_ty: Ty<'tcx> = - Ty::new_param(tcx, u32::MAX, Symbol::intern("RustaceansAreAwesome")); + Ty::new_param(tcx, u32::MAX, rustc_span::sym::RustaceansAreAwesome); // `Receiver[Self => U]` let unsized_receiver_ty = diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 03e483f555d..7529ee128f5 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -213,6 +213,10 @@ where } } + fn has_pending_obligations(&self) -> bool { + self.predicates.has_pending_obligations() + } + fn pending_obligations(&self) -> PredicateObligations<'tcx> { self.predicates.map_pending_obligations(|o| o.obligation.clone()) } diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index e99c5eacbd8..ad62b456ad4 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -7,6 +7,7 @@ use rustc_infer::traits::{ FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine, }; use rustc_macros::extension; +use rustc_middle::span_bug; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, @@ -63,10 +64,18 @@ impl<'tcx> At<'_, 'tcx> { if self.infcx.next_trait_solver() { crate::solve::deeply_normalize(self, value) } else { + if fulfill_cx.has_pending_obligations() { + let pending_obligations = fulfill_cx.pending_obligations(); + span_bug!( + pending_obligations[0].cause.span, + "deeply_normalize should not be called with pending obligations: \ + {pending_obligations:#?}" + ); + } let value = self .normalize(value) .into_value_registering_obligations(self.infcx, &mut *fulfill_cx); - let errors = fulfill_cx.select_where_possible(self.infcx); + let errors = fulfill_cx.select_all_or_error(self.infcx); let value = self.infcx.resolve_vars_if_possible(value); if errors.is_empty() { Ok(value) } else { Err(errors) } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 01f6cccb375..49c34550f8e 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -14,7 +14,7 @@ use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt}; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Term, Ty, TyCtxt, TypingMode, Upcast}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; @@ -179,35 +179,11 @@ pub(super) fn poly_project_and_unify_term<'cx, 'tcx>( ) -> ProjectAndUnifyResult<'tcx> { let infcx = selcx.infcx; let r = infcx.commit_if_ok(|_snapshot| { - let old_universe = infcx.universe(); let placeholder_predicate = infcx.enter_forall_and_leak_universe(obligation.predicate); - let new_universe = infcx.universe(); let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate); match project_and_unify_term(selcx, &placeholder_obligation) { ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e), - ProjectAndUnifyResult::Holds(obligations) - if old_universe != new_universe - && selcx.tcx().features().generic_associated_types_extended() => - { - // If the `generic_associated_types_extended` feature is active, then we ignore any - // obligations references lifetimes from any universe greater than or equal to the - // universe just created. Otherwise, we can end up with something like `for<'a> I: 'a`, - // which isn't quite what we want. Ideally, we want either an implied - // `for<'a where I: 'a> I: 'a` or we want to "lazily" check these hold when we - // instantiate concrete regions. There is design work to be done here; until then, - // however, this allows experimenting potential GAT features without running into - // well-formedness issues. - let new_obligations = obligations - .into_iter() - .filter(|obligation| { - let mut visitor = MaxUniverse::new(); - obligation.predicate.visit_with(&mut visitor); - visitor.max_universe() < new_universe - }) - .collect(); - Ok(ProjectAndUnifyResult::Holds(new_obligations)) - } other => Ok(other), } }); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index c6e41e57f0c..fe47e837dfb 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -59,12 +59,16 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, ) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> { - let normalize_op = |ty| { - let ty = ocx.normalize(&ObligationCause::dummy(), param_env, ty); + let normalize_op = |ty| -> Result<_, NoSolution> { + // We must normalize the type so we can compute the right outlives components. + // for example, if we have some constrained param type like `T: Trait<Out = U>`, + // and we know that `&'a T::Out` is WF, then we want to imply `U: 'a`. + let ty = ocx + .deeply_normalize(&ObligationCause::dummy(), param_env, ty) + .map_err(|_| NoSolution)?; if !ocx.select_all_or_error().is_empty() { return Err(NoSolution); } - let ty = ocx.infcx.resolve_vars_if_possible(ty); let ty = OpportunisticRegionResolver::new(&ocx.infcx).fold_ty(ty); Ok(ty) }; diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 712856e6a8f..19b4125e75c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -626,7 +626,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for assoc_type in assoc_types { let defs: &ty::Generics = tcx.generics_of(assoc_type); - if !defs.own_params.is_empty() && !tcx.features().generic_associated_types_extended() { + if !defs.own_params.is_empty() { tcx.dcx().span_delayed_bug( obligation.cause.span, "GATs in trait object shouldn't have been considered", diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 50c4f9eff6f..41a35c31fe4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1543,14 +1543,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if self.can_use_global_caches(param_env, cache_fresh_trait_pred) { if let Some(res) = tcx.selection_cache.get(&(infcx.typing_env(param_env), pred), tcx) { - Some(res) - } else { - debug_assert_eq!(infcx.selection_cache.get(&(param_env, pred), tcx), None); - None + return Some(res); + } else if cfg!(debug_assertions) { + match infcx.selection_cache.get(&(param_env, pred), tcx) { + None | Some(Err(Overflow(OverflowError::Canonical))) => {} + res => bug!("unexpected local cache result: {res:?}"), + } } - } else { - infcx.selection_cache.get(&(param_env, pred), tcx) } + + // Subtle: we need to check the local cache even if we're able to use the + // global cache as we don't cache overflow in the global cache but need to + // cache it as otherwise rustdoc hangs when compiling diesel. + infcx.selection_cache.get(&(param_env, pred), tcx) } /// Determines whether can we safely cache the result diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index a9cd705465e..1430cfae51f 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -15,6 +15,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::codes::*; use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_infer::traits::Obligation; use rustc_middle::bug; use rustc_middle::query::LocalCrate; use rustc_middle::ty::print::PrintTraitRefExt as _; @@ -224,21 +225,30 @@ pub(super) fn specialization_enabled_in(tcx: TyCtxt<'_>, _: LocalCrate) -> bool tcx.features().specialization() || tcx.features().min_specialization() } -/// Is `impl1` a specialization of `impl2`? +/// Is `specializing_impl_def_id` a specialization of `parent_impl_def_id`? /// -/// Specialization is determined by the sets of types to which the impls apply; -/// `impl1` specializes `impl2` if it applies to a subset of the types `impl2` applies -/// to. +/// For every type that could apply to `specializing_impl_def_id`, we prove that +/// the `parent_impl_def_id` also applies (i.e. it has a valid impl header and +/// its where-clauses hold). +/// +/// For the purposes of const traits, we also check that the specializing +/// impl is not more restrictive than the parent impl. That is, if the +/// `parent_impl_def_id` is a const impl (conditionally based off of some `~const` +/// bounds), then `specializing_impl_def_id` must also be const for the same +/// set of types. #[instrument(skip(tcx), level = "debug")] -pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId)) -> bool { +pub(super) fn specializes( + tcx: TyCtxt<'_>, + (specializing_impl_def_id, parent_impl_def_id): (DefId, DefId), +) -> bool { // We check that the specializing impl comes from a crate that has specialization enabled, // or if the specializing impl is marked with `allow_internal_unstable`. // // We don't really care if the specialized impl (the parent) is in a crate that has // specialization enabled, since it's not being specialized, and it's already been checked // for coherence. - if !tcx.specialization_enabled_in(impl1_def_id.krate) { - let span = tcx.def_span(impl1_def_id); + if !tcx.specialization_enabled_in(specializing_impl_def_id.krate) { + let span = tcx.def_span(specializing_impl_def_id); if !span.allows_unstable(sym::specialization) && !span.allows_unstable(sym::min_specialization) { @@ -246,7 +256,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, } } - let impl1_trait_header = tcx.impl_trait_header(impl1_def_id).unwrap(); + let specializing_impl_trait_header = tcx.impl_trait_header(specializing_impl_def_id).unwrap(); // We determine whether there's a subset relationship by: // @@ -261,27 +271,123 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, // See RFC 1210 for more details and justification. // Currently we do not allow e.g., a negative impl to specialize a positive one - if impl1_trait_header.polarity != tcx.impl_polarity(impl2_def_id) { + if specializing_impl_trait_header.polarity != tcx.impl_polarity(parent_impl_def_id) { return false; } - // create a parameter environment corresponding to an identity instantiation of impl1, - // i.e. the most generic instantiation of impl1. - let param_env = tcx.param_env(impl1_def_id); + // create a parameter environment corresponding to an identity instantiation of the specializing impl, + // i.e. the most generic instantiation of the specializing impl. + let param_env = tcx.param_env(specializing_impl_def_id); - // Create an infcx, taking the predicates of impl1 as assumptions: + // Create an infcx, taking the predicates of the specializing impl as assumptions: let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); - // Attempt to prove that impl2 applies, given all of the above. - fulfill_implication( - &infcx, + let specializing_impl_trait_ref = + specializing_impl_trait_header.trait_ref.instantiate_identity(); + let cause = &ObligationCause::dummy(); + debug!( + "fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)", + param_env, specializing_impl_trait_ref, parent_impl_def_id + ); + + // Attempt to prove that the parent impl applies, given all of the above. + + let ocx = ObligationCtxt::new(&infcx); + let specializing_impl_trait_ref = ocx.normalize(cause, param_env, specializing_impl_trait_ref); + + if !ocx.select_all_or_error().is_empty() { + infcx.dcx().span_delayed_bug( + infcx.tcx.def_span(specializing_impl_def_id), + format!("failed to fully normalize {specializing_impl_trait_ref}"), + ); + return false; + } + + let parent_args = infcx.fresh_args_for_item(DUMMY_SP, parent_impl_def_id); + let parent_impl_trait_ref = ocx.normalize( + cause, param_env, - impl1_trait_header.trait_ref.instantiate_identity(), - impl1_def_id, - impl2_def_id, - &ObligationCause::dummy(), - ) - .is_ok() + infcx + .tcx + .impl_trait_ref(parent_impl_def_id) + .expect("expected source impl to be a trait impl") + .instantiate(infcx.tcx, parent_args), + ); + + // do the impls unify? If not, no specialization. + let Ok(()) = ocx.eq(cause, param_env, specializing_impl_trait_ref, parent_impl_trait_ref) + else { + return false; + }; + + // Now check that the source trait ref satisfies all the where clauses of the target impl. + // This is not just for correctness; we also need this to constrain any params that may + // only be referenced via projection predicates. + let predicates = ocx.normalize( + cause, + param_env, + infcx.tcx.predicates_of(parent_impl_def_id).instantiate(infcx.tcx, parent_args), + ); + let obligations = predicates_for_generics(|_, _| cause.clone(), param_env, predicates); + ocx.register_obligations(obligations); + + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + // no dice! + debug!( + "fulfill_implication: for impls on {:?} and {:?}, \ + could not fulfill: {:?} given {:?}", + specializing_impl_trait_ref, + parent_impl_trait_ref, + errors, + param_env.caller_bounds() + ); + return false; + } + + // If the parent impl is const, then the specializing impl must be const, + // and it must not be *more restrictive* than the parent impl (that is, + // it cannot be const in fewer cases than the parent impl). + if tcx.is_conditionally_const(parent_impl_def_id) { + if !tcx.is_conditionally_const(specializing_impl_def_id) { + return false; + } + + let const_conditions = ocx.normalize( + cause, + param_env, + infcx.tcx.const_conditions(parent_impl_def_id).instantiate(infcx.tcx, parent_args), + ); + ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, _)| { + Obligation::new( + infcx.tcx, + cause.clone(), + param_env, + trait_ref.to_host_effect_clause(infcx.tcx, ty::BoundConstness::Maybe), + ) + })); + + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + // no dice! + debug!( + "fulfill_implication: for impls on {:?} and {:?}, \ + could not fulfill: {:?} given {:?}", + specializing_impl_trait_ref, + parent_impl_trait_ref, + errors, + param_env.caller_bounds() + ); + return false; + } + } + + debug!( + "fulfill_implication: an impl for {:?} specializes {:?}", + specializing_impl_trait_ref, parent_impl_trait_ref + ); + + true } /// Query provider for `specialization_graph_of`. diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index f19a567cd84..83463babc4f 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -319,38 +319,35 @@ pub(crate) mod rustc { ) -> Result<Self, Err> { assert!(def.is_enum()); - // Computes the variant of a given index. - let layout_of_variant = |index, encoding: Option<TagEncoding<VariantIdx>>| { - let tag = cx.tcx().tag_for_variant((cx.tcx().erase_regions(ty), index)); - let variant_def = Def::Variant(def.variant(index)); - let variant_layout = ty_variant(cx, (ty, layout), index); - Self::from_variant( - variant_def, - tag.map(|tag| (tag, index, encoding.unwrap())), - (ty, variant_layout), - layout.size, - cx, - ) - }; + // Computes the layout of a variant. + let layout_of_variant = + |index, encoding: Option<TagEncoding<VariantIdx>>| -> Result<Self, Err> { + let variant_layout = ty_variant(cx, (ty, layout), index); + if variant_layout.is_uninhabited() { + return Ok(Self::uninhabited()); + } + let tag = cx.tcx().tag_for_variant((cx.tcx().erase_regions(ty), index)); + let variant_def = Def::Variant(def.variant(index)); + Self::from_variant( + variant_def, + tag.map(|tag| (tag, index, encoding.unwrap())), + (ty, variant_layout), + layout.size, + cx, + ) + }; - // We consider three kinds of enums, each demanding a different - // treatment of their layout computation: - // 1. enums that are uninhabited ZSTs - // 2. enums that delegate their layout to a variant - // 3. enums with multiple variants match layout.variants() { - Variants::Single { .. } if layout.is_uninhabited() && layout.size == Size::ZERO => { - // The layout representation of uninhabited, ZST enums is - // defined to be like that of the `!` type, as opposed of a - // typical enum. Consequently, they cannot be descended into - // as if they typical enums. We therefore special-case this - // scenario and simply return an uninhabited `Tree`. - Ok(Self::uninhabited()) - } Variants::Single { index } => { - // `Variants::Single` on enums with variants denotes that - // the enum delegates its layout to the variant at `index`. - layout_of_variant(*index, None) + // Hilariously, `Single` is used even for 0-variant enums; + // `index` is just junk in that case. + if ty.ty_adt_def().unwrap().variants().is_empty() { + Ok(Self::uninhabited()) + } else { + // `Variants::Single` on enums with variants denotes that + // the enum delegates its layout to the variant at `index`. + layout_of_variant(*index, None) + } } Variants::Multiple { tag, tag_encoding, tag_field, .. } => { // `Variants::Multiple` denotes an enum with multiple @@ -369,7 +366,7 @@ pub(crate) mod rustc { }, )?; - return Ok(Self::def(Def::Adt(def)).then(variants)); + Ok(Self::def(Def::Adt(def)).then(variants)) } } } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 66134b81b2a..0d656f1b63b 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -81,7 +81,7 @@ fn layout_of<'tcx>( record_layout_for_printing(&cx, layout); } - invariant::partially_check_layout(&cx, &layout); + invariant::layout_sanity_check(&cx, &layout); Ok(layout) } diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index 26ea81daf78..f39b87622f4 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -1,11 +1,11 @@ use std::assert_matches::assert_matches; -use rustc_abi::{BackendRepr, FieldsShape, Scalar, Size, Variants}; +use rustc_abi::{BackendRepr, FieldsShape, Scalar, Size, TagEncoding, Variants}; use rustc_middle::bug; use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, TyAndLayout}; /// Enforce some basic invariants on layouts. -pub(super) fn partially_check_layout<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) { +pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) { let tcx = cx.tcx(); // Type-level uninhabitedness should always imply ABI uninhabitedness. @@ -241,7 +241,17 @@ pub(super) fn partially_check_layout<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLa check_layout_abi(cx, layout); - if let Variants::Multiple { variants, .. } = &layout.variants { + if let Variants::Multiple { variants, tag, tag_encoding, .. } = &layout.variants { + if let TagEncoding::Niche { niche_start, untagged_variant, niche_variants } = tag_encoding { + let niche_size = tag.size(cx); + assert!(*niche_start <= niche_size.unsigned_int_max()); + for (idx, variant) in variants.iter_enumerated() { + // Ensure all inhabited variants are accounted for. + if !variant.is_uninhabited() { + assert!(idx == *untagged_variant || niche_variants.contains(&idx)); + } + } + } for variant in variants.iter() { // No nested "multiple". assert_matches!(variant.variants, Variants::Single { .. }); diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index d85da7d355e..1c85eb2a861 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -202,7 +202,7 @@ where } } - _ if component.is_copy_modulo_regions(tcx, self.typing_env) => {} + _ if tcx.type_is_copy_modulo_regions(self.typing_env, component) => {} ty::Closure(_, args) => { for upvar in args.as_closure().upvar_tys() { diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index c739832bc78..9c074383a5e 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -384,7 +384,7 @@ impl CString { /// fn some_extern_function(s: *mut c_char); /// } /// - /// let c_string = CString::new("Hello!").expect("CString::new failed"); + /// let c_string = CString::from(c"Hello!"); /// let raw = c_string.into_raw(); /// unsafe { /// some_extern_function(raw); @@ -429,7 +429,7 @@ impl CString { /// ``` /// use std::ffi::CString; /// - /// let c_string = CString::new("foo").expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// /// let ptr = c_string.into_raw(); /// @@ -487,7 +487,7 @@ impl CString { /// ``` /// use std::ffi::CString; /// - /// let c_string = CString::new("foo").expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// let bytes = c_string.into_bytes(); /// assert_eq!(bytes, vec![b'f', b'o', b'o']); /// ``` @@ -508,7 +508,7 @@ impl CString { /// ``` /// use std::ffi::CString; /// - /// let c_string = CString::new("foo").expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// let bytes = c_string.into_bytes_with_nul(); /// assert_eq!(bytes, vec![b'f', b'o', b'o', b'\0']); /// ``` @@ -530,7 +530,7 @@ impl CString { /// ``` /// use std::ffi::CString; /// - /// let c_string = CString::new("foo").expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// let bytes = c_string.as_bytes(); /// assert_eq!(bytes, &[b'f', b'o', b'o']); /// ``` @@ -550,7 +550,7 @@ impl CString { /// ``` /// use std::ffi::CString; /// - /// let c_string = CString::new("foo").expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// let bytes = c_string.as_bytes_with_nul(); /// assert_eq!(bytes, &[b'f', b'o', b'o', b'\0']); /// ``` @@ -568,7 +568,7 @@ impl CString { /// ``` /// use std::ffi::{CString, CStr}; /// - /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// let cstr = c_string.as_c_str(); /// assert_eq!(cstr, /// CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed")); @@ -586,12 +586,9 @@ impl CString { /// # Examples /// /// ``` - /// use std::ffi::{CString, CStr}; - /// - /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed"); + /// let c_string = c"foo".to_owned(); /// let boxed = c_string.into_boxed_c_str(); - /// assert_eq!(&*boxed, - /// CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed")); + /// assert_eq!(boxed.to_bytes_with_nul(), b"foo\0"); /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "into_boxed_c_str", since = "1.20.0")] @@ -658,7 +655,7 @@ impl CString { /// assert_eq!( /// CString::from_vec_with_nul(b"abc\0".to_vec()) /// .expect("CString::from_vec_with_nul failed"), - /// CString::new(b"abc".to_vec()).expect("CString::new failed") + /// c"abc".to_owned() /// ); /// ``` /// @@ -1168,11 +1165,12 @@ impl CStr { /// # Examples /// /// ``` - /// use std::ffi::CString; + /// use std::ffi::{CStr, CString}; /// - /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed"); - /// let boxed = c_string.into_boxed_c_str(); - /// assert_eq!(boxed.into_c_string(), CString::new("foo").expect("CString::new failed")); + /// let boxed: Box<CStr> = Box::from(c"foo"); + /// let c_string: CString = c"foo".to_owned(); + /// + /// assert_eq!(boxed.into_c_string(), c_string); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "`self` will be dropped if the result is not used"] diff --git a/library/alloc/src/ffi/c_str/tests.rs b/library/alloc/src/ffi/c_str/tests.rs index 8b7172b3f20..d6b797347c2 100644 --- a/library/alloc/src/ffi/c_str/tests.rs +++ b/library/alloc/src/ffi/c_str/tests.rs @@ -159,7 +159,7 @@ fn boxed_default() { #[test] fn test_c_str_clone_into() { - let mut c_string = CString::new("lorem").unwrap(); + let mut c_string = c"lorem".to_owned(); let c_ptr = c_string.as_ptr(); let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap(); c_str.clone_into(&mut c_string); diff --git a/library/alloc/src/rc/tests.rs b/library/alloc/src/rc/tests.rs index 333e1bde31c..2210a7c24c0 100644 --- a/library/alloc/src/rc/tests.rs +++ b/library/alloc/src/rc/tests.rs @@ -349,9 +349,9 @@ fn test_unsized() { #[test] fn test_maybe_thin_unsized() { // If/when custom thin DSTs exist, this test should be updated to use one - use std::ffi::{CStr, CString}; + use std::ffi::CStr; - let x: Rc<CStr> = Rc::from(CString::new("swordfish").unwrap().into_boxed_c_str()); + let x: Rc<CStr> = Rc::from(c"swordfish"); assert_eq!(format!("{x:?}"), "\"swordfish\""); let y: Weak<CStr> = Rc::downgrade(&x); drop(x); diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/src/sync/tests.rs index 3f66c889923..de5816fda97 100644 --- a/library/alloc/src/sync/tests.rs +++ b/library/alloc/src/sync/tests.rs @@ -412,9 +412,9 @@ fn test_unsized() { #[test] fn test_maybe_thin_unsized() { // If/when custom thin DSTs exist, this test should be updated to use one - use std::ffi::{CStr, CString}; + use std::ffi::CStr; - let x: Arc<CStr> = Arc::from(CString::new("swordfish").unwrap().into_boxed_c_str()); + let x: Arc<CStr> = Arc::from(c"swordfish"); assert_eq!(format!("{x:?}"), "\"swordfish\""); let y: Weak<CStr> = Arc::downgrade(&x); drop(x); diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 60936da2e0b..d884fa69efb 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -179,6 +179,7 @@ impl Layout { /// or other unsized type like a slice). #[stable(feature = "alloc_layout", since = "1.28.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[rustc_const_stable_indirect] #[must_use] #[inline] pub const fn for_value<T: ?Sized>(t: &T) -> Self { @@ -215,7 +216,6 @@ impl Layout { /// [trait object]: ../../book/ch17-02-trait-objects.html /// [extern type]: ../../unstable-book/language-features/extern-types.html #[unstable(feature = "layout_for_ptr", issue = "69835")] - #[rustc_const_unstable(feature = "layout_for_ptr", issue = "69835")] #[must_use] pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self { // SAFETY: we pass along the prerequisites of these functions to the caller diff --git a/library/core/src/arch.rs b/library/core/src/arch.rs index 57f456c98b3..95d88c7f679 100644 --- a/library/core/src/arch.rs +++ b/library/core/src/arch.rs @@ -42,3 +42,30 @@ pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ } + +/// Compiles to a target-specific software breakpoint instruction or equivalent. +/// +/// This will typically abort the program. It may result in a core dump, and/or the system logging +/// debug information. Additional target-specific capabilities may be possible depending on +/// debuggers or other tooling; in particular, a debugger may be able to resume execution. +/// +/// If possible, this will produce an instruction sequence that allows a debugger to resume *after* +/// the breakpoint, rather than resuming *at* the breakpoint; however, the exact behavior is +/// target-specific and debugger-specific, and not guaranteed. +/// +/// If the target platform does not have any kind of debug breakpoint instruction, this may compile +/// to a trapping instruction (e.g. an undefined instruction) instead, or to some other form of +/// target-specific abort that may or may not support convenient resumption. +/// +/// The precise behavior and the precise instruction generated are not guaranteed, except that in +/// normal execution with no debug tooling involved this will not continue executing. +/// +/// - On x86 targets, this produces an `int3` instruction. +/// - On aarch64 targets, this produces a `brk #0xf000` instruction. +// When stabilizing this, update the comment on `core::intrinsics::breakpoint`. +#[unstable(feature = "breakpoint", issue = "133724")] +#[inline(always)] +#[cfg(not(bootstrap))] +pub fn breakpoint() { + core::intrinsics::breakpoint(); +} diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 061690e88dd..84bbf985e8b 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -752,10 +752,10 @@ pub struct BuildHasherDefault<H>(marker::PhantomData<fn() -> H>); impl<H> BuildHasherDefault<H> { /// Creates a new BuildHasherDefault for Hasher `H`. - #[unstable( + #[stable(feature = "build_hasher_default_const_new", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable( feature = "build_hasher_default_const_new", - issue = "123197", - reason = "recently added" + since = "CURRENT_RUSTC_VERSION" )] pub const fn new() -> Self { BuildHasherDefault(marker::PhantomData) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 46873fdc047..802b571c510 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1381,6 +1381,18 @@ pub unsafe fn prefetch_write_instruction<T>(_data: *const T, _locality: i32) { #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] +#[cfg(not(bootstrap))] +pub fn breakpoint() { + unreachable!() +} + +/// Executes a breakpoint trap, for inspection by a debugger. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +#[cfg(bootstrap)] pub unsafe fn breakpoint() { unreachable!() } @@ -4099,6 +4111,7 @@ pub const fn variant_count<T>() -> usize { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] +#[rustc_intrinsic_const_stable_indirect] pub const unsafe fn size_of_val<T: ?Sized>(_ptr: *const T) -> usize { unreachable!() } @@ -4114,6 +4127,7 @@ pub const unsafe fn size_of_val<T: ?Sized>(_ptr: *const T) -> usize { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] +#[rustc_intrinsic_const_stable_indirect] pub const unsafe fn min_align_of_val<T: ?Sized>(_ptr: *const T) -> usize { unreachable!() } diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 5ddca9c4dce..0d24b0558c5 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -612,6 +612,20 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn simd_fma<T>(x: T, y: T, z: T) -> T; + /// Computes `(x*y) + z` for each element, non-deterministically executing either + /// a fused multiply-add or two operations with rounding of the intermediate result. + /// + /// The operation is fused if the code generator determines that target instruction + /// set has support for a fused operation, and that the fused operation is more efficient + /// than the equivalent, separate pair of mul and add instructions. It is unspecified + /// whether or not a fused operation is selected, and that may depend on optimization + /// level and context, for example. + /// + /// `T` must be a vector of floats. + #[cfg(not(bootstrap))] + #[rustc_nounwind] + pub fn simd_relaxed_fma<T>(x: T, y: T, z: T) -> T; + // Computes the sine of each element. /// /// `T` must be a vector of floats. diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 3c1a098374e..9b3d6902098 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -485,9 +485,9 @@ impl<T> MaybeUninit<T> { /// } /// } /// ``` - #[stable(feature = "maybe_uninit_write", since = "1.55.0")] - #[rustc_const_unstable(feature = "const_maybe_uninit_write", issue = "63567")] #[inline(always)] + #[stable(feature = "maybe_uninit_write", since = "1.55.0")] + #[rustc_const_stable(feature = "const_maybe_uninit_write", since = "CURRENT_RUSTC_VERSION")] pub const fn write(&mut self, val: T) -> &mut T { *self = MaybeUninit::new(val); // SAFETY: We just initialized this value. diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 4cf52042a57..78ad6880709 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -333,7 +333,7 @@ pub const fn size_of<T>() -> usize { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")] +#[rustc_const_stable(feature = "const_size_of_val", since = "CURRENT_RUSTC_VERSION")] #[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of_val")] pub const fn size_of_val<T: ?Sized>(val: &T) -> usize { // SAFETY: `val` is a reference, so it's a valid raw pointer @@ -390,7 +390,6 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize { #[inline] #[must_use] #[unstable(feature = "layout_for_ptr", issue = "69835")] -#[rustc_const_unstable(feature = "const_size_of_val_raw", issue = "46571")] pub const unsafe fn size_of_val_raw<T: ?Sized>(val: *const T) -> usize { // SAFETY: the caller must provide a valid raw pointer unsafe { intrinsics::size_of_val(val) } @@ -485,7 +484,7 @@ pub const fn align_of<T>() -> usize { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")] +#[rustc_const_stable(feature = "const_align_of_val", since = "CURRENT_RUSTC_VERSION")] #[allow(deprecated)] pub const fn align_of_val<T: ?Sized>(val: &T) -> usize { // SAFETY: val is a reference, so it's a valid raw pointer @@ -534,7 +533,6 @@ pub const fn align_of_val<T: ?Sized>(val: &T) -> usize { #[inline] #[must_use] #[unstable(feature = "layout_for_ptr", issue = "69835")] -#[rustc_const_unstable(feature = "const_align_of_val_raw", issue = "46571")] pub const unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize { // SAFETY: the caller must provide a valid raw pointer unsafe { intrinsics::min_align_of_val(val) } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 5e1098c877f..c82f0d7cd4a 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -803,7 +803,7 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] pub const fn midpoint(self, other: f16) -> f16 { const LO: f16 = f16::MIN_POSITIVE * 2.; const HI: f16 = f16::MAX / 2.; diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index e97af081143..a9294306b1b 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -37,6 +37,8 @@ pub unsafe trait ZeroablePrimitive: Sized + Copy + private::Sealed { macro_rules! impl_zeroable_primitive { ($($NonZeroInner:ident ( $primitive:ty )),+ $(,)?) => { mod private { + use super::*; + #[unstable( feature = "nonzero_internals", reason = "implementation detail which may disappear or be replaced at any time", @@ -45,7 +47,11 @@ macro_rules! impl_zeroable_primitive { pub trait Sealed {} $( - #[derive(Debug, Clone, Copy, PartialEq)] + // This inner type is never shown directly, so intentionally does not have Debug + #[expect(missing_debug_implementations)] + // Since this struct is non-generic and derives Copy, + // the derived Clone is `*self` and thus doesn't field-project. + #[derive(Clone, Copy)] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] @@ -55,6 +61,16 @@ macro_rules! impl_zeroable_primitive { issue = "none" )] pub struct $NonZeroInner($primitive); + + // This is required to allow matching a constant. We don't get it from a derive + // because the derived `PartialEq` would do a field projection, which is banned + // by <https://github.com/rust-lang/compiler-team/issues/807>. + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + impl StructuralPartialEq for $NonZeroInner {} )+ } @@ -172,7 +188,7 @@ where { #[inline] fn clone(&self) -> Self { - Self(self.0) + *self } } @@ -440,15 +456,21 @@ where #[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")] #[inline] pub const fn get(self) -> T { - // FIXME: This can be changed to simply `self.0` once LLVM supports `!range` metadata - // for function arguments: https://github.com/llvm/llvm-project/issues/76628 - // // Rustc can set range metadata only if it loads `self` from // memory somewhere. If the value of `self` was from by-value argument // of some not-inlined function, LLVM don't have range metadata // to understand that the value cannot be zero. // - // For now, using the transmute `assume`s the range at runtime. + // Using the transmute `assume`s the range at runtime. + // + // Even once LLVM supports `!range` metadata for function arguments + // (see <https://github.com/llvm/llvm-project/issues/76628>), this can't + // be `.0` because MCP#807 bans field-projecting into `scalar_valid_range` + // types, and it arguably wouldn't want to be anyway because if this is + // MIR-inlined, there's no opportunity to put that argument metadata anywhere. + // + // The good answer here will eventually be pattern types, which will hopefully + // allow it to go back to `.0`, maybe with a cast of some sort. // // SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity // of `.0` is such that this transmute is sound. diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index c853db181ce..c79b2f7ad8e 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2445,7 +2445,7 @@ macro_rules! uint_impl { // to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic let (a, b) = self.overflowing_sub(rhs); let (c, d) = a.overflowing_sub(borrow as $SelfT); - (c, b || d) + (c, b | d) } /// Calculates `self` - `rhs` with a signed `rhs` diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index d37b7eedfcb..0ad1cad6914 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -7,7 +7,7 @@ use crate::pin::PinCoerceUnsized; use crate::ptr::Unique; use crate::slice::{self, SliceIndex}; use crate::ub_checks::assert_unsafe_precondition; -use crate::{fmt, hash, intrinsics, ptr}; +use crate::{fmt, hash, intrinsics, mem, ptr}; /// `*mut T` but non-zero and [covariant]. /// @@ -69,6 +69,8 @@ use crate::{fmt, hash, intrinsics, ptr}; #[rustc_nonnull_optimization_guaranteed] #[rustc_diagnostic_item = "NonNull"] pub struct NonNull<T: ?Sized> { + // Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to + // this is banned by <https://github.com/rust-lang/compiler-team/issues/807>. pointer: *const T, } @@ -282,7 +284,7 @@ impl<T: ?Sized> NonNull<T> { pub fn addr(self) -> NonZero<usize> { // SAFETY: The pointer is guaranteed by the type to be non-null, // meaning that the address will be non-zero. - unsafe { NonZero::new_unchecked(self.pointer.addr()) } + unsafe { NonZero::new_unchecked(self.as_ptr().addr()) } } /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of @@ -296,7 +298,7 @@ impl<T: ?Sized> NonNull<T> { #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn with_addr(self, addr: NonZero<usize>) -> Self { // SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero. - unsafe { NonNull::new_unchecked(self.pointer.with_addr(addr.get()) as *mut _) } + unsafe { NonNull::new_unchecked(self.as_ptr().with_addr(addr.get()) as *mut _) } } /// Creates a new pointer by mapping `self`'s address to a new one, preserving the @@ -335,7 +337,12 @@ impl<T: ?Sized> NonNull<T> { #[must_use] #[inline(always)] pub const fn as_ptr(self) -> *mut T { - self.pointer as *mut T + // This is a transmute for the same reasons as `NonZero::get`. + + // SAFETY: `NonNull` is `transparent` over a `*const T`, and `*const T` + // and `*mut T` have the same layout, so transitively we can transmute + // our `NonNull` to a `*mut T` directly. + unsafe { mem::transmute::<Self, *mut T>(self) } } /// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`] @@ -484,7 +491,7 @@ impl<T: ?Sized> NonNull<T> { // Additionally safety contract of `offset` guarantees that the resulting pointer is // pointing to an allocation, there can't be an allocation at null, thus it's safe to // construct `NonNull`. - unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } } + unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } } } /// Calculates the offset from a pointer in bytes. @@ -508,7 +515,7 @@ impl<T: ?Sized> NonNull<T> { // Additionally safety contract of `offset` guarantees that the resulting pointer is // pointing to an allocation, there can't be an allocation at null, thus it's safe to // construct `NonNull`. - unsafe { NonNull { pointer: self.pointer.byte_offset(count) } } + unsafe { NonNull { pointer: self.as_ptr().byte_offset(count) } } } /// Adds an offset to a pointer (convenience for `.offset(count as isize)`). @@ -560,7 +567,7 @@ impl<T: ?Sized> NonNull<T> { // Additionally safety contract of `offset` guarantees that the resulting pointer is // pointing to an allocation, there can't be an allocation at null, thus it's safe to // construct `NonNull`. - unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } } + unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } } } /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`). @@ -584,7 +591,7 @@ impl<T: ?Sized> NonNull<T> { // Additionally safety contract of `add` guarantees that the resulting pointer is pointing // to an allocation, there can't be an allocation at null, thus it's safe to construct // `NonNull`. - unsafe { NonNull { pointer: self.pointer.byte_add(count) } } + unsafe { NonNull { pointer: self.as_ptr().byte_add(count) } } } /// Subtracts an offset from a pointer (convenience for @@ -666,7 +673,7 @@ impl<T: ?Sized> NonNull<T> { // Additionally safety contract of `sub` guarantees that the resulting pointer is pointing // to an allocation, there can't be an allocation at null, thus it's safe to construct // `NonNull`. - unsafe { NonNull { pointer: self.pointer.byte_sub(count) } } + unsafe { NonNull { pointer: self.as_ptr().byte_sub(count) } } } /// Calculates the distance between two pointers within the same allocation. The returned value is in @@ -763,7 +770,7 @@ impl<T: ?Sized> NonNull<T> { T: Sized, { // SAFETY: the caller must uphold the safety contract for `offset_from`. - unsafe { self.pointer.offset_from(origin.pointer) } + unsafe { self.as_ptr().offset_from(origin.as_ptr()) } } /// Calculates the distance between two pointers within the same allocation. The returned value is in @@ -781,7 +788,7 @@ impl<T: ?Sized> NonNull<T> { #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn byte_offset_from<U: ?Sized>(self, origin: NonNull<U>) -> isize { // SAFETY: the caller must uphold the safety contract for `byte_offset_from`. - unsafe { self.pointer.byte_offset_from(origin.pointer) } + unsafe { self.as_ptr().byte_offset_from(origin.as_ptr()) } } // N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null @@ -856,7 +863,7 @@ impl<T: ?Sized> NonNull<T> { T: Sized, { // SAFETY: the caller must uphold the safety contract for `sub_ptr`. - unsafe { self.pointer.sub_ptr(subtracted.pointer) } + unsafe { self.as_ptr().sub_ptr(subtracted.as_ptr()) } } /// Calculates the distance between two pointers within the same allocation, *where it's known that @@ -875,7 +882,7 @@ impl<T: ?Sized> NonNull<T> { #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: NonNull<U>) -> usize { // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. - unsafe { self.pointer.byte_sub_ptr(origin.pointer) } + unsafe { self.as_ptr().byte_sub_ptr(origin.as_ptr()) } } /// Reads the value from `self` without moving it. This leaves the @@ -893,7 +900,7 @@ impl<T: ?Sized> NonNull<T> { T: Sized, { // SAFETY: the caller must uphold the safety contract for `read`. - unsafe { ptr::read(self.pointer) } + unsafe { ptr::read(self.as_ptr()) } } /// Performs a volatile read of the value from `self` without moving it. This @@ -914,7 +921,7 @@ impl<T: ?Sized> NonNull<T> { T: Sized, { // SAFETY: the caller must uphold the safety contract for `read_volatile`. - unsafe { ptr::read_volatile(self.pointer) } + unsafe { ptr::read_volatile(self.as_ptr()) } } /// Reads the value from `self` without moving it. This leaves the @@ -934,7 +941,7 @@ impl<T: ?Sized> NonNull<T> { T: Sized, { // SAFETY: the caller must uphold the safety contract for `read_unaligned`. - unsafe { ptr::read_unaligned(self.pointer) } + unsafe { ptr::read_unaligned(self.as_ptr()) } } /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source @@ -954,7 +961,7 @@ impl<T: ?Sized> NonNull<T> { T: Sized, { // SAFETY: the caller must uphold the safety contract for `copy`. - unsafe { ptr::copy(self.pointer, dest.as_ptr(), count) } + unsafe { ptr::copy(self.as_ptr(), dest.as_ptr(), count) } } /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source @@ -974,7 +981,7 @@ impl<T: ?Sized> NonNull<T> { T: Sized, { // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`. - unsafe { ptr::copy_nonoverlapping(self.pointer, dest.as_ptr(), count) } + unsafe { ptr::copy_nonoverlapping(self.as_ptr(), dest.as_ptr(), count) } } /// Copies `count * size_of<T>` bytes from `src` to `self`. The source @@ -994,7 +1001,7 @@ impl<T: ?Sized> NonNull<T> { T: Sized, { // SAFETY: the caller must uphold the safety contract for `copy`. - unsafe { ptr::copy(src.pointer, self.as_ptr(), count) } + unsafe { ptr::copy(src.as_ptr(), self.as_ptr(), count) } } /// Copies `count * size_of<T>` bytes from `src` to `self`. The source @@ -1014,7 +1021,7 @@ impl<T: ?Sized> NonNull<T> { T: Sized, { // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`. - unsafe { ptr::copy_nonoverlapping(src.pointer, self.as_ptr(), count) } + unsafe { ptr::copy_nonoverlapping(src.as_ptr(), self.as_ptr(), count) } } /// Executes the destructor (if any) of the pointed-to value. @@ -1201,7 +1208,7 @@ impl<T: ?Sized> NonNull<T> { { // SAFETY: `align` has been checked to be a power of 2 above. - unsafe { ptr::align_offset(self.pointer, align) } + unsafe { ptr::align_offset(self.as_ptr(), align) } } } @@ -1229,7 +1236,7 @@ impl<T: ?Sized> NonNull<T> { where T: Sized, { - self.pointer.is_aligned() + self.as_ptr().is_aligned() } /// Returns whether the pointer is aligned to `align`. @@ -1266,7 +1273,7 @@ impl<T: ?Sized> NonNull<T> { #[must_use] #[unstable(feature = "pointer_is_aligned_to", issue = "96284")] pub fn is_aligned_to(self, align: usize) -> bool { - self.pointer.is_aligned_to(align) + self.as_ptr().is_aligned_to(align) } } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index a5507f0f338..191eaccff98 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -858,7 +858,7 @@ impl<T> [T] { /// Gets a reference to the underlying array. /// - /// If `N` is not exactly equal to slice's the length of `self`, then this method returns `None`. + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. #[unstable(feature = "slice_as_array", issue = "133508")] #[inline] #[must_use] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index ec4b42b966b..e0b1c21e1ec 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -13,7 +13,6 @@ #![feature(bigint_helper_methods)] #![feature(cell_update)] #![feature(clone_to_uninit)] -#![feature(const_align_of_val_raw)] #![feature(const_black_box)] #![feature(const_eval_select)] #![feature(const_nonnull_new)] diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index 7e9773f2fb9..454b13a7ee3 100644 --- a/library/core/tests/ptr.rs +++ b/library/core/tests/ptr.rs @@ -304,6 +304,7 @@ fn test_const_nonnull_new() { #[test] #[cfg(unix)] // printf may not be available on other platforms #[allow(deprecated)] // For SipHasher +#[cfg_attr(not(bootstrap), allow(unpredictable_function_pointer_comparisons))] pub fn test_variadic_fnptr() { use core::ffi; use core::hash::{Hash, SipHasher}; diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 09c0b61fb2b..109bc394634 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -204,6 +204,25 @@ use crate::ops::Index; /// println!("{viking:?} has {health} hp"); /// } /// ``` +/// +/// # Usage in `const` and `static` +/// +/// As explained above, `HashMap` is randomly seeded: each `HashMap` instance uses a different seed, +/// which means that `HashMap::new` cannot be used in const context. To construct a `HashMap` in the +/// initializer of a `const` or `static` item, you will have to use a different hasher that does not +/// involve a random seed, as demonstrated in the following example. **A `HashMap` constructed this +/// way is not resistant against HashDoS!** +/// +/// ```rust +/// use std::collections::HashMap; +/// use std::hash::{BuildHasherDefault, DefaultHasher}; +/// use std::sync::Mutex; +/// +/// const EMPTY_MAP: HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>> = +/// HashMap::with_hasher(BuildHasherDefault::new()); +/// static MAP: Mutex<HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>>> = +/// Mutex::new(HashMap::with_hasher(BuildHasherDefault::new())); +/// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "HashMap")] #[stable(feature = "rust1", since = "1.0.0")] @@ -277,7 +296,10 @@ impl<K, V, S> HashMap<K, V, S> { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] + #[rustc_const_stable( + feature = "const_collections_with_hasher", + since = "CURRENT_RUSTC_VERSION" + )] pub const fn with_hasher(hash_builder: S) -> HashMap<K, V, S> { HashMap { base: base::HashMap::with_hasher(hash_builder) } } diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 21a73259f61..4c81aaff458 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -101,6 +101,25 @@ use crate::ops::{BitAnd, BitOr, BitXor, Sub}; /// [`HashMap`]: crate::collections::HashMap /// [`RefCell`]: crate::cell::RefCell /// [`Cell`]: crate::cell::Cell +/// +/// # Usage in `const` and `static` +/// +/// Like `HashMap`, `HashSet` is randomly seeded: each `HashSet` instance uses a different seed, +/// which means that `HashSet::new` cannot be used in const context. To construct a `HashSet` in the +/// initializer of a `const` or `static` item, you will have to use a different hasher that does not +/// involve a random seed, as demonstrated in the following example. **A `HashSet` constructed this +/// way is not resistant against HashDoS!** +/// +/// ```rust +/// use std::collections::HashSet; +/// use std::hash::{BuildHasherDefault, DefaultHasher}; +/// use std::sync::Mutex; +/// +/// const EMPTY_SET: HashSet<String, BuildHasherDefault<DefaultHasher>> = +/// HashSet::with_hasher(BuildHasherDefault::new()); +/// static SET: Mutex<HashSet<String, BuildHasherDefault<DefaultHasher>>> = +/// Mutex::new(HashSet::with_hasher(BuildHasherDefault::new())); +/// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "HashSet")] #[stable(feature = "rust1", since = "1.0.0")] pub struct HashSet<T, S = RandomState> { @@ -369,7 +388,10 @@ impl<T, S> HashSet<T, S> { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] + #[rustc_const_stable( + feature = "const_collections_with_hasher", + since = "CURRENT_RUSTC_VERSION" + )] pub const fn with_hasher(hasher: S) -> HashSet<T, S> { HashSet { base: base::HashSet::with_hasher(hasher) } } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 143878170f0..585946c1d50 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -320,7 +320,6 @@ // Library features (core): // tidy-alphabetical-start #![feature(array_chunks)] -#![feature(build_hasher_default_const_new)] #![feature(c_str_module)] #![feature(char_internals)] #![feature(clone_to_uninit)] diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/pal/unix/process/process_common.rs index 13290fed762..342818ac911 100644 --- a/library/std/src/sys/pal/unix/process/process_common.rs +++ b/library/std/src/sys/pal/unix/process/process_common.rs @@ -393,7 +393,7 @@ impl Command { fn os2c(s: &OsStr, saw_nul: &mut bool) -> CString { CString::new(s.as_bytes()).unwrap_or_else(|_e| { *saw_nul = true; - CString::new("<string-with-nul>").unwrap() + c"<string-with-nul>".to_owned() }) } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 2ff44fcd4c6..cfbf6548a38 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1021,11 +1021,11 @@ impl Drop for PanicGuard { /// /// # Memory Ordering /// -/// Calls to `park` _synchronize-with_ calls to `unpark`, meaning that memory +/// Calls to `unpark` _synchronize-with_ calls to `park`, meaning that memory /// operations performed before a call to `unpark` are made visible to the thread that /// consumes the token and returns from `park`. Note that all `park` and `unpark` -/// operations for a given thread form a total order and `park` synchronizes-with -/// _all_ prior `unpark` operations. +/// operations for a given thread form a total order and _all_ prior `unpark` operations +/// synchronize-with `park`. /// /// In atomic ordering terms, `unpark` performs a `Release` operation and `park` /// performs the corresponding `Acquire` operation. Calls to `unpark` for the same diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 86d23d9bd02..c9697e670b7 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -324,9 +324,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.162" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libredox" @@ -558,9 +558,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.31.4" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be" +checksum = "948512566b1895f93b1592c7574baeb2de842f224f2aab158799ecadb8ebbb46" dependencies = [ "core-foundation-sys", "libc", diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index fcd97b7b589..6da716b7a89 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -63,7 +63,7 @@ walkdir = "2.4" xz2 = "0.1" # Dependencies needed by the build-metrics feature -sysinfo = { version = "0.31.2", default-features = false, optional = true, features = ["system"] } +sysinfo = { version = "0.33.0", default-features = false, optional = true, features = ["system"] } [target.'cfg(windows)'.dependencies.junction] version = "1.0.0" diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index ee813de1c9e..74dfe2e7ec8 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -48,9 +48,9 @@ fn main() { err => { drop(err); if let Ok(pid) = pid { - println!("WARNING: build directory locked by process {pid}, waiting for lock"); + eprintln!("WARNING: build directory locked by process {pid}, waiting for lock"); } else { - println!("WARNING: build directory locked, waiting for lock"); + eprintln!("WARNING: build directory locked, waiting for lock"); } let mut lock = t!(build_lock.write()); t!(lock.write(process::id().to_string().as_ref())); @@ -70,13 +70,13 @@ fn main() { // changelog warning, not the `x.py setup` message. let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. }); if suggest_setup { - println!("WARNING: you have not made a `config.toml`"); - println!( + eprintln!("WARNING: you have not made a `config.toml`"); + eprintln!( "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \ `cp config.example.toml config.toml`" ); } else if let Some(suggestion) = &changelog_suggestion { - println!("{suggestion}"); + eprintln!("{suggestion}"); } let pre_commit = config.src.join(".git").join("hooks").join("pre-commit"); @@ -86,13 +86,13 @@ fn main() { Build::new(config).build(); if suggest_setup { - println!("WARNING: you have not made a `config.toml`"); - println!( + eprintln!("WARNING: you have not made a `config.toml`"); + eprintln!( "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \ `cp config.example.toml config.toml`" ); } else if let Some(suggestion) = &changelog_suggestion { - println!("{suggestion}"); + eprintln!("{suggestion}"); } // Give a warning if the pre-commit script is in pre-commit and not pre-push. @@ -102,14 +102,14 @@ fn main() { if fs::read_to_string(pre_commit).is_ok_and(|contents| { contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570") }) { - println!( + eprintln!( "WARNING: You have the pre-push script installed to .git/hooks/pre-commit. \ Consider moving it to .git/hooks/pre-push instead, which runs less often." ); } if suggest_setup || changelog_suggestion.is_some() { - println!("NOTE: this message was printed twice to make it more likely to be seen"); + eprintln!("NOTE: this message was printed twice to make it more likely to be seen"); } if dump_bootstrap_shims { diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 88595ff7e51..e57ed488f97 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -306,7 +306,7 @@ fn main() { // should run on success, after this block. } if verbose > 0 { - println!("\nDid not run successfully: {status}\n{cmd:?}\n-------------"); + eprintln!("\nDid not run successfully: {status}\n{cmd:?}\n-------------"); } if let Some(mut on_fail) = on_fail { diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index d46c0ab7fef..2af2e83db8f 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -287,7 +287,7 @@ impl Step for CodegenBackend { fn run(self, builder: &Builder<'_>) { // FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved if builder.build.config.vendor && self.backend == "gcc" { - println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled."); + eprintln!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled."); return; } diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 0cacd6e4f37..4419b11ac19 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1611,7 +1611,7 @@ impl Step for Sysroot { let sysroot = sysroot_dir(compiler.stage); builder - .verbose(|| println!("Removing sysroot {} to avoid caching bugs", sysroot.display())); + .verbose(|| eprintln!("Removing sysroot {} to avoid caching bugs", sysroot.display())); let _ = fs::remove_dir_all(&sysroot); t!(fs::create_dir_all(&sysroot)); @@ -1681,7 +1681,7 @@ impl Step for Sysroot { return true; } if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) { - builder.verbose_than(1, || println!("ignoring {}", path.display())); + builder.verbose_than(1, || eprintln!("ignoring {}", path.display())); false } else { true @@ -2240,7 +2240,7 @@ pub fn stream_cargo( cargo.arg(arg); } - builder.verbose(|| println!("running: {cargo:?}")); + builder.verbose(|| eprintln!("running: {cargo:?}")); if builder.config.dry_run() { return true; @@ -2261,12 +2261,12 @@ pub fn stream_cargo( Ok(msg) => { if builder.config.json_output { // Forward JSON to stdout. - println!("{line}"); + eprintln!("{line}"); } cb(msg) } // If this was informational, just print it out and continue - Err(_) => println!("{line}"), + Err(_) => eprintln!("{line}"), } } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index a636c4a9ef1..57fce206f95 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -549,24 +549,24 @@ impl Step for DebuggerScripts { cp_debugger_script("natvis/liballoc.natvis"); cp_debugger_script("natvis/libcore.natvis"); cp_debugger_script("natvis/libstd.natvis"); - } else { - cp_debugger_script("rust_types.py"); + } - // gdb debugger scripts - builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"), 0o755); - builder.install(&builder.src.join("src/etc/rust-gdbgui"), &sysroot.join("bin"), 0o755); + cp_debugger_script("rust_types.py"); - cp_debugger_script("gdb_load_rust_pretty_printers.py"); - cp_debugger_script("gdb_lookup.py"); - cp_debugger_script("gdb_providers.py"); + // gdb debugger scripts + builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"), 0o755); + builder.install(&builder.src.join("src/etc/rust-gdbgui"), &sysroot.join("bin"), 0o755); - // lldb debugger scripts - builder.install(&builder.src.join("src/etc/rust-lldb"), &sysroot.join("bin"), 0o755); + cp_debugger_script("gdb_load_rust_pretty_printers.py"); + cp_debugger_script("gdb_lookup.py"); + cp_debugger_script("gdb_providers.py"); - cp_debugger_script("lldb_lookup.py"); - cp_debugger_script("lldb_providers.py"); - cp_debugger_script("lldb_commands") - } + // lldb debugger scripts + builder.install(&builder.src.join("src/etc/rust-lldb"), &sysroot.join("bin"), 0o755); + + cp_debugger_script("lldb_lookup.py"); + cp_debugger_script("lldb_providers.py"); + cp_debugger_script("lldb_commands") } } @@ -2080,7 +2080,7 @@ fn maybe_install_llvm( { let mut cmd = command(llvm_config); cmd.arg("--libfiles"); - builder.verbose(|| println!("running {cmd:?}")); + builder.verbose(|| eprintln!("running {cmd:?}")); let files = cmd.run_capture_stdout(builder).stdout(); let build_llvm_out = &builder.llvm_out(builder.config.build); let target_llvm_out = &builder.llvm_out(target); diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 29a96f77672..d32e06d8748 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -107,10 +107,10 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) { if let Some(adjective) = adjective { format!("{adjective} ") } else { String::new() }; if len <= 10 { for path in paths { - println!("fmt: {verb} {adjective}file {path}"); + eprintln!("fmt: {verb} {adjective}file {path}"); } } else { - println!("fmt: {verb} {len} {adjective}files"); + eprintln!("fmt: {verb} {len} {adjective}files"); } } @@ -199,7 +199,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { match get_modified_rs_files(build) { Ok(Some(files)) => { if files.is_empty() { - println!("fmt info: No modified files detected for formatting."); + eprintln!("fmt info: No modified files detected for formatting."); return; } diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 3a8f9e48c0d..1af7b954f5e 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -134,7 +134,7 @@ impl Step for Profile { t!(fs::remove_file(path)); } _ => { - println!("Exiting."); + eprintln!("Exiting."); crate::exit!(1); } } @@ -184,15 +184,15 @@ pub fn setup(config: &Config, profile: Profile) { Profile::Dist => &["dist", "build"], }; - println!(); + eprintln!(); - println!("To get started, try one of the following commands:"); + eprintln!("To get started, try one of the following commands:"); for cmd in suggestions { - println!("- `x.py {cmd}`"); + eprintln!("- `x.py {cmd}`"); } if profile != Profile::Dist { - println!( + eprintln!( "For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html" ); } @@ -224,7 +224,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { t!(fs::write(path, settings)); let include_path = profile.include_path(&config.src); - println!("`x.py` will now use the configuration at {}", include_path.display()); + eprintln!("`x.py` will now use the configuration at {}", include_path.display()); } /// Creates a toolchain link for stage1 using `rustup` @@ -256,7 +256,7 @@ impl Step for Link { } if !rustup_installed(builder) { - println!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking."); + eprintln!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking."); return; } @@ -296,7 +296,7 @@ fn attempt_toolchain_link(builder: &Builder<'_>, stage_path: &str) { } if try_link_toolchain(builder, stage_path) { - println!( + eprintln!( "Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain" ); } else { @@ -321,14 +321,14 @@ fn toolchain_is_linked(builder: &Builder<'_>) -> bool { return false; } // The toolchain has already been linked. - println!( + eprintln!( "`stage1` toolchain already linked; not attempting to link `stage1` toolchain" ); } None => { // In this case, we don't know if the `stage1` toolchain has been linked; // but `rustup` failed, so let's not go any further. - println!( + eprintln!( "`rustup` failed to list current toolchains; not attempting to link `stage1` toolchain" ); } @@ -389,9 +389,9 @@ pub fn interactive_path() -> io::Result<Profile> { input.parse() } - println!("Welcome to the Rust project! What do you want to do with x.py?"); + eprintln!("Welcome to the Rust project! What do you want to do with x.py?"); for ((letter, _), profile) in abbrev_all() { - println!("{}) {}: {}", letter, profile, profile.purpose()); + eprintln!("{}) {}: {}", letter, profile, profile.purpose()); } let template = loop { print!( @@ -488,7 +488,7 @@ fn install_git_hook_maybe(builder: &Builder<'_>, config: &Config) -> io::Result< return Ok(()); } - println!( + eprintln!( "\nRust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality. If you'd like, x.py can install a git hook for you that will automatically run `test tidy` before pushing your code to ensure your code is up to par. If you decide later that this behavior is @@ -496,7 +496,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks." ); if prompt_user("Would you like to install the git hook?: [y/N]")? != Some(PromptResult::Yes) { - println!("Ok, skipping installation!"); + eprintln!("Ok, skipping installation!"); return Ok(()); } if !hooks_dir.exists() { @@ -513,7 +513,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks." ); return Err(e); } - Ok(_) => println!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"), + Ok(_) => eprintln!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"), }; Ok(()) } @@ -654,7 +654,7 @@ impl Step for Editor { if let Some(editor_kind) = editor_kind { while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {} } else { - println!("Ok, skipping editor setup!"); + eprintln!("Ok, skipping editor setup!"); } } Err(e) => eprintln!("Could not determine the editor: {e}"), @@ -687,7 +687,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu mismatched_settings = Some(false); } } - println!( + eprintln!( "\nx.py can automatically install the recommended `{settings_filename}` file for rustc development" ); @@ -706,7 +706,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu Some(PromptResult::Yes) => true, Some(PromptResult::Print) => false, _ => { - println!("Ok, skipping settings!"); + eprintln!("Ok, skipping settings!"); return Ok(true); } }; @@ -733,9 +733,9 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu _ => "Created", }; fs::write(&settings_path, editor.settings_template())?; - println!("{verb} `{}`", settings_filename); + eprintln!("{verb} `{}`", settings_filename); } else { - println!("\n{}", editor.settings_template()); + eprintln!("\n{}", editor.settings_template()); } Ok(should_create) } diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs index ba9b1b2fc33..7b2d9fff8f5 100644 --- a/src/bootstrap/src/core/build_steps/suggest.rs +++ b/src/bootstrap/src/core/build_steps/suggest.rs @@ -66,6 +66,6 @@ pub fn suggest(builder: &Builder<'_>, run: bool) { build.build(); } } else { - println!("HELP: consider using the `--run` flag to automatically run suggested tests"); + eprintln!("HELP: consider using the `--run` flag to automatically run suggested tests"); } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 4fa91c1a571..6da37530d96 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -471,11 +471,11 @@ impl Miri { // We re-use the `cargo` from above. cargo.arg("--print-sysroot"); - builder.verbose(|| println!("running: {cargo:?}")); + builder.verbose(|| eprintln!("running: {cargo:?}")); let stdout = cargo.run_capture_stdout(builder).stdout(); // Output is "<sysroot>\n". let sysroot = stdout.trim_end(); - builder.verbose(|| println!("`cargo miri setup --print-sysroot` said: {sysroot:?}")); + builder.verbose(|| eprintln!("`cargo miri setup --print-sysroot` said: {sysroot:?}")); PathBuf::from(sysroot) } } @@ -2478,7 +2478,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> } } - builder.verbose(|| println!("doc tests for: {}", markdown.display())); + builder.verbose(|| eprintln!("doc tests for: {}", markdown.display())); let mut cmd = builder.rustdoc_cmd(compiler); builder.add_rust_test_threads(&mut cmd); // allow for unstable options such as new editions @@ -2756,6 +2756,10 @@ impl Step for Crate { // `lib.rs` file, and a `lib.miri.rs` file exists in the same folder, we build that // instead. But crucially we only do that for the library, not the test builds. cargo.env("MIRI_REPLACE_LIBRS_IF_NOT_TEST", "1"); + // std needs to be built with `-Zforce-unstable-if-unmarked`. For some reason the builder + // does not set this directly, but relies on the rustc wrapper to set it, and we are not using + // the wrapper -- hence we have to set it ourselves. + cargo.rustflag("-Zforce-unstable-if-unmarked"); cargo } else { // Also prepare a sysroot for the target. diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index dd138508bea..38abca8b8da 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -523,7 +523,7 @@ impl Builder<'_> { let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8"); if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) { - println!("using sysroot {sysroot_str}"); + eprintln!("using sysroot {sysroot_str}"); } let mut rustflags = Rustflags::new(target); @@ -1033,6 +1033,15 @@ impl Builder<'_> { if mode == Mode::Rustc { rustflags.arg("-Wrustc::internal"); + // cfg(bootstrap) - remove this check when lint is in bootstrap compiler + if stage != 0 { + // Lint is allow by default so downstream tools don't get a lit + // they can do nothing about + // We shouldn't be preinterning symbols used by tests + if cmd_kind != Kind::Test { + rustflags.arg("-Drustc::symbol_intern_string_literal"); + } + } // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all // of the individual lints are satisfied. rustflags.arg("-Wkeyword_idents_2024"); diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 73bc7195ac2..ffe3e053e72 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -392,14 +392,14 @@ impl StepDescription { fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool { if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) { if !matches!(builder.config.dry_run, DryRun::SelfCheck) { - println!("Skipping {pathset:?} because it is excluded"); + eprintln!("Skipping {pathset:?} because it is excluded"); } return true; } if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) { builder.verbose(|| { - println!( + eprintln!( "{:?} not skipped for {:?} -- not in {:?}", pathset, self.name, builder.config.skip ) @@ -765,6 +765,54 @@ impl Kind { } } +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +struct Libdir { + compiler: Compiler, + target: TargetSelection, +} + +impl Step for Libdir { + type Output = PathBuf; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.never() + } + + fn run(self, builder: &Builder<'_>) -> PathBuf { + let relative_sysroot_libdir = builder.sysroot_libdir_relative(self.compiler); + let sysroot = builder.sysroot(self.compiler).join(relative_sysroot_libdir).join("rustlib"); + + if !builder.config.dry_run() { + // Avoid deleting the `rustlib/` directory we just copied (in `impl Step for + // Sysroot`). + if !builder.download_rustc() { + let sysroot_target_libdir = sysroot.join(self.target).join("lib"); + builder.verbose(|| { + eprintln!( + "Removing sysroot {} to avoid caching bugs", + sysroot_target_libdir.display() + ) + }); + let _ = fs::remove_dir_all(&sysroot_target_libdir); + t!(fs::create_dir_all(&sysroot_target_libdir)); + } + + if self.compiler.stage == 0 { + // The stage 0 compiler for the build triple is always pre-built. Ensure that + // `libLLVM.so` ends up in the target libdir, so that ui-fulldeps tests can use + // it when run. + dist::maybe_install_llvm_target( + builder, + self.compiler.host, + &builder.sysroot(self.compiler), + ); + } + } + + sysroot + } +} + impl<'a> Builder<'a> { fn get_step_descriptions(kind: Kind) -> Vec<StepDescription> { macro_rules! describe { @@ -1165,56 +1213,13 @@ impl<'a> Builder<'a> { /// Returns the bindir for a compiler's sysroot. pub fn sysroot_target_bindir(&self, compiler: Compiler, target: TargetSelection) -> PathBuf { - self.sysroot_target_libdir(compiler, target).parent().unwrap().join("bin") + self.ensure(Libdir { compiler, target }).join(target).join("bin") } /// Returns the libdir where the standard library and other artifacts are /// found for a compiler's sysroot. pub fn sysroot_target_libdir(&self, compiler: Compiler, target: TargetSelection) -> PathBuf { - #[derive(Debug, Clone, Hash, PartialEq, Eq)] - struct Libdir { - compiler: Compiler, - target: TargetSelection, - } - impl Step for Libdir { - type Output = PathBuf; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.never() - } - - fn run(self, builder: &Builder<'_>) -> PathBuf { - let lib = builder.sysroot_libdir_relative(self.compiler); - let sysroot = builder - .sysroot(self.compiler) - .join(lib) - .join("rustlib") - .join(self.target) - .join("lib"); - // Avoid deleting the rustlib/ directory we just copied - // (in `impl Step for Sysroot`). - if !builder.download_rustc() { - builder.verbose(|| { - println!("Removing sysroot {} to avoid caching bugs", sysroot.display()) - }); - let _ = fs::remove_dir_all(&sysroot); - t!(fs::create_dir_all(&sysroot)); - } - - if self.compiler.stage == 0 { - // The stage 0 compiler for the build triple is always pre-built. - // Ensure that `libLLVM.so` ends up in the target libdir, so that ui-fulldeps tests can use it when run. - dist::maybe_install_llvm_target( - builder, - self.compiler.host, - &builder.sysroot(self.compiler), - ); - } - - sysroot - } - } - self.ensure(Libdir { compiler, target }) + self.ensure(Libdir { compiler, target }).join(target).join("lib") } pub fn sysroot_codegen_backends(&self, compiler: Compiler) -> PathBuf { @@ -1432,11 +1437,11 @@ impl<'a> Builder<'a> { panic!("{}", out); } if let Some(out) = self.cache.get(&step) { - self.verbose_than(1, || println!("{}c {:?}", " ".repeat(stack.len()), step)); + self.verbose_than(1, || eprintln!("{}c {:?}", " ".repeat(stack.len()), step)); return out; } - self.verbose_than(1, || println!("{}> {:?}", " ".repeat(stack.len()), step)); + self.verbose_than(1, || eprintln!("{}> {:?}", " ".repeat(stack.len()), step)); stack.push(Box::new(step.clone())); } @@ -1457,7 +1462,7 @@ impl<'a> Builder<'a> { let step_string = format!("{step:?}"); let brace_index = step_string.find('{').unwrap_or(0); let type_string = type_name::<S>(); - println!( + eprintln!( "[TIMING] {} {} -- {}.{:03}", &type_string.strip_prefix("bootstrap::").unwrap_or(type_string), &step_string[brace_index..], @@ -1474,7 +1479,9 @@ impl<'a> Builder<'a> { let cur_step = stack.pop().expect("step stack empty"); assert_eq!(cur_step.downcast_ref(), Some(&step)); } - self.verbose_than(1, || println!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step)); + self.verbose_than(1, || { + eprintln!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step) + }); self.cache.put(step, out.clone()); out } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index a1c8bff0db9..b2ffbd9c70f 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -738,3 +738,49 @@ mod dist { ]); } } + +mod sysroot_target_dirs { + use super::{ + Build, Builder, Compiler, TEST_TRIPLE_1, TEST_TRIPLE_2, TargetSelection, configure, + }; + + #[test] + fn test_sysroot_target_libdir() { + let build = Build::new(configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1])); + let builder = Builder::new(&build); + let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1); + let compiler = Compiler { stage: 1, host: target_triple_1 }; + let target_triple_2 = TargetSelection::from_user(TEST_TRIPLE_2); + let actual = builder.sysroot_target_libdir(compiler, target_triple_2); + + assert_eq!( + builder + .sysroot(compiler) + .join(builder.sysroot_libdir_relative(compiler)) + .join("rustlib") + .join(TEST_TRIPLE_2) + .join("lib"), + actual + ); + } + + #[test] + fn test_sysroot_target_bindir() { + let build = Build::new(configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1])); + let builder = Builder::new(&build); + let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1); + let compiler = Compiler { stage: 1, host: target_triple_1 }; + let target_triple_2 = TargetSelection::from_user(TEST_TRIPLE_2); + let actual = builder.sysroot_target_bindir(compiler, target_triple_2); + + assert_eq!( + builder + .sysroot(compiler) + .join(builder.sysroot_libdir_relative(compiler)) + .join("rustlib") + .join(TEST_TRIPLE_2) + .join("bin"), + actual + ); + } +} diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index b0fbff79b90..aa5cce2fb1b 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1293,7 +1293,7 @@ impl Config { .map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids)) { if !changes.is_empty() { - println!( + eprintln!( "WARNING: There have been changes to x.py since you last updated:\n{}", crate::human_readable_changes(&changes) ); @@ -1559,7 +1559,7 @@ impl Config { } if cargo_clippy.is_some() && rustc.is_none() { - println!( + eprintln!( "WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict." ); } @@ -1841,7 +1841,7 @@ impl Config { // FIXME: Remove this option at the end of 2024. if parallel_compiler.is_some() { - println!( + eprintln!( "WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default" ); } @@ -1873,7 +1873,7 @@ impl Config { if available_backends.contains(&backend) { panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'."); } else { - println!("HELP: '{s}' for 'rust.codegen-backends' might fail. \ + eprintln!("HELP: '{s}' for 'rust.codegen-backends' might fail. \ Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ In this case, it would be referred to as '{backend}'."); } @@ -1902,7 +1902,7 @@ impl Config { // tests may fail due to using a different channel than the one used by the compiler during tests. if let Some(commit) = &config.download_rustc_commit { if is_user_configured_rust_channel { - println!( + eprintln!( "WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel." ); @@ -1992,10 +1992,10 @@ impl Config { if config.llvm_from_ci { let warn = |option: &str| { - println!( + eprintln!( "WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build." ); - println!( + eprintln!( "HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false." ); }; @@ -2014,12 +2014,12 @@ impl Config { // if they've chosen a different value. if libzstd.is_some() { - println!( + eprintln!( "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \ like almost all `llvm.*` options, will be ignored and set by the LLVM CI \ artifacts builder config." ); - println!( + eprintln!( "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false." ); } @@ -2088,7 +2088,7 @@ impl Config { if available_backends.contains(&backend) { panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'."); } else { - println!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \ + eprintln!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \ Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ In this case, it would be referred to as '{backend}'."); } @@ -2304,7 +2304,7 @@ impl Config { if self.dry_run() { return Ok(()); } - self.verbose(|| println!("running: {cmd:?}")); + self.verbose(|| eprintln!("running: {cmd:?}")); build_helper::util::try_run(cmd, self.is_verbose()) } @@ -2479,7 +2479,7 @@ impl Config { // This happens when LLVM submodule is updated in CI, we should disable ci-rustc without an error // to not break CI. For non-CI environments, we should return an error. if CiEnv::is_ci() { - println!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled."); + eprintln!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled."); return None; } else { panic!("ERROR: LLVM submodule has changes, `download-rustc` can't be used."); @@ -2490,8 +2490,8 @@ impl Config { let ci_config_toml = match self.get_builder_toml("ci-rustc") { Ok(ci_config_toml) => ci_config_toml, Err(e) if e.to_string().contains("unknown field") => { - println!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled."); - println!("HELP: Consider rebasing to a newer commit if available."); + eprintln!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled."); + eprintln!("HELP: Consider rebasing to a newer commit if available."); return None; }, Err(e) => { @@ -2505,6 +2505,7 @@ impl Config { // Check the config compatibility // FIXME: this doesn't cover `--set` flags yet. let res = check_incompatible_options_for_ci_rustc( + self.build, current_config_toml, ci_config_toml, ); @@ -2515,7 +2516,7 @@ impl Config { .is_some_and(|s| s == "1" || s == "true"); if disable_ci_rustc_if_incompatible && res.is_err() { - println!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env."); + eprintln!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env."); return None; } @@ -2700,7 +2701,7 @@ impl Config { return; } - println!("Updating submodule {relative_path}"); + eprintln!("Updating submodule {relative_path}"); self.check_run( helpers::git(Some(&self.src)) .run_always() @@ -2823,7 +2824,7 @@ impl Config { Some(StringOrBool::Bool(true)) => false, Some(StringOrBool::String(s)) if s == "if-unchanged" => { if !self.rust_info.is_managed_git_subrepository() { - println!( + eprintln!( "ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources." ); crate::exit!(1); @@ -2856,10 +2857,10 @@ impl Config { if if_unchanged { return None; } - println!("ERROR: could not find commit hash for downloading rustc"); - println!("HELP: maybe your repository history is too shallow?"); - println!("HELP: consider setting `rust.download-rustc=false` in config.toml"); - println!("HELP: or fetch enough history to include one upstream commit"); + eprintln!("ERROR: could not find commit hash for downloading rustc"); + eprintln!("HELP: maybe your repository history is too shallow?"); + eprintln!("HELP: consider setting `rust.download-rustc=false` in config.toml"); + eprintln!("HELP: or fetch enough history to include one upstream commit"); crate::exit!(1); } }; @@ -2898,7 +2899,7 @@ impl Config { let if_unchanged = || { if self.rust_info.is_from_tarball() { // Git is needed for running "if-unchanged" logic. - println!( + eprintln!( "WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`." ); return false; @@ -2947,10 +2948,10 @@ impl Config { // Only commits merged by bors will have CI artifacts. let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap(); if commit.is_empty() { - println!("error: could not find commit hash for downloading components from CI"); - println!("help: maybe your repository history is too shallow?"); - println!("help: consider disabling `{option_name}`"); - println!("help: or fetch enough history to include one upstream commit"); + eprintln!("error: could not find commit hash for downloading components from CI"); + eprintln!("help: maybe your repository history is too shallow?"); + eprintln!("help: consider disabling `{option_name}`"); + eprintln!("help: or fetch enough history to include one upstream commit"); crate::exit!(1); } @@ -2962,14 +2963,14 @@ impl Config { if has_changes { if if_unchanged { if self.is_verbose() { - println!( + eprintln!( "warning: saw changes to one of {modified_paths:?} since {commit}; \ ignoring `{option_name}`" ); } return None; } - println!( + eprintln!( "warning: `{option_name}` is enabled, but there are changes to one of {modified_paths:?}" ); } @@ -3006,7 +3007,7 @@ pub(crate) fn check_incompatible_options_for_ci_llvm( ($current:expr, $expected:expr) => { if let Some(current) = &$current { if Some(current) != $expected.as_ref() { - println!( + eprintln!( "WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \ Current value: {:?}, Expected value(s): {}{:?}", stringify!($expected).replace("_", "-"), @@ -3086,17 +3087,18 @@ pub(crate) fn check_incompatible_options_for_ci_llvm( /// Compares the current Rust options against those in the CI rustc builder and detects any incompatible options. /// It does this by destructuring the `Rust` instance to make sure every `Rust` field is covered and not missing. fn check_incompatible_options_for_ci_rustc( + host: TargetSelection, current_config_toml: TomlConfig, ci_config_toml: TomlConfig, ) -> Result<(), String> { macro_rules! err { - ($current:expr, $expected:expr) => { + ($current:expr, $expected:expr, $config_section:expr) => { if let Some(current) = &$current { if Some(current) != $expected.as_ref() { return Err(format!( - "ERROR: Setting `rust.{}` is incompatible with `rust.download-rustc`. \ + "ERROR: Setting `{}` is incompatible with `rust.download-rustc`. \ Current value: {:?}, Expected value(s): {}{:?}", - stringify!($expected).replace("_", "-"), + format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")), $current, if $expected.is_some() { "None/" } else { "" }, $expected, @@ -3107,13 +3109,13 @@ fn check_incompatible_options_for_ci_rustc( } macro_rules! warn { - ($current:expr, $expected:expr) => { + ($current:expr, $expected:expr, $config_section:expr) => { if let Some(current) = &$current { if Some(current) != $expected.as_ref() { - println!( - "WARNING: `rust.{}` has no effect with `rust.download-rustc`. \ + eprintln!( + "WARNING: `{}` has no effect with `rust.download-rustc`. \ Current value: {:?}, Expected value(s): {}{:?}", - stringify!($expected).replace("_", "-"), + format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")), $current, if $expected.is_some() { "None/" } else { "" }, $expected, @@ -3123,6 +3125,31 @@ fn check_incompatible_options_for_ci_rustc( }; } + let current_profiler = current_config_toml.build.as_ref().and_then(|b| b.profiler); + let profiler = ci_config_toml.build.as_ref().and_then(|b| b.profiler); + err!(current_profiler, profiler, "build"); + + let current_optimized_compiler_builtins = + current_config_toml.build.as_ref().and_then(|b| b.optimized_compiler_builtins); + let optimized_compiler_builtins = + ci_config_toml.build.as_ref().and_then(|b| b.optimized_compiler_builtins); + err!(current_optimized_compiler_builtins, optimized_compiler_builtins, "build"); + + // We always build the in-tree compiler on cross targets, so we only care + // about the host target here. + let host_str = host.to_string(); + if let Some(current_cfg) = current_config_toml.target.as_ref().and_then(|c| c.get(&host_str)) { + if current_cfg.profiler.is_some() { + let ci_target_toml = ci_config_toml.target.as_ref().and_then(|c| c.get(&host_str)); + let ci_cfg = ci_target_toml.ok_or(format!( + "Target specific config for '{host_str}' is not present for CI-rustc" + ))?; + + let profiler = &ci_cfg.profiler; + err!(current_cfg.profiler, profiler, "build"); + } + } + let (Some(current_rust_config), Some(ci_rust_config)) = (current_config_toml.rust, ci_config_toml.rust) else { @@ -3196,24 +3223,24 @@ fn check_incompatible_options_for_ci_rustc( // If the option belongs to the first category, we call `err` macro for a hard error; // otherwise, we just print a warning with `warn` macro. - err!(current_rust_config.optimize, optimize); - err!(current_rust_config.randomize_layout, randomize_layout); - err!(current_rust_config.debug_logging, debug_logging); - err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc); - err!(current_rust_config.rpath, rpath); - err!(current_rust_config.strip, strip); - err!(current_rust_config.lld_mode, lld_mode); - err!(current_rust_config.llvm_tools, llvm_tools); - err!(current_rust_config.llvm_bitcode_linker, llvm_bitcode_linker); - err!(current_rust_config.jemalloc, jemalloc); - err!(current_rust_config.default_linker, default_linker); - err!(current_rust_config.stack_protector, stack_protector); - err!(current_rust_config.lto, lto); - err!(current_rust_config.std_features, std_features); - - warn!(current_rust_config.channel, channel); - warn!(current_rust_config.description, description); - warn!(current_rust_config.incremental, incremental); + err!(current_rust_config.optimize, optimize, "rust"); + err!(current_rust_config.randomize_layout, randomize_layout, "rust"); + err!(current_rust_config.debug_logging, debug_logging, "rust"); + err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc, "rust"); + err!(current_rust_config.rpath, rpath, "rust"); + err!(current_rust_config.strip, strip, "rust"); + err!(current_rust_config.lld_mode, lld_mode, "rust"); + err!(current_rust_config.llvm_tools, llvm_tools, "rust"); + err!(current_rust_config.llvm_bitcode_linker, llvm_bitcode_linker, "rust"); + err!(current_rust_config.jemalloc, jemalloc, "rust"); + err!(current_rust_config.default_linker, default_linker, "rust"); + err!(current_rust_config.stack_protector, stack_protector, "rust"); + err!(current_rust_config.lto, lto, "rust"); + err!(current_rust_config.std_features, std_features, "rust"); + + warn!(current_rust_config.channel, channel, "rust"); + warn!(current_rust_config.description, description, "rust"); + warn!(current_rust_config.incremental, incremental, "rust"); Ok(()) } diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index bfeb811508c..66b9f5ed84e 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -196,12 +196,12 @@ impl Flags { if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) = HelpVerboseOnly::try_parse_from(normalize_args(args)) { - println!("NOTE: updating submodules before printing available paths"); + eprintln!("NOTE: updating submodules before printing available paths"); let config = Config::parse(Self::parse(&[String::from("build")])); let build = Build::new(config); let paths = Builder::get_help(&build, subcommand); if let Some(s) = paths { - println!("{s}"); + eprintln!("{s}"); } else { panic!("No paths available for subcommand `{}`", subcommand.as_str()); } diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index db35e6907e6..05b91c518cf 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -77,7 +77,7 @@ impl Config { if self.dry_run() && !cmd.run_always { return true; } - self.verbose(|| println!("running: {cmd:?}")); + self.verbose(|| eprintln!("running: {cmd:?}")); check_run(cmd, self.is_verbose()) } @@ -144,7 +144,7 @@ impl Config { /// Please see <https://nixos.org/patchelf.html> for more information fn fix_bin_or_dylib(&self, fname: &Path) { assert_eq!(SHOULD_FIX_BINS_AND_DYLIBS.get(), Some(&true)); - println!("attempting to patch {}", fname.display()); + eprintln!("attempting to patch {}", fname.display()); // Only build `.nix-deps` once. static NIX_DEPS_DIR: OnceLock<PathBuf> = OnceLock::new(); @@ -206,7 +206,7 @@ impl Config { } fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) { - self.verbose(|| println!("download {url}")); + self.verbose(|| eprintln!("download {url}")); // Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/. let tempfile = self.tempdir().join(dest_path.file_name().unwrap()); // While bootstrap itself only supports http and https downloads, downstream forks might @@ -226,7 +226,7 @@ impl Config { } fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) { - println!("downloading {url}"); + eprintln!("downloading {url}"); // Try curl. If that fails and we are on windows, fallback to PowerShell. // options should be kept in sync with // src/bootstrap/src/core/download.rs @@ -341,7 +341,7 @@ impl Config { short_path = short_path.strip_prefix(pattern).unwrap_or(short_path); let dst_path = dst.join(short_path); self.verbose(|| { - println!("extracting {} to {}", original_path.display(), dst.display()) + eprintln!("extracting {} to {}", original_path.display(), dst.display()) }); if !t!(member.unpack_in(dst)) { panic!("path traversal attack ??"); @@ -365,7 +365,7 @@ impl Config { pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool { use sha2::Digest; - self.verbose(|| println!("verifying {}", path.display())); + self.verbose(|| eprintln!("verifying {}", path.display())); if self.dry_run() { return false; @@ -391,7 +391,7 @@ impl Config { let verified = checksum == expected; if !verified { - println!( + eprintln!( "invalid checksum: \n\ found: {checksum}\n\ expected: {expected}", @@ -421,7 +421,7 @@ enum DownloadSource { /// Functions that are only ever called once, but named for clarify and to avoid thousand-line functions. impl Config { pub(crate) fn download_clippy(&self) -> PathBuf { - self.verbose(|| println!("downloading stage0 clippy artifacts")); + self.verbose(|| eprintln!("downloading stage0 clippy artifacts")); let date = &self.stage0_metadata.compiler.date; let version = &self.stage0_metadata.compiler.version; @@ -518,7 +518,7 @@ impl Config { } pub(crate) fn download_ci_rustc(&self, commit: &str) { - self.verbose(|| println!("using downloaded stage2 artifacts from CI (commit {commit})")); + self.verbose(|| eprintln!("using downloaded stage2 artifacts from CI (commit {commit})")); let version = self.artifact_version_part(commit); // download-rustc doesn't need its own cargo, it can just use beta's. But it does need the @@ -539,7 +539,7 @@ impl Config { #[cfg(not(feature = "bootstrap-self-test"))] pub(crate) fn download_beta_toolchain(&self) { - self.verbose(|| println!("downloading stage0 beta artifacts")); + self.verbose(|| eprintln!("downloading stage0 beta artifacts")); let date = &self.stage0_metadata.compiler.date; let version = &self.stage0_metadata.compiler.version; @@ -677,7 +677,7 @@ impl Config { return; } else { self.verbose(|| { - println!( + eprintln!( "ignoring cached file {} due to failed verification", tarball.display() ) @@ -776,10 +776,10 @@ download-rustc = false t!(check_incompatible_options_for_ci_llvm(current_config_toml, ci_config_toml)); } Err(e) if e.to_string().contains("unknown field") => { - println!( + eprintln!( "WARNING: CI LLVM has some fields that are no longer supported in bootstrap; download-ci-llvm will be disabled." ); - println!("HELP: Consider rebasing to a newer commit if available."); + eprintln!("HELP: Consider rebasing to a newer commit if available."); } Err(e) => { eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}"); diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index dcf68cbeeda..71e7f40f032 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -237,11 +237,11 @@ than building it. stage0_supported_target_list.intersection(&missing_targets_hashset).collect(); if !duplicated_targets.is_empty() { - println!( + eprintln!( "Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list." ); for duplicated_target in duplicated_targets { - println!(" {duplicated_target}"); + eprintln!(" {duplicated_target}"); } std::process::exit(1); } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 0ecf61ffcd9..5f778223d7d 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -406,11 +406,11 @@ impl Build { .unwrap() .trim(); if local_release.split('.').take(2).eq(version.split('.').take(2)) { - build.verbose(|| println!("auto-detected local-rebuild {local_release}")); + build.verbose(|| eprintln!("auto-detected local-rebuild {local_release}")); build.local_rebuild = true; } - build.verbose(|| println!("finding compilers")); + build.verbose(|| eprintln!("finding compilers")); utils::cc_detect::find(&build); // When running `setup`, the profile is about to change, so any requirements we have now may // be different on the next invocation. Don't check for them until the next time x.py is @@ -418,7 +418,7 @@ impl Build { // // Similarly, for `setup` we don't actually need submodules or cargo metadata. if !matches!(build.config.cmd, Subcommand::Setup { .. }) { - build.verbose(|| println!("running sanity check")); + build.verbose(|| eprintln!("running sanity check")); crate::core::sanity::check(&mut build); // Make sure we update these before gathering metadata so we don't get an error about missing @@ -436,7 +436,7 @@ impl Build { // Now, update all existing submodules. build.update_existing_submodules(); - build.verbose(|| println!("learning about cargo")); + build.verbose(|| eprintln!("learning about cargo")); crate::core::metadata::build(&mut build); } @@ -605,7 +605,7 @@ impl Build { let stamp = dir.join(".stamp"); let mut cleared = false; if mtime(&stamp) < mtime(input) { - self.verbose(|| println!("Dirty - {}", dir.display())); + self.verbose(|| eprintln!("Dirty - {}", dir.display())); let _ = fs::remove_dir_all(dir); cleared = true; } else if stamp.exists() { @@ -890,7 +890,7 @@ impl Build { let executed_at = std::panic::Location::caller(); self.verbose(|| { - println!("running: {command:?} (created at {created_at}, executed at {executed_at})") + eprintln!("running: {command:?} (created at {created_at}, executed at {executed_at})") }); let cmd = command.as_command_mut(); @@ -947,7 +947,7 @@ Executed at: {executed_at}"#, let fail = |message: &str, output: CommandOutput| -> ! { if self.is_verbose() { - println!("{message}"); + eprintln!("{message}"); } else { let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present()); // If the command captures output, the user would not see any indication that @@ -957,16 +957,16 @@ Executed at: {executed_at}"#, if let Some(stdout) = output.stdout_if_present().take_if(|s| !s.trim().is_empty()) { - println!("STDOUT:\n{stdout}\n"); + eprintln!("STDOUT:\n{stdout}\n"); } if let Some(stderr) = output.stderr_if_present().take_if(|s| !s.trim().is_empty()) { - println!("STDERR:\n{stderr}\n"); + eprintln!("STDERR:\n{stderr}\n"); } - println!("Command {command:?} has failed. Rerun with -v to see more details."); + eprintln!("Command {command:?} has failed. Rerun with -v to see more details."); } else { - println!("Command has failed. Rerun with -v to see more details."); + eprintln!("Command has failed. Rerun with -v to see more details."); } } exit!(1); @@ -1011,7 +1011,7 @@ Executed at: {executed_at}"#, match self.config.dry_run { DryRun::SelfCheck => (), DryRun::Disabled | DryRun::UserSelected => { - println!("{msg}"); + eprintln!("{msg}"); } } } @@ -1666,7 +1666,7 @@ Executed at: {executed_at}"#, if self.config.dry_run() { return; } - self.verbose_than(1, || println!("Copy/Link {src:?} to {dst:?}")); + self.verbose_than(1, || eprintln!("Copy/Link {src:?} to {dst:?}")); if src == dst { return; } @@ -1775,7 +1775,7 @@ Executed at: {executed_at}"#, return; } let dst = dstdir.join(src.file_name().unwrap()); - self.verbose_than(1, || println!("Install {src:?} to {dst:?}")); + self.verbose_than(1, || eprintln!("Install {src:?} to {dst:?}")); t!(fs::create_dir_all(dstdir)); if !src.exists() { panic!("ERROR: File \"{}\" not found!", src.display()); diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs index 0df00469452..e8d5b60948a 100644 --- a/src/bootstrap/src/utils/cc_detect.rs +++ b/src/bootstrap/src/utils/cc_detect.rs @@ -155,15 +155,15 @@ pub fn find_target(build: &Build, target: TargetSelection) { build.cxx.borrow_mut().insert(target, compiler); } - build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target))); - build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple)); + build.verbose(|| eprintln!("CC_{} = {:?}", target.triple, build.cc(target))); + build.verbose(|| eprintln!("CFLAGS_{} = {cflags:?}", target.triple)); if let Ok(cxx) = build.cxx(target) { let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx); - build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple)); - build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple)); + build.verbose(|| eprintln!("CXX_{} = {cxx:?}", target.triple)); + build.verbose(|| eprintln!("CXXFLAGS_{} = {cxxflags:?}", target.triple)); } if let Some(ar) = ar { - build.verbose(|| println!("AR_{} = {ar:?}", target.triple)); + build.verbose(|| eprintln!("AR_{} = {ar:?}", target.triple)); build.ar.borrow_mut().insert(target, ar); } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 923cc2dfc28..c0d52fd3430 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -135,7 +135,7 @@ impl Drop for TimeIt { fn drop(&mut self) { let time = self.1.elapsed(); if !self.0 { - println!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis()); + eprintln!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis()); } } } @@ -267,12 +267,12 @@ pub fn check_run(cmd: &mut BootstrapCommand, print_cmd_on_fail: bool) -> bool { let status = match cmd.as_command_mut().status() { Ok(status) => status, Err(e) => { - println!("failed to execute command: {cmd:?}\nERROR: {e}"); + eprintln!("failed to execute command: {cmd:?}\nERROR: {e}"); return false; } }; if !status.success() && print_cmd_on_fail { - println!( + eprintln!( "\n\ncommand did not execute successfully: {cmd:?}\n\ expected success, got: {status}\n\n" ); diff --git a/src/bootstrap/src/utils/metrics.rs b/src/bootstrap/src/utils/metrics.rs index 3b31fa36e88..06d3add6281 100644 --- a/src/bootstrap/src/utils/metrics.rs +++ b/src/bootstrap/src/utils/metrics.rs @@ -56,7 +56,7 @@ impl BuildMetrics { running_steps: Vec::new(), system_info: System::new_with_specifics( - RefreshKind::new().with_cpu(CpuRefreshKind::everything()), + RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()), ), timer_start: None, invocation_timer_start: Instant::now(), @@ -161,8 +161,9 @@ impl BuildMetrics { let dest = build.out.join("metrics.json"); - let mut system = - System::new_with_specifics(RefreshKind::new().with_cpu(CpuRefreshKind::everything())); + let mut system = System::new_with_specifics( + RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()), + ); system.refresh_cpu_usage(); system.refresh_memory(); @@ -184,7 +185,7 @@ impl BuildMetrics { if version.format_version == CURRENT_FORMAT_VERSION { t!(serde_json::from_slice::<JsonRoot>(&contents)).invocations } else { - println!( + eprintln!( "WARNING: overriding existing build/metrics.json, as it's not \ compatible with build metrics format version {CURRENT_FORMAT_VERSION}." ); diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index eb2c8254dc0..27e1c5d01b7 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -56,7 +56,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) -> let cmd = cmd.as_command_mut(); cmd.stdout(Stdio::piped()); - builder.verbose(|| println!("running: {cmd:?}")); + builder.verbose(|| eprintln!("running: {cmd:?}")); let mut process = cmd.spawn().unwrap(); @@ -71,7 +71,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) -> let result = process.wait_with_output().unwrap(); if !result.status.success() && builder.is_verbose() { - println!( + eprintln!( "\n\ncommand did not execute successfully: {cmd:?}\n\ expected success, got: {}", result.status @@ -135,7 +135,9 @@ impl<'a> Renderer<'a> { if self.up_to_date_tests > 0 { let n = self.up_to_date_tests; let s = if n > 1 { "s" } else { "" }; - println!("help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n"); + eprintln!( + "help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n" + ); } } @@ -190,7 +192,7 @@ impl<'a> Renderer<'a> { if let Some(exec_time) = test.exec_time { print!(" ({exec_time:.2?})"); } - println!(); + eprintln!(); } fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome) { @@ -200,7 +202,7 @@ impl<'a> Renderer<'a> { let executed = format!("{:>width$}", self.executed_tests - 1, width = total.len()); print!(" {executed}/{total}"); } - println!(); + eprintln!(); self.terse_tests_in_line = 0; } @@ -212,31 +214,31 @@ impl<'a> Renderer<'a> { fn render_suite_outcome(&self, outcome: Outcome<'_>, suite: &SuiteOutcome) { // The terse output doesn't end with a newline, so we need to add it ourselves. if !self.builder.config.verbose_tests { - println!(); + eprintln!(); } if !self.failures.is_empty() { - println!("\nfailures:\n"); + eprintln!("\nfailures:\n"); for failure in &self.failures { if failure.stdout.is_some() || failure.message.is_some() { - println!("---- {} stdout ----", failure.name); + eprintln!("---- {} stdout ----", failure.name); if let Some(stdout) = &failure.stdout { - println!("{stdout}"); + eprintln!("{stdout}"); } if let Some(message) = &failure.message { - println!("NOTE: {message}"); + eprintln!("NOTE: {message}"); } } } - println!("\nfailures:"); + eprintln!("\nfailures:"); for failure in &self.failures { - println!(" {}", failure.name); + eprintln!(" {}", failure.name); } } if !self.benches.is_empty() { - println!("\nbenchmarks:"); + eprintln!("\nbenchmarks:"); let mut rows = Vec::new(); for bench in &self.benches { @@ -251,13 +253,13 @@ impl<'a> Renderer<'a> { let max_1 = rows.iter().map(|r| r.1.len()).max().unwrap_or(0); let max_2 = rows.iter().map(|r| r.2.len()).max().unwrap_or(0); for row in &rows { - println!(" {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2); + eprintln!(" {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2); } } print!("\ntest result: "); self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap(); - println!( + eprintln!( ". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n", suite.passed, suite.failed, @@ -274,7 +276,7 @@ impl<'a> Renderer<'a> { fn render_message(&mut self, message: Message) { match message { Message::Suite(SuiteMessage::Started { test_count }) => { - println!("\nrunning {test_count} tests"); + eprintln!("\nrunning {test_count} tests"); self.executed_tests = 0; self.terse_tests_in_line = 0; self.tests_count = Some(test_count); @@ -314,7 +316,7 @@ impl<'a> Renderer<'a> { self.failures.push(outcome); } Message::Test(TestMessage::Timeout { name }) => { - println!("test {name} has been running for a long time"); + eprintln!("test {name} has been running for a long time"); } Message::Test(TestMessage::Started) => {} // Not useful } diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 3c6c7a7fa18..f60498a4872 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -344,7 +344,7 @@ impl<'a> Tarball<'a> { // For `x install` tarball files aren't needed, so we can speed up the process by not producing them. let compression_profile = if self.builder.kind == Kind::Install { self.builder.verbose(|| { - println!("Forcing dist.compression-profile = 'no-op' for `x install`.") + eprintln!("Forcing dist.compression-profile = 'no-op' for `x install`.") }); // "no-op" indicates that the rust-installer won't produce compressed tarball sources. "no-op" diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 454c855c75d..2ea37c168dd 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -338,6 +338,7 @@ auto: --set rust.jemalloc --set llvm.ninja=false --set rust.lto=thin + --set rust.codegen-units=1 RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 SELECT_XCODE: /Applications/Xcode_15.4.app USE_XCODE_CLANG: 1 diff --git a/src/doc/unstable-book/src/compiler-flags/debug_info_type_line_numbers.md b/src/doc/unstable-book/src/compiler-flags/debug_info_type_line_numbers.md new file mode 100644 index 00000000000..bea667dcf44 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/debug_info_type_line_numbers.md @@ -0,0 +1,7 @@ +# `debug-info-type-line-numbers` + +--- + +This option causes additional type and line information to be emitted in debug +info to provide richer information to debuggers. This is currently off by +default as it causes some compilation scenarios to be noticeably slower. diff --git a/src/doc/unstable-book/src/compiler-flags/randomize-layout.md b/src/doc/unstable-book/src/compiler-flags/randomize-layout.md new file mode 100644 index 00000000000..84c6712bc23 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/randomize-layout.md @@ -0,0 +1,23 @@ +# `randomize-layout` + +The tracking issue for this feature is: [#106764](https://github.com/rust-lang/rust/issues/106764). + +------------------------ + +The `-Zrandomize-layout` flag changes the layout algorithm for `repr(Rust)` types defined in the current crate from its normal +optimization goals to pseudorandomly rearranging fields within the degrees of freedom provided by the largely unspecified +default representation. This also affects type sizes and padding. +Downstream intantiations of generic types defined in a crate with randomization enabled will also be randomized. + +It can be used to find unsafe code that accidentally relies on unspecified behavior. + +Randomization is not guaranteed to use a different permutation for each compilation session. +`-Zlayout-seed=<u64>` can be used to supply additional entropy. + +Randomization only approximates the intended freedom of repr(Rust). Sometimes two distinct types may still consistently +result in the same layout due to limitations of the current implementation. Randomization may become +more aggressive over time as our coverage of the available degrees of freedoms improves. +Corollary: Randomization is not a safety oracle. Two struct layouts being observably the same under different layout seeds +on the current compiler version does not guarantee that future compiler versions won't give them distinct layouts. + +Randomization may also become less aggressive in the future if additional guarantees get added to the default layout. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5b407ea9a2b..34141c47cf3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2647,7 +2647,7 @@ fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) { }); args.tokens = TokenStream::new(tokens); } - ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => {} + ast::AttrArgs::Empty | ast::AttrArgs::Eq { .. } => {} } } diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 582ef7d2c48..5e4e6f27a15 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -17,17 +17,18 @@ pub(crate) trait FormatRenderer<'tcx>: Sized { /// /// This is true for html, and false for json. See #80664 const RUN_ON_MODULE: bool; + /// This associated type is the type where the current module information is stored. /// /// For each module, we go through their items by calling for each item: /// - /// 1. save_module_data - /// 2. item - /// 3. set_back_info + /// 1. `save_module_data` + /// 2. `item` + /// 3. `restore_module_data` /// - /// However,the `item` method might update information in `self` (for example if the child is - /// a module). To prevent it to impact the other children of the current module, we need to - /// reset the information between each call to `item` by using `set_back_info`. + /// This is because the `item` method might update information in `self` (for example if the child + /// is a module). To prevent it from impacting the other children of the current module, we need to + /// reset the information between each call to `item` by using `restore_module_data`. type ModuleData; /// Sets up any state required for the renderer. When this is called the cache has already been @@ -41,18 +42,18 @@ pub(crate) trait FormatRenderer<'tcx>: Sized { /// This method is called right before call [`Self::item`]. This method returns a type /// containing information that needs to be reset after the [`Self::item`] method has been - /// called with the [`Self::set_back_info`] method. + /// called with the [`Self::restore_module_data`] method. /// /// In short it goes like this: /// /// ```ignore (not valid code) - /// let reset_data = type.save_module_data(); - /// type.item(item)?; - /// type.set_back_info(reset_data); + /// let reset_data = renderer.save_module_data(); + /// renderer.item(item)?; + /// renderer.restore_module_data(reset_data); /// ``` fn save_module_data(&mut self) -> Self::ModuleData; /// Used to reset current module's information. - fn set_back_info(&mut self, info: Self::ModuleData); + fn restore_module_data(&mut self, info: Self::ModuleData); /// Renders a single non-module item. This means no recursive sub-item rendering is required. fn item(&mut self, item: clean::Item) -> Result<(), Error>; @@ -91,7 +92,7 @@ fn run_format_inner<'tcx, T: FormatRenderer<'tcx>>( for it in module.items { let info = cx.save_module_data(); run_format_inner(cx, it, prof)?; - cx.set_back_info(info); + cx.restore_module_data(info); } cx.mod_item_out()?; diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index d18673c8140..5e3d06a4ae7 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -32,12 +32,11 @@ use std::iter::Peekable; use std::ops::{ControlFlow, Range}; use std::path::PathBuf; use std::str::{self, CharIndices}; -use std::sync::OnceLock; use pulldown_cmark::{ BrokenLink, CodeBlockKind, CowStr, Event, LinkType, Options, Parser, Tag, TagEnd, html, }; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Diag, DiagMessage}; use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::TyCtxt; @@ -1882,66 +1881,63 @@ pub(crate) fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec<Rust #[derive(Clone, Default, Debug)] pub struct IdMap { - map: FxHashMap<Cow<'static, str>, usize>, + map: FxHashMap<String, usize>, existing_footnotes: usize, } -// The map is pre-initialized and then can be used as is to prevent cloning it for each item -// (in the sidebar rendering). -static DEFAULT_ID_MAP: OnceLock<FxHashSet<&'static str>> = OnceLock::new(); - -fn init_id_map() -> FxHashSet<&'static str> { - let mut map = FxHashSet::default(); - // This is the list of IDs used in JavaScript. - map.insert("help"); - map.insert("settings"); - map.insert("not-displayed"); - map.insert("alternative-display"); - map.insert("search"); - map.insert("crate-search"); - map.insert("crate-search-div"); - // This is the list of IDs used in HTML generated in Rust (including the ones - // used in tera template files). - map.insert("themeStyle"); - map.insert("settings-menu"); - map.insert("help-button"); - map.insert("sidebar-button"); - map.insert("main-content"); - map.insert("toggle-all-docs"); - map.insert("all-types"); - map.insert("default-settings"); - map.insert("sidebar-vars"); - map.insert("copy-path"); - map.insert("rustdoc-toc"); - map.insert("rustdoc-modnav"); - // This is the list of IDs used by rustdoc sections (but still generated by - // rustdoc). - map.insert("fields"); - map.insert("variants"); - map.insert("implementors-list"); - map.insert("synthetic-implementors-list"); - map.insert("foreign-impls"); - map.insert("implementations"); - map.insert("trait-implementations"); - map.insert("synthetic-implementations"); - map.insert("blanket-implementations"); - map.insert("required-associated-types"); - map.insert("provided-associated-types"); - map.insert("provided-associated-consts"); - map.insert("required-associated-consts"); - map.insert("required-methods"); - map.insert("provided-methods"); - map.insert("dyn-compatibility"); - map.insert("implementors"); - map.insert("synthetic-implementors"); - map.insert("implementations-list"); - map.insert("trait-implementations-list"); - map.insert("synthetic-implementations-list"); - map.insert("blanket-implementations-list"); - map.insert("deref-methods"); - map.insert("layout"); - map.insert("aliased-type"); - map +fn is_default_id(id: &str) -> bool { + matches!( + id, + // This is the list of IDs used in JavaScript. + "help" + | "settings" + | "not-displayed" + | "alternative-display" + | "search" + | "crate-search" + | "crate-search-div" + // This is the list of IDs used in HTML generated in Rust (including the ones + // used in tera template files). + | "themeStyle" + | "settings-menu" + | "help-button" + | "sidebar-button" + | "main-content" + | "toggle-all-docs" + | "all-types" + | "default-settings" + | "sidebar-vars" + | "copy-path" + | "rustdoc-toc" + | "rustdoc-modnav" + // This is the list of IDs used by rustdoc sections (but still generated by + // rustdoc). + | "fields" + | "variants" + | "implementors-list" + | "synthetic-implementors-list" + | "foreign-impls" + | "implementations" + | "trait-implementations" + | "synthetic-implementations" + | "blanket-implementations" + | "required-associated-types" + | "provided-associated-types" + | "provided-associated-consts" + | "required-associated-consts" + | "required-methods" + | "provided-methods" + | "dyn-compatibility" + | "implementors" + | "synthetic-implementors" + | "implementations-list" + | "trait-implementations-list" + | "synthetic-implementations-list" + | "blanket-implementations-list" + | "deref-methods" + | "layout" + | "aliased-type" + ) } impl IdMap { @@ -1953,7 +1949,7 @@ impl IdMap { let id = match self.map.get_mut(candidate.as_ref()) { None => { let candidate = candidate.to_string(); - if DEFAULT_ID_MAP.get_or_init(init_id_map).contains(candidate.as_str()) { + if is_default_id(&candidate) { let id = format!("{}-{}", candidate, 1); self.map.insert(candidate.into(), 2); id diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 40468aef4db..2d5df75e7dc 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -601,7 +601,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { self.info } - fn set_back_info(&mut self, info: Self::ModuleData) { + fn restore_module_data(&mut self, info: Self::ModuleData) { self.info = info; } diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index c37506e3588..9827f97d28d 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_span::{FileName, sym}; +use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, sym}; use tracing::info; use crate::clean; @@ -50,8 +50,14 @@ struct LocalSourcesCollector<'a, 'tcx> { src_root: &'a Path, } -fn is_real_and_local(span: clean::Span, sess: &Session) -> bool { - span.cnum(sess) == LOCAL_CRATE && span.filename(sess).is_real() +fn filename_real_and_local(span: clean::Span, sess: &Session) -> Option<RealFileName> { + if span.cnum(sess) == LOCAL_CRATE + && let FileName::Real(file) = span.filename(sess) + { + Some(file) + } else { + None + } } impl LocalSourcesCollector<'_, '_> { @@ -60,16 +66,8 @@ impl LocalSourcesCollector<'_, '_> { let span = item.span(self.tcx); let Some(span) = span else { return }; // skip all synthetic "files" - if !is_real_and_local(span, sess) { - return; - } - let filename = span.filename(sess); - let p = if let FileName::Real(file) = filename { - match file.into_local_path() { - Some(p) => p, - None => return, - } - } else { + let Some(p) = filename_real_and_local(span, sess).and_then(|file| file.into_local_path()) + else { return; }; if self.local_sources.contains_key(&*p) { @@ -135,8 +133,7 @@ impl DocVisitor<'_> for SourceCollector<'_, '_> { // If we're not rendering sources, there's nothing to do. // If we're including source files, and we haven't seen this file yet, // then we need to render it out to the filesystem. - if is_real_and_local(span, sess) { - let filename = span.filename(sess); + if let Some(filename) = filename_real_and_local(span, sess) { let span = span.inner(); let pos = sess.source_map().lookup_source_file(span.lo()); let file_span = span.with_lo(pos.start_pos).with_hi(pos.end_position()); @@ -152,7 +149,7 @@ impl DocVisitor<'_> for SourceCollector<'_, '_> { span, format!( "failed to render source code for `{filename}`: {e}", - filename = filename.prefer_local(), + filename = filename.to_string_lossy(FileNameDisplayPreference::Local), ), ); false @@ -168,18 +165,13 @@ impl SourceCollector<'_, '_> { /// Renders the given filename into its corresponding HTML source file. fn emit_source( &mut self, - filename: &FileName, + file: &RealFileName, file_span: rustc_span::Span, ) -> Result<(), Error> { - let p = match *filename { - FileName::Real(ref file) => { - if let Some(local_path) = file.local_path() { - local_path.to_path_buf() - } else { - unreachable!("only the current crate should have sources emitted"); - } - } - _ => return Ok(()), + let p = if let Some(local_path) = file.local_path() { + local_path.to_path_buf() + } else { + unreachable!("only the current crate should have sources emitted"); }; if self.emitted_local_sources.contains(&*p) { // We've already emitted this source @@ -233,8 +225,10 @@ impl SourceCollector<'_, '_> { cur.push(&fname); let title = format!("{} - source", src_fname.to_string_lossy()); - let desc = - format!("Source of the Rust file `{}`.", filename.prefer_remapped_unconditionaly()); + let desc = format!( + "Source of the Rust file `{}`.", + file.to_string_lossy(FileNameDisplayPreference::Remapped) + ); let page = layout::Page { title: &title, css_class: "src", diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 1c8303d4c20..bb967b7f163 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -321,8 +321,8 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), renderer)), TyMethodItem(m) => ItemEnum::Function(from_function(m, false, header.unwrap(), renderer)), ImplItem(i) => ItemEnum::Impl((*i).into_json(renderer)), - StaticItem(s) => ItemEnum::Static(s.into_json(renderer)), - ForeignStaticItem(s, _) => ItemEnum::Static(s.into_json(renderer)), + StaticItem(s) => ItemEnum::Static(convert_static(s, rustc_hir::Safety::Safe, renderer)), + ForeignStaticItem(s, safety) => ItemEnum::Static(convert_static(s, safety, renderer)), ForeignTypeItem => ItemEnum::ExternType, TypeAliasItem(t) => ItemEnum::TypeAlias(t.into_json(renderer)), // FIXME(generic_const_items): Add support for generic free consts @@ -831,17 +831,20 @@ impl FromClean<Box<clean::TypeAlias>> for TypeAlias { } } -impl FromClean<clean::Static> for Static { - fn from_clean(stat: clean::Static, renderer: &JsonRenderer<'_>) -> Self { - let tcx = renderer.tcx; - Static { - type_: (*stat.type_).into_json(renderer), - is_mutable: stat.mutability == ast::Mutability::Mut, - expr: stat - .expr - .map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e))) - .unwrap_or_default(), - } +fn convert_static( + stat: clean::Static, + safety: rustc_hir::Safety, + renderer: &JsonRenderer<'_>, +) -> Static { + let tcx = renderer.tcx; + Static { + type_: (*stat.type_).into_json(renderer), + is_mutable: stat.mutability == ast::Mutability::Mut, + is_unsafe: safety == rustc_hir::Safety::Unsafe, + expr: stat + .expr + .map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e))) + .unwrap_or_default(), } } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 9efcf6b4983..789a5614967 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -163,11 +163,10 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { } fn save_module_data(&mut self) -> Self::ModuleData { - unreachable!("RUN_ON_MODULE = false should never call save_module_data") + unreachable!("RUN_ON_MODULE = false, should never call save_module_data") } - - fn set_back_info(&mut self, _info: Self::ModuleData) { - unreachable!("RUN_ON_MODULE = false should never call set_back_info") + fn restore_module_data(&mut self, _info: Self::ModuleData) { + unreachable!("RUN_ON_MODULE = false, should never call set_back_info") } /// Inserts an item into the index. This should be used rather than directly calling insert on @@ -248,7 +247,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { } fn mod_item_in(&mut self, _item: &clean::Item) -> Result<(), Error> { - unreachable!("RUN_ON_MODULE = false should never call mod_item_in") + unreachable!("RUN_ON_MODULE = false, should never call mod_item_in") } fn after_krate(&mut self) -> Result<(), Error> { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 436d36d899e..8bc543f7e72 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -68,7 +68,7 @@ extern crate test; // See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs // about jemalloc. #[cfg(feature = "jemalloc")] -extern crate jemalloc_sys; +extern crate tikv_jemalloc_sys as jemalloc_sys; use std::env::{self, VarError}; use std::io::{self, IsTerminal}; diff --git a/src/llvm-project b/src/llvm-project -Subproject 104d0d16c3c7c3fef2435fef6efb2d57b70fff7 +Subproject 1268e87bdbaed0693a9d782ccd5a21e2cab2de3 diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index f553a78d766..84b33e3d860 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc /// This integer is incremented with every breaking change to the API, /// and is returned along with the JSON blob as [`Crate::format_version`]. /// Consuming code should assert that this value matches the format version(s) that it supports. -pub const FORMAT_VERSION: u32 = 36; +pub const FORMAT_VERSION: u32 = 37; /// The root of the emitted JSON blob. /// @@ -1238,6 +1238,22 @@ pub struct Static { /// /// It's not guaranteed that it'll match the actual source code for the initial value. pub expr: String, + + /// Is the static `unsafe`? + /// + /// This is only true if it's in an `extern` block, and not explicity marked + /// as `safe`. + /// + /// ```rust + /// unsafe extern { + /// static A: i32; // unsafe + /// safe static B: i32; // safe + /// } + /// + /// static C: i32 = 0; // safe + /// static mut D: i32 = 0; // safe + /// ``` + pub is_unsafe: bool, } /// A primitive type declaration. Declarations of this kind can only come from the core library. diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 4c39aaff66862cc0da52fe529aa1990bb8bb9a2 +Subproject 05f54fdc34310f458033af8a63ce1d699fae8bf diff --git a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs index fadd5272880..97cffeb098e 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs @@ -9,7 +9,7 @@ use rustc_span::sym; pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) { if let AttrKind::Normal(normal_attr) = &attr.kind { - if let AttrArgs::Eq(_, AttrArgsEq::Ast(_)) = &normal_attr.item.args { + if let AttrArgs::Eq { value: AttrArgsEq::Ast(_), .. } = &normal_attr.item.args { // `#[should_panic = ".."]` found, good return; } diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index c4a0c8f1865..022ed180ed8 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -744,7 +744,6 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::unit_types::LET_UNIT_VALUE_INFO, crate::unit_types::UNIT_ARG_INFO, crate::unit_types::UNIT_CMP_INFO, - crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO, crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO, crate::unnecessary_literal_bound::UNNECESSARY_LITERAL_BOUND_INFO, crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO, diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs index 77dbe9b78a1..3ea792d8b83 100644 --- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs +++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs @@ -74,6 +74,8 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[ #[clippy::version = "1.53.0"] ("clippy::filter_map", "clippy::manual_filter_map"), #[clippy::version = ""] + ("clippy::fn_address_comparisons", "unpredictable_function_pointer_comparisons"), + #[clippy::version = ""] ("clippy::identity_conversion", "clippy::useless_conversion"), #[clippy::version = "pre 1.29.0"] ("clippy::if_let_redundant_pattern_matching", "clippy::redundant_pattern_matching"), diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index b1d192adff9..c449a1a875b 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -7,7 +7,7 @@ use clippy_utils::{ peel_middle_ty_refs, }; use core::mem; -use rustc_ast::util::parser::{PREC_PREFIX, PREC_UNAMBIGUOUS}; +use rustc_ast::util::parser::ExprPrecedence; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; @@ -963,7 +963,7 @@ fn report<'tcx>( // expr_str (the suggestion) is never shown if is_final_ufcs is true, since it's // `expr.kind == ExprKind::Call`. Therefore, this is, afaik, always unnecessary. /* - expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence() < PREC_PREFIX { + expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence() < ExprPrecedence::Prefix { Cow::Owned(format!("({expr_str})")) } else { expr_str @@ -999,13 +999,13 @@ fn report<'tcx>( data.first_expr.span, state.msg, |diag| { - let (precedence, calls_field) = match cx.tcx.parent_hir_node(data.first_expr.hir_id) { + let needs_paren = match cx.tcx.parent_hir_node(data.first_expr.hir_id) { Node::Expr(e) => match e.kind { - ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false), - ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))), - _ => (e.precedence(), false), + ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => false, + ExprKind::Call(..) => expr.precedence() < ExprPrecedence::Unambiguous || matches!(expr.kind, ExprKind::Field(..)), + _ => expr.precedence() < e.precedence(), }, - _ => (0, false), + _ => false, }; let is_in_tuple = matches!( get_parent_expr(cx, data.first_expr), @@ -1016,7 +1016,7 @@ fn report<'tcx>( ); let sugg = if !snip_is_macro - && (calls_field || expr.precedence() < precedence) + && needs_paren && !has_enclosing_paren(&snip) && !is_in_tuple { @@ -1049,16 +1049,16 @@ fn report<'tcx>( } } - let (prefix, precedence) = match mutability { + let (prefix, needs_paren) = match mutability { Some(mutability) if !ty.is_ref() => { let prefix = match mutability { Mutability::Not => "&", Mutability::Mut => "&mut ", }; - (prefix, PREC_PREFIX) + (prefix, expr.precedence() < ExprPrecedence::Prefix) }, - None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", 0), - _ => ("", 0), + None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", false), + _ => ("", false), }; span_lint_hir_and_then( cx, @@ -1070,7 +1070,7 @@ fn report<'tcx>( let mut app = Applicability::MachineApplicable; let (snip, snip_is_macro) = snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app); - let sugg = if !snip_is_macro && expr.precedence() < precedence && !has_enclosing_paren(&snip) { + let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) { format!("{prefix}({snip})") } else { format!("{prefix}{snip}") @@ -1157,7 +1157,7 @@ impl<'tcx> Dereferencing<'tcx> { }, Some(parent) if !parent.span.from_expansion() => { // Double reference might be needed at this point. - if parent.precedence() == PREC_UNAMBIGUOUS { + if parent.precedence() == ExprPrecedence::Unambiguous { // Parentheses would be needed here, don't lint. *outer_pat = None; } else { diff --git a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs index 49978d4a655..2182689f985 100644 --- a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs +++ b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs @@ -12,7 +12,7 @@ pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) { if !attr.span.from_expansion() && let AttrKind::Normal(ref normal) = attr.kind && normal.item.path == sym::doc - && let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args + && let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs index 4f22931a4de..b38e362410e 100644 --- a/src/tools/clippy/clippy_lints/src/large_include_file.rs +++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs @@ -96,7 +96,7 @@ impl LateLintPass<'_> for LargeIncludeFile { && let AttrKind::Normal(ref normal) = attr.kind && let Some(doc) = attr.doc_str() && doc.as_str().len() as u64 > self.max_file_size - && let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args + && let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index c9064df25ac..e80cca6e7db 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -363,7 +363,6 @@ mod uninhabited_references; mod uninit_vec; mod unit_return_expecting_ord; mod unit_types; -mod unnamed_address; mod unnecessary_box_returns; mod unnecessary_literal_bound; mod unnecessary_map_on_constructor; @@ -786,7 +785,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap)); store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(conf))); store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default()); - store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress)); store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default()); store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse)); store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend)); diff --git a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs index 35dc8e9aa4e..12719c4f94b 100644 --- a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::{indent_of, snippet, snippet_with_applicability}; use clippy_utils::visitors::contains_break_or_continue; use rustc_ast::Mutability; -use rustc_ast::util::parser::PREC_PREFIX; +use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, Pat, PatKind, is_range_literal}; use rustc_lint::LateContext; @@ -84,7 +84,7 @@ pub(super) fn check<'tcx>( if !prefix.is_empty() && ( // Precedence of internal expression is less than or equal to precedence of `&expr`. - arg_expression.precedence() <= PREC_PREFIX || is_range_literal(arg_expression) + arg_expression.precedence() <= ExprPrecedence::Prefix || is_range_literal(arg_expression) ) { arg_snip = format!("({arg_snip})").into(); diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs index 9c6df4d8ac0..bac5cf88cfb 100644 --- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs +++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs @@ -7,7 +7,7 @@ use clippy_utils::{ CaptureKind, can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res, path_to_local_id, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while, }; -use rustc_ast::util::parser::PREC_UNAMBIGUOUS; +use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::Applicability; use rustc_hir::LangItem::{OptionNone, OptionSome}; use rustc_hir::def::Res; @@ -117,7 +117,7 @@ where // it's being passed by value. let scrutinee = peel_hir_expr_refs(scrutinee).0; let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app); - let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < PREC_UNAMBIGUOUS { + let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < ExprPrecedence::Unambiguous { format!("({scrutinee_str})") } else { scrutinee_str.into() diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs index 865a42b65c6..20e4d233525 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs @@ -148,7 +148,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: _ => {}, } } - requires_copy |= !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()); + requires_copy |= !cx.type_is_copy_modulo_regions(ty); break; } }, @@ -158,7 +158,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: } if can_lint - && (!requires_copy || arg_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env())) + && (!requires_copy || cx.type_is_copy_modulo_regions(arg_ty)) // This case could be handled, but a fair bit of care would need to be taken. && (!requires_deref || arg_ty.is_freeze(cx.tcx, cx.typing_env())) { diff --git a/src/tools/clippy/clippy_lints/src/neg_multiply.rs b/src/tools/clippy/clippy_lints/src/neg_multiply.rs index a0ba2aaf552..429afff9b66 100644 --- a/src/tools/clippy/clippy_lints/src/neg_multiply.rs +++ b/src/tools/clippy/clippy_lints/src/neg_multiply.rs @@ -2,7 +2,7 @@ use clippy_utils::consts::{self, Constant}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::has_enclosing_paren; -use rustc_ast::util::parser::PREC_PREFIX; +use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; @@ -58,7 +58,7 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) { { let mut applicability = Applicability::MachineApplicable; let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability); - let suggestion = if !from_macro && exp.precedence() < PREC_PREFIX && !has_enclosing_paren(&snip) { + let suggestion = if !from_macro && exp.precedence() < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) { format!("-({snip})") } else { format!("-{snip}") diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs index 4b96858d8f6..77abe7151f0 100644 --- a/src/tools/clippy/clippy_lints/src/question_mark.rs +++ b/src/tools/clippy/clippy_lints/src/question_mark.rs @@ -251,7 +251,7 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex { let mut applicability = Applicability::MachineApplicable; let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability); - let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()) + let by_ref = !cx.type_is_copy_modulo_regions(caller_ty) && !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)); let sugg = if let Some(else_inner) = r#else { if eq_expr_value(cx, caller, peel_blocks(else_inner)) { diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index 79baa914b03..8e3472b1b5a 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::is_type_lang_item; use clippy_utils::{get_parent_expr, peel_middle_ty_refs}; -use rustc_ast::util::parser::PREC_PREFIX; +use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability}; use rustc_lint::{LateContext, LateLintPass, Lint}; @@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { let (expr_ty, expr_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(expr)); let (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed)); let parent_expr = get_parent_expr(cx, expr); - let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence() > PREC_PREFIX); + let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence() > ExprPrecedence::Prefix); if expr_ty == indexed_ty { if expr_ref_count > indexed_ref_count { diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs index 8d71036084d..0d5cf45a5e6 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs @@ -1,7 +1,7 @@ use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::sugg::Sugg; -use rustc_ast::util::parser::AssocOp; +use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::Applicability; use rustc_hir::{Expr, Node}; use rustc_hir_typeck::cast::check_cast; @@ -44,8 +44,7 @@ pub(super) fn check<'tcx>( }; if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id) - && parent.precedence() - > i8::try_from(AssocOp::As.precedence()).expect("AssocOp always returns a precedence < 128") + && parent.precedence() > ExprPrecedence::Cast { sugg = format!("({sugg})"); } diff --git a/src/tools/clippy/clippy_lints/src/unnamed_address.rs b/src/tools/clippy/clippy_lints/src/unnamed_address.rs deleted file mode 100644 index cd2dacc9f09..00000000000 --- a/src/tools/clippy/clippy_lints/src/unnamed_address.rs +++ /dev/null @@ -1,60 +0,0 @@ -use clippy_utils::diagnostics::span_lint; -use rustc_hir::{BinOpKind, Expr, ExprKind}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; -use rustc_session::declare_lint_pass; - -declare_clippy_lint! { - /// ### What it does - /// Checks for comparisons with an address of a function item. - /// - /// ### Why is this bad? - /// Function item address is not guaranteed to be unique and could vary - /// between different code generation units. Furthermore different function items could have - /// the same address after being merged together. - /// - /// ### Example - /// ```no_run - /// type F = fn(); - /// fn a() {} - /// let f: F = a; - /// if f == a { - /// // ... - /// } - /// ``` - #[clippy::version = "1.44.0"] - pub FN_ADDRESS_COMPARISONS, - correctness, - "comparison with an address of a function item" -} - -declare_lint_pass!(UnnamedAddress => [FN_ADDRESS_COMPARISONS]); - -impl LateLintPass<'_> for UnnamedAddress { - fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - fn is_comparison(binop: BinOpKind) -> bool { - matches!( - binop, - BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ne | BinOpKind::Ge | BinOpKind::Gt - ) - } - - fn is_fn_def(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - matches!(cx.typeck_results().expr_ty(expr).kind(), ty::FnDef(..)) - } - - if let ExprKind::Binary(binop, left, right) = expr.kind - && is_comparison(binop.node) - && cx.typeck_results().expr_ty_adjusted(left).is_fn_ptr() - && cx.typeck_results().expr_ty_adjusted(right).is_fn_ptr() - && (is_fn_def(cx, left) || is_fn_def(cx, right)) - { - span_lint( - cx, - FN_ADDRESS_COMPARISONS, - expr.span, - "comparing with a non-unique address of a function item", - ); - } - } -} diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index c90f4a6ebfe..620a9b56eb5 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -872,8 +872,8 @@ pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool { match (l, r) { (Empty, Empty) => true, (Delimited(la), Delimited(ra)) => eq_delim_args(la, ra), - (Eq(_, AttrArgsEq::Ast(le)), Eq(_, AttrArgsEq::Ast(re))) => eq_expr(le, re), - (Eq(_, AttrArgsEq::Hir(ll)), Eq(_, AttrArgsEq::Hir(rl))) => ll.kind == rl.kind, + (Eq { value: AttrArgsEq::Ast(le), .. }, Eq{ value: AttrArgsEq::Ast(re), .. }) => eq_expr(le, re), + (Eq { value: AttrArgsEq::Hir(ll), .. }, Eq{ value: AttrArgsEq::Hir(rl), .. }) => ll.kind == rl.kind, _ => false, } } diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 39c9d234a1a..260d1b801e3 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -38,7 +38,7 @@ pub use type_certainty::expr_type_is_certain; /// Checks if the given type implements copy. pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()) + cx.type_is_copy_modulo_regions(ty) } /// This checks whether a given type is known to implement Debug. diff --git a/src/tools/clippy/tests/ui/fn_address_comparisons.rs b/src/tools/clippy/tests/ui/fn_address_comparisons.rs deleted file mode 100644 index 35535bd4fdd..00000000000 --- a/src/tools/clippy/tests/ui/fn_address_comparisons.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::fmt::Debug; -use std::ptr; -use std::rc::Rc; -use std::sync::Arc; - -fn a() {} - -#[warn(clippy::fn_address_comparisons)] -fn main() { - type F = fn(); - let f: F = a; - let g: F = f; - - // These should fail: - let _ = f == a; - //~^ ERROR: comparing with a non-unique address of a function item - //~| NOTE: `-D clippy::fn-address-comparisons` implied by `-D warnings` - let _ = f != a; - //~^ ERROR: comparing with a non-unique address of a function item - - // These should be fine: - let _ = f == g; -} diff --git a/src/tools/clippy/tests/ui/fn_address_comparisons.stderr b/src/tools/clippy/tests/ui/fn_address_comparisons.stderr deleted file mode 100644 index e6de7e35807..00000000000 --- a/src/tools/clippy/tests/ui/fn_address_comparisons.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: comparing with a non-unique address of a function item - --> tests/ui/fn_address_comparisons.rs:15:13 - | -LL | let _ = f == a; - | ^^^^^^ - | - = note: `-D clippy::fn-address-comparisons` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::fn_address_comparisons)]` - -error: comparing with a non-unique address of a function item - --> tests/ui/fn_address_comparisons.rs:18:13 - | -LL | let _ = f != a; - | ^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 0d6e07aa546..47149622ef7 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -59,6 +59,7 @@ #![allow(unknown_lints)] #![allow(unused_labels)] #![allow(ambiguous_wide_pointer_comparisons)] +#![allow(unpredictable_function_pointer_comparisons)] #![allow(clippy::reversed_empty_ranges)] #![warn(clippy::almost_complete_range)] //~ ERROR: lint `clippy::almost_complete_letter_range` #![warn(clippy::disallowed_names)] //~ ERROR: lint `clippy::blacklisted_name` @@ -74,6 +75,7 @@ #![warn(clippy::mixed_read_write_in_expression)] //~ ERROR: lint `clippy::eval_order_dependence` #![warn(clippy::manual_find_map)] //~ ERROR: lint `clippy::find_map` #![warn(clippy::manual_filter_map)] //~ ERROR: lint `clippy::filter_map` +#![warn(unpredictable_function_pointer_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons` #![warn(clippy::useless_conversion)] //~ ERROR: lint `clippy::identity_conversion` #![warn(clippy::redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching` #![warn(clippy::match_result_ok)] //~ ERROR: lint `clippy::if_let_some_result` diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 2ac59718786..7a78a5d280d 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -59,6 +59,7 @@ #![allow(unknown_lints)] #![allow(unused_labels)] #![allow(ambiguous_wide_pointer_comparisons)] +#![allow(unpredictable_function_pointer_comparisons)] #![allow(clippy::reversed_empty_ranges)] #![warn(clippy::almost_complete_letter_range)] //~ ERROR: lint `clippy::almost_complete_letter_range` #![warn(clippy::blacklisted_name)] //~ ERROR: lint `clippy::blacklisted_name` @@ -74,6 +75,7 @@ #![warn(clippy::eval_order_dependence)] //~ ERROR: lint `clippy::eval_order_dependence` #![warn(clippy::find_map)] //~ ERROR: lint `clippy::find_map` #![warn(clippy::filter_map)] //~ ERROR: lint `clippy::filter_map` +#![warn(clippy::fn_address_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons` #![warn(clippy::identity_conversion)] //~ ERROR: lint `clippy::identity_conversion` #![warn(clippy::if_let_redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching` #![warn(clippy::if_let_some_result)] //~ ERROR: lint `clippy::if_let_some_result` diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index a5ae727b7ee..dc24bc16d0e 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> tests/ui/rename.rs:63:9 + --> tests/ui/rename.rs:64:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -8,394 +8,400 @@ LL | #![warn(clippy::almost_complete_letter_range)] = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> tests/ui/rename.rs:64:9 + --> tests/ui/rename.rs:65:9 | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_conditions` - --> tests/ui/rename.rs:65:9 + --> tests/ui/rename.rs:66:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_conditions` - --> tests/ui/rename.rs:66:9 + --> tests/ui/rename.rs:67:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions` error: lint `clippy::blocks_in_if_conditions` has been renamed to `clippy::blocks_in_conditions` - --> tests/ui/rename.rs:67:9 + --> tests/ui/rename.rs:68:9 | LL | #![warn(clippy::blocks_in_if_conditions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> tests/ui/rename.rs:68:9 + --> tests/ui/rename.rs:69:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> tests/ui/rename.rs:69:9 + --> tests/ui/rename.rs:70:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> tests/ui/rename.rs:70:9 + --> tests/ui/rename.rs:71:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> tests/ui/rename.rs:71:9 + --> tests/ui/rename.rs:72:9 | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> tests/ui/rename.rs:72:9 + --> tests/ui/rename.rs:73:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> tests/ui/rename.rs:73:9 + --> tests/ui/rename.rs:74:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> tests/ui/rename.rs:74:9 + --> tests/ui/rename.rs:75:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::find_map` has been renamed to `clippy::manual_find_map` - --> tests/ui/rename.rs:75:9 + --> tests/ui/rename.rs:76:9 | LL | #![warn(clippy::find_map)] | ^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_find_map` error: lint `clippy::filter_map` has been renamed to `clippy::manual_filter_map` - --> tests/ui/rename.rs:76:9 + --> tests/ui/rename.rs:77:9 | LL | #![warn(clippy::filter_map)] | ^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_filter_map` +error: lint `clippy::fn_address_comparisons` has been renamed to `unpredictable_function_pointer_comparisons` + --> tests/ui/rename.rs:78:9 + | +LL | #![warn(clippy::fn_address_comparisons)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unpredictable_function_pointer_comparisons` + error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> tests/ui/rename.rs:77:9 + --> tests/ui/rename.rs:79:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_redundant_pattern_matching` has been renamed to `clippy::redundant_pattern_matching` - --> tests/ui/rename.rs:78:9 + --> tests/ui/rename.rs:80:9 | LL | #![warn(clippy::if_let_redundant_pattern_matching)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_pattern_matching` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> tests/ui/rename.rs:79:9 + --> tests/ui/rename.rs:81:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl` - --> tests/ui/rename.rs:80:9 + --> tests/ui/rename.rs:82:9 | LL | #![warn(clippy::incorrect_clone_impl_on_copy_type)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl` error: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl` - --> tests/ui/rename.rs:81:9 + --> tests/ui/rename.rs:83:9 | LL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl` error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects` - --> tests/ui/rename.rs:82:9 + --> tests/ui/rename.rs:84:9 | LL | #![warn(clippy::integer_arithmetic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> tests/ui/rename.rs:83:9 + --> tests/ui/rename.rs:85:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> tests/ui/rename.rs:84:9 + --> tests/ui/rename.rs:86:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> tests/ui/rename.rs:85:9 + --> tests/ui/rename.rs:87:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> tests/ui/rename.rs:86:9 + --> tests/ui/rename.rs:88:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> tests/ui/rename.rs:87:9 + --> tests/ui/rename.rs:89:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> tests/ui/rename.rs:88:9 + --> tests/ui/rename.rs:90:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> tests/ui/rename.rs:89:9 + --> tests/ui/rename.rs:91:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::overflow_check_conditional` has been renamed to `clippy::panicking_overflow_checks` - --> tests/ui/rename.rs:90:9 + --> tests/ui/rename.rs:92:9 | LL | #![warn(clippy::overflow_check_conditional)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::panicking_overflow_checks` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> tests/ui/rename.rs:91:9 + --> tests/ui/rename.rs:93:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> tests/ui/rename.rs:92:9 + --> tests/ui/rename.rs:94:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> tests/ui/rename.rs:93:9 + --> tests/ui/rename.rs:95:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> tests/ui/rename.rs:94:9 + --> tests/ui/rename.rs:96:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> tests/ui/rename.rs:95:9 + --> tests/ui/rename.rs:97:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> tests/ui/rename.rs:96:9 + --> tests/ui/rename.rs:98:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::thread_local_initializer_can_be_made_const` has been renamed to `clippy::missing_const_for_thread_local` - --> tests/ui/rename.rs:97:9 + --> tests/ui/rename.rs:99:9 | LL | #![warn(clippy::thread_local_initializer_can_be_made_const)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::missing_const_for_thread_local` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> tests/ui/rename.rs:98:9 + --> tests/ui/rename.rs:100:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::unwrap_or_else_default` has been renamed to `clippy::unwrap_or_default` - --> tests/ui/rename.rs:99:9 + --> tests/ui/rename.rs:101:9 | LL | #![warn(clippy::unwrap_or_else_default)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_or_default` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> tests/ui/rename.rs:100:9 + --> tests/ui/rename.rs:102:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting` - --> tests/ui/rename.rs:101:9 + --> tests/ui/rename.rs:103:9 | LL | #![warn(clippy::cast_ref_to_mut)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting` error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` - --> tests/ui/rename.rs:102:9 + --> tests/ui/rename.rs:104:9 | LL | #![warn(clippy::clone_double_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons` - --> tests/ui/rename.rs:103:9 + --> tests/ui/rename.rs:105:9 | LL | #![warn(clippy::cmp_nan)] | ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> tests/ui/rename.rs:104:9 + --> tests/ui/rename.rs:106:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types` - --> tests/ui/rename.rs:105:9 + --> tests/ui/rename.rs:107:9 | LL | #![warn(clippy::drop_copy)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types` error: lint `clippy::drop_ref` has been renamed to `dropping_references` - --> tests/ui/rename.rs:106:9 + --> tests/ui/rename.rs:108:9 | LL | #![warn(clippy::drop_ref)] | ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references` error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks` - --> tests/ui/rename.rs:107:9 + --> tests/ui/rename.rs:109:9 | LL | #![warn(clippy::fn_null_check)] | ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks` error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> tests/ui/rename.rs:108:9 + --> tests/ui/rename.rs:110:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> tests/ui/rename.rs:109:9 + --> tests/ui/rename.rs:111:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> tests/ui/rename.rs:110:9 + --> tests/ui/rename.rs:112:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types` - --> tests/ui/rename.rs:111:9 + --> tests/ui/rename.rs:113:9 | LL | #![warn(clippy::forget_copy)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types` error: lint `clippy::forget_ref` has been renamed to `forgetting_references` - --> tests/ui/rename.rs:112:9 + --> tests/ui/rename.rs:114:9 | LL | #![warn(clippy::forget_ref)] | ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> tests/ui/rename.rs:113:9 + --> tests/ui/rename.rs:115:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> tests/ui/rename.rs:114:9 + --> tests/ui/rename.rs:116:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> tests/ui/rename.rs:115:9 + --> tests/ui/rename.rs:117:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked` - --> tests/ui/rename.rs:116:9 + --> tests/ui/rename.rs:118:9 | LL | #![warn(clippy::invalid_utf8_in_unchecked)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> tests/ui/rename.rs:117:9 + --> tests/ui/rename.rs:119:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::maybe_misused_cfg` has been renamed to `unexpected_cfgs` - --> tests/ui/rename.rs:118:9 + --> tests/ui/rename.rs:120:9 | LL | #![warn(clippy::maybe_misused_cfg)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> tests/ui/rename.rs:119:9 + --> tests/ui/rename.rs:121:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::mismatched_target_os` has been renamed to `unexpected_cfgs` - --> tests/ui/rename.rs:120:9 + --> tests/ui/rename.rs:122:9 | LL | #![warn(clippy::mismatched_target_os)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> tests/ui/rename.rs:121:9 + --> tests/ui/rename.rs:123:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> tests/ui/rename.rs:122:9 + --> tests/ui/rename.rs:124:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries` - --> tests/ui/rename.rs:123:9 + --> tests/ui/rename.rs:125:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries` error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops` - --> tests/ui/rename.rs:124:9 + --> tests/ui/rename.rs:126:9 | LL | #![warn(clippy::undropped_manually_drops)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> tests/ui/rename.rs:125:9 + --> tests/ui/rename.rs:127:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> tests/ui/rename.rs:126:9 + --> tests/ui/rename.rs:128:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons` - --> tests/ui/rename.rs:127:9 + --> tests/ui/rename.rs:129:9 | LL | #![warn(clippy::vtable_address_comparisons)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons` error: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_empty_ranges` - --> tests/ui/rename.rs:128:9 + --> tests/ui/rename.rs:130:9 | LL | #![warn(clippy::reverse_range_loop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges` -error: aborting due to 66 previous errors +error: aborting due to 67 previous errors diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index e6fbba943a4..36f876bcdc6 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeSet, HashMap, HashSet}; use std::ffi::OsString; use std::path::{Path, PathBuf}; use std::process::Command; @@ -486,6 +486,9 @@ impl Config { } } +/// Known widths of `target_has_atomic`. +pub const KNOWN_TARGET_HAS_ATOMIC_WIDTHS: &[&str] = &["8", "16", "32", "64", "128", "ptr"]; + #[derive(Debug, Clone)] pub struct TargetCfgs { pub current: TargetCfg, @@ -611,6 +614,17 @@ impl TargetCfgs { ("panic", Some("abort")) => cfg.panic = PanicStrategy::Abort, ("panic", Some("unwind")) => cfg.panic = PanicStrategy::Unwind, ("panic", other) => panic!("unexpected value for panic cfg: {other:?}"), + + ("target_has_atomic", Some(width)) + if KNOWN_TARGET_HAS_ATOMIC_WIDTHS.contains(&width) => + { + cfg.target_has_atomic.insert(width.to_string()); + } + ("target_has_atomic", Some(other)) => { + panic!("unexpected value for `target_has_atomic` cfg: {other:?}") + } + // Nightly-only std-internal impl detail. + ("target_has_atomic", None) => {} _ => {} } } @@ -645,6 +659,12 @@ pub struct TargetCfg { pub(crate) xray: bool, #[serde(default = "default_reloc_model")] pub(crate) relocation_model: String, + + // Not present in target cfg json output, additional derived information. + #[serde(skip)] + /// Supported target atomic widths: e.g. `8` to `128` or `ptr`. This is derived from the builtin + /// `target_has_atomic` `cfg`s e.g. `target_has_atomic="8"`. + pub(crate) target_has_atomic: BTreeSet<String>, } impl TargetCfg { diff --git a/src/tools/compiletest/src/compute_diff.rs b/src/tools/compiletest/src/compute_diff.rs index 92c80c27de0..3ace6c5b6d7 100644 --- a/src/tools/compiletest/src/compute_diff.rs +++ b/src/tools/compiletest/src/compute_diff.rs @@ -144,7 +144,7 @@ where } if !wrote_data { - println!("note: diff is identical to nightly rustdoc"); + eprintln!("note: diff is identical to nightly rustdoc"); assert!(diff_output.metadata().unwrap().len() == 0); return false; } else if verbose { diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs index b605bc813f1..e75c8a5993e 100644 --- a/src/tools/compiletest/src/debuggers.rs +++ b/src/tools/compiletest/src/debuggers.rs @@ -20,7 +20,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> { } if config.remote_test_client.is_some() && !config.target.contains("android") { - println!( + eprintln!( "WARNING: debuginfo tests are not available when \ testing with remote" ); @@ -28,7 +28,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> { } if config.target.contains("android") { - println!( + eprintln!( "{} debug-info test uses tcp 5039 port.\ please reserve it", config.target @@ -50,7 +50,7 @@ pub(crate) fn configure_lldb(config: &Config) -> Option<Arc<Config>> { config.lldb_python_dir.as_ref()?; if let Some(350) = config.lldb_version { - println!( + eprintln!( "WARNING: The used version of LLDB (350) has a \ known issue that breaks debuginfo tests. See \ issue #32520 for more information. Skipping all \ diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 952533e904c..5638d471890 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -17,7 +17,6 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "check-run-results", "check-stdout", "check-test-line-numbers-match", - "compare-output-lines-by-subset", "compile-flags", "doc-flags", "dont-check-compiler-stderr", @@ -154,6 +153,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-sanitizer-thread", "needs-std-debug-assertions", "needs-symlink", + "needs-target-has-atomic", "needs-threads", "needs-unwind", "needs-wasmtime", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index fe4c5fdd8b5..91558d0c898 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -115,9 +115,6 @@ pub struct TestProps { pub dont_check_compiler_stdout: bool, // For UI tests, allows compiler to generate arbitrary output to stderr pub dont_check_compiler_stderr: bool, - // When checking the output of stdout or stderr check - // that the lines of expected output are a subset of the actual output. - pub compare_output_lines_by_subset: bool, // Don't force a --crate-type=dylib flag on the command line // // Set this for example if you have an auxiliary test file that contains @@ -240,7 +237,6 @@ mod directives { pub const KNOWN_BUG: &'static str = "known-bug"; pub const TEST_MIR_PASS: &'static str = "test-mir-pass"; pub const REMAP_SRC_BASE: &'static str = "remap-src-base"; - pub const COMPARE_OUTPUT_LINES_BY_SUBSET: &'static str = "compare-output-lines-by-subset"; pub const LLVM_COV_FLAGS: &'static str = "llvm-cov-flags"; pub const FILECHECK_FLAGS: &'static str = "filecheck-flags"; pub const NO_AUTO_CHECK_CFG: &'static str = "no-auto-check-cfg"; @@ -274,7 +270,6 @@ impl TestProps { check_run_results: false, dont_check_compiler_stdout: false, dont_check_compiler_stderr: false, - compare_output_lines_by_subset: false, no_prefer_dynamic: false, pretty_mode: "normal".to_string(), pretty_compare_only: false, @@ -550,11 +545,6 @@ impl TestProps { |s| s.trim().to_string(), ); config.set_name_directive(ln, REMAP_SRC_BASE, &mut self.remap_src_base); - config.set_name_directive( - ln, - COMPARE_OUTPUT_LINES_BY_SUBSET, - &mut self.compare_output_lines_by_subset, - ); if let Some(flags) = config.parse_name_value_directive(ln, LLVM_COV_FLAGS) { self.llvm_cov_flags.extend(split_flags(&flags)); @@ -1135,6 +1125,8 @@ fn parse_normalize_rule(header: &str) -> Option<(String, String)> { .captures(header)?; let regex = captures["regex"].to_owned(); let replacement = captures["replacement"].to_owned(); + // FIXME: Support escaped new-line in strings. + let replacement = replacement.replace("\\n", "\n"); Some((regex, replacement)) } diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 77570c58db5..e19dcd992fc 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -1,4 +1,4 @@ -use crate::common::{Config, Sanitizer}; +use crate::common::{Config, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer}; use crate::header::{IgnoreDecision, llvm_has_libzstd}; pub(super) fn handle_needs( @@ -171,11 +171,54 @@ pub(super) fn handle_needs( }, ]; - let (name, comment) = match ln.split_once([':', ' ']) { - Some((name, comment)) => (name, Some(comment)), + let (name, rest) = match ln.split_once([':', ' ']) { + Some((name, rest)) => (name, Some(rest)), None => (ln, None), }; + // FIXME(jieyouxu): tighten up this parsing to reject using both `:` and ` ` as means to + // delineate value. + if name == "needs-target-has-atomic" { + let Some(rest) = rest else { + return IgnoreDecision::Error { + message: "expected `needs-target-has-atomic` to have a comma-separated list of atomic widths".to_string(), + }; + }; + + // Expect directive value to be a list of comma-separated atomic widths. + let specified_widths = rest + .split(',') + .map(|width| width.trim()) + .map(ToString::to_string) + .collect::<Vec<String>>(); + + for width in &specified_widths { + if !KNOWN_TARGET_HAS_ATOMIC_WIDTHS.contains(&width.as_str()) { + return IgnoreDecision::Error { + message: format!( + "unknown width specified in `needs-target-has-atomic`: `{width}` is not a \ + known `target_has_atomic_width`, known values are `{:?}`", + KNOWN_TARGET_HAS_ATOMIC_WIDTHS + ), + }; + } + } + + let satisfies_all_specified_widths = specified_widths + .iter() + .all(|specified| config.target_cfg().target_has_atomic.contains(specified)); + if satisfies_all_specified_widths { + return IgnoreDecision::Continue; + } else { + return IgnoreDecision::Ignore { + reason: format!( + "skipping test as target does not support all of the required `target_has_atomic` widths `{:?}`", + specified_widths + ), + }; + } + } + if !name.starts_with("needs-") { return IgnoreDecision::Continue; } @@ -193,7 +236,7 @@ pub(super) fn handle_needs( break; } else { return IgnoreDecision::Ignore { - reason: if let Some(comment) = comment { + reason: if let Some(comment) = rest { format!("{} ({})", need.ignore_reason, comment.trim()) } else { need.ignore_reason.into() diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 4d75c38dd32..cd7c6f8361e 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -787,3 +787,40 @@ fn test_not_trailing_directive() { run_path(&mut poisoned, Path::new("a.rs"), b"//@ revisions: incremental"); assert!(!poisoned); } + +#[test] +fn test_needs_target_has_atomic() { + use std::collections::BTreeSet; + + // `x86_64-unknown-linux-gnu` supports `["8", "16", "32", "64", "ptr"]` but not `128`. + + let config = cfg().target("x86_64-unknown-linux-gnu").build(); + // Expectation sanity check. + assert_eq!( + config.target_cfg().target_has_atomic, + BTreeSet::from([ + "8".to_string(), + "16".to_string(), + "32".to_string(), + "64".to_string(), + "ptr".to_string() + ]), + "expected `x86_64-unknown-linux-gnu` to not have 128-bit atomic support" + ); + + assert!(!check_ignore(&config, "//@ needs-target-has-atomic: 8")); + assert!(!check_ignore(&config, "//@ needs-target-has-atomic: 16")); + assert!(!check_ignore(&config, "//@ needs-target-has-atomic: 32")); + assert!(!check_ignore(&config, "//@ needs-target-has-atomic: 64")); + assert!(!check_ignore(&config, "//@ needs-target-has-atomic: ptr")); + + assert!(check_ignore(&config, "//@ needs-target-has-atomic: 128")); + + assert!(!check_ignore(&config, "//@ needs-target-has-atomic: 8,16,32,64,ptr")); + + assert!(check_ignore(&config, "//@ needs-target-has-atomic: 8,16,32,64,ptr,128")); + + // Check whitespace between widths is permitted. + assert!(!check_ignore(&config, "//@ needs-target-has-atomic: 8, ptr")); + assert!(check_ignore(&config, "//@ needs-target-has-atomic: 8, ptr, 128")); +} diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index bf4a3124075..447568065f5 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -188,8 +188,8 @@ pub fn parse_config(args: Vec<String>) -> Config { let (argv0, args_) = args.split_first().unwrap(); if args.len() == 1 || args[1] == "-h" || args[1] == "--help" { let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0); - println!("{}", opts.usage(&message)); - println!(); + eprintln!("{}", opts.usage(&message)); + eprintln!(); panic!() } @@ -200,8 +200,8 @@ pub fn parse_config(args: Vec<String>) -> Config { if matches.opt_present("h") || matches.opt_present("help") { let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0); - println!("{}", opts.usage(&message)); - println!(); + eprintln!("{}", opts.usage(&message)); + eprintln!(); panic!() } @@ -501,7 +501,7 @@ pub fn run_tests(config: Arc<Config>) { // easy to miss which tests failed, and as such fail to reproduce // the failure locally. - println!( + eprintln!( "Some tests failed in compiletest suite={}{} mode={} host={} target={}", config.suite, config diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 93e5980f1f5..8c747a1d93f 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -350,10 +350,13 @@ impl<'test> TestCx<'test> { } } else { if proc_res.status.success() { - self.fatal_proc_rec( - &format!("{} test compiled successfully!", self.config.mode)[..], - proc_res, - ); + { + self.error(&format!("{} test did not emit an error", self.config.mode)); + if self.config.mode == crate::common::Mode::Ui { + println!("note: by default, ui tests are expected not to compile"); + } + proc_res.fatal(None, || ()); + }; } if !self.props.dont_check_failure_status { @@ -771,20 +774,20 @@ impl<'test> TestCx<'test> { unexpected.len(), not_found.len() )); - println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline); + eprintln!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline); if !unexpected.is_empty() { - println!("{}", "--- unexpected errors (from JSON output) ---".green()); + eprintln!("{}", "--- unexpected errors (from JSON output) ---".green()); for error in &unexpected { - println!("{}", error.render_for_expected()); + eprintln!("{}", error.render_for_expected()); } - println!("{}", "---".green()); + eprintln!("{}", "---".green()); } if !not_found.is_empty() { - println!("{}", "--- not found errors (from test file) ---".red()); + eprintln!("{}", "--- not found errors (from test file) ---".red()); for error in ¬_found { - println!("{}", error.render_for_expected()); + eprintln!("{}", error.render_for_expected()); } - println!("{}", "---\n".red()); + eprintln!("{}", "---\n".red()); } panic!("errors differ from expected"); } @@ -1873,18 +1876,18 @@ impl<'test> TestCx<'test> { fn maybe_dump_to_stdout(&self, out: &str, err: &str) { if self.config.verbose { - println!("------stdout------------------------------"); - println!("{}", out); - println!("------stderr------------------------------"); - println!("{}", err); - println!("------------------------------------------"); + eprintln!("------stdout------------------------------"); + eprintln!("{}", out); + eprintln!("------stderr------------------------------"); + eprintln!("{}", err); + eprintln!("------------------------------------------"); } } fn error(&self, err: &str) { match self.revision { - Some(rev) => println!("\nerror in revision `{}`: {}", rev, err), - None => println!("\nerror: {}", err), + Some(rev) => eprintln!("\nerror in revision `{}`: {}", rev, err), + None => eprintln!("\nerror: {}", err), } } @@ -1969,7 +1972,7 @@ impl<'test> TestCx<'test> { if !self.config.has_html_tidy { return; } - println!("info: generating a diff against nightly rustdoc"); + eprintln!("info: generating a diff against nightly rustdoc"); let suffix = self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly"); @@ -2079,7 +2082,7 @@ impl<'test> TestCx<'test> { .output() .unwrap(); assert!(output.status.success()); - println!("{}", String::from_utf8_lossy(&output.stdout)); + eprintln!("{}", String::from_utf8_lossy(&output.stdout)); eprintln!("{}", String::from_utf8_lossy(&output.stderr)); } else { use colored::Colorize; @@ -2479,7 +2482,7 @@ impl<'test> TestCx<'test> { )"# ) .replace_all(&output, |caps: &Captures<'_>| { - println!("{}", &caps[0]); + eprintln!("{}", &caps[0]); caps[0].replace(r"\", "/") }) .replace("\r\n", "\n") @@ -2541,13 +2544,10 @@ impl<'test> TestCx<'test> { return 0; } - // If `compare-output-lines-by-subset` is not explicitly enabled then - // auto-enable it when a `runner` is in use since wrapper tools might - // provide extra output on failure, for example a WebAssembly runtime - // might print the stack trace of an `unreachable` instruction by - // default. - let compare_output_by_lines = - self.props.compare_output_lines_by_subset || self.config.runner.is_some(); + // Wrapper tools set by `runner` might provide extra output on failure, + // for example a WebAssembly runtime might print the stack trace of an + // `unreachable` instruction by default. + let compare_output_by_lines = self.config.runner.is_some(); let tmp; let (expected, actual): (&str, &str) = if compare_output_by_lines { @@ -2581,16 +2581,16 @@ impl<'test> TestCx<'test> { if let Err(err) = fs::write(&actual_path, &actual) { self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",)); } - println!("Saved the actual {stream} to {actual_path:?}"); + eprintln!("Saved the actual {stream} to {actual_path:?}"); let expected_path = expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream); if !self.config.bless { if expected.is_empty() { - println!("normalized {}:\n{}\n", stream, actual); + eprintln!("normalized {}:\n{}\n", stream, actual); } else { - println!("diff of {stream}:\n"); + eprintln!("diff of {stream}:\n"); if let Some(diff_command) = self.config.diff_command.as_deref() { let mut args = diff_command.split_whitespace(); let name = args.next().unwrap(); @@ -2625,10 +2625,10 @@ impl<'test> TestCx<'test> { if let Err(err) = fs::write(&expected_path, &actual) { self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}")); } - println!("Blessing the {stream} of {test_name} in {expected_path:?}"); + eprintln!("Blessing the {stream} of {test_name} in {expected_path:?}"); } - println!("\nThe actual {0} differed from the expected {0}.", stream); + eprintln!("\nThe actual {0} differed from the expected {0}.", stream); if self.config.bless { 0 } else { 1 } } @@ -2707,7 +2707,7 @@ impl<'test> TestCx<'test> { fs::create_dir_all(&incremental_dir).unwrap(); if self.config.verbose { - println!("init_incremental_test: incremental_dir={}", incremental_dir.display()); + eprintln!("init_incremental_test: incremental_dir={}", incremental_dir.display()); } } @@ -2765,7 +2765,7 @@ impl ProcRes { } } - println!( + eprintln!( "status: {}\ncommand: {}\n{}\n{}\n", self.status, self.cmdline, @@ -2776,7 +2776,7 @@ impl ProcRes { pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! { if let Some(e) = err { - println!("\nerror: {}", e); + eprintln!("\nerror: {}", e); } self.print_info(); on_failure(); diff --git a/src/tools/compiletest/src/runtest/codegen_units.rs b/src/tools/compiletest/src/runtest/codegen_units.rs index 6c866cbef21..6acd140183d 100644 --- a/src/tools/compiletest/src/runtest/codegen_units.rs +++ b/src/tools/compiletest/src/runtest/codegen_units.rs @@ -64,13 +64,13 @@ impl TestCx<'_> { if !missing.is_empty() { missing.sort(); - println!("\nThese items should have been contained but were not:\n"); + eprintln!("\nThese items should have been contained but were not:\n"); for item in &missing { - println!("{}", item); + eprintln!("{}", item); } - println!("\n"); + eprintln!("\n"); } if !unexpected.is_empty() { @@ -80,24 +80,24 @@ impl TestCx<'_> { sorted }; - println!("\nThese items were contained but should not have been:\n"); + eprintln!("\nThese items were contained but should not have been:\n"); for item in sorted { - println!("{}", item); + eprintln!("{}", item); } - println!("\n"); + eprintln!("\n"); } if !wrong_cgus.is_empty() { wrong_cgus.sort_by_key(|pair| pair.0.name.clone()); - println!("\nThe following items were assigned to wrong codegen units:\n"); + eprintln!("\nThe following items were assigned to wrong codegen units:\n"); for &(ref expected_item, ref actual_item) in &wrong_cgus { - println!("{}", expected_item.name); - println!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units)); - println!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units)); - println!(); + eprintln!("{}", expected_item.name); + eprintln!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units)); + eprintln!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units)); + eprintln!(); } } diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index c621c22ac99..7322e730e53 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -260,7 +260,7 @@ impl TestCx<'_> { cmdline, }; if adb.kill().is_err() { - println!("Adb process is already finished."); + eprintln!("Adb process is already finished."); } } else { let rust_src_root = @@ -275,7 +275,7 @@ impl TestCx<'_> { match self.config.gdb_version { Some(version) => { - println!("NOTE: compiletest thinks it is using GDB version {}", version); + eprintln!("NOTE: compiletest thinks it is using GDB version {}", version); if version > extract_gdb_version("7.4").unwrap() { // Add the directory containing the pretty printers to @@ -297,7 +297,7 @@ impl TestCx<'_> { } } _ => { - println!( + eprintln!( "NOTE: compiletest does not know which version of \ GDB it is using" ); @@ -392,10 +392,10 @@ impl TestCx<'_> { match self.config.lldb_version { Some(ref version) => { - println!("NOTE: compiletest thinks it is using LLDB version {}", version); + eprintln!("NOTE: compiletest thinks it is using LLDB version {}", version); } _ => { - println!( + eprintln!( "NOTE: compiletest does not know which version of \ LLDB it is using" ); diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs index 31fdb0a5d13..84376d346af 100644 --- a/src/tools/compiletest/src/runtest/rustdoc_json.rs +++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs @@ -29,7 +29,7 @@ impl TestCx<'_> { if !res.status.success() { self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| { - println!("Rustdoc Output:"); + eprintln!("Rustdoc Output:"); proc_res.print_info(); }) } diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index bb747c68029..414f1a6adb3 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -109,10 +109,10 @@ impl TestCx<'_> { } if errors > 0 { - println!("To update references, rerun the tests and pass the `--bless` flag"); + eprintln!("To update references, rerun the tests and pass the `--bless` flag"); let relative_path_to_file = self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap()); - println!( + eprintln!( "To only update this specific test, also pass `--test-args {}`", relative_path_to_file.display(), ); diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index bff02f1db9f..7b50e62c29b 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -30,7 +30,7 @@ fn path_div() -> &'static str { pub fn logv(config: &Config, s: String) { debug!("{}", s); if config.verbose { - println!("{}", s); + eprintln!("{}", s); } } diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index cb02914fd93..473b4fba928 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -31,8 +31,8 @@ directories = "5" # Copied from `compiler/rustc/Cargo.toml`. # But only for some targets, it fails for others. Rustc configures this in its CI, but we can't # easily use that since we support of-tree builds. -[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies.jemalloc-sys] -version = "0.5.0" +[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies.tikv-jemalloc-sys] +version = "0.6.0" features = ['unprefixed_malloc_on_supported_platforms'] [target.'cfg(unix)'.dependencies] diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index c61c62c73da..1e0e31f01ab 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -316,6 +316,8 @@ fn jemalloc_magic() { // See there for further comments. use std::os::raw::{c_int, c_void}; + use tikv_jemalloc_sys as jemalloc_sys; + #[used] static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; #[used] diff --git a/src/tools/miri/tests/fail/breakpoint.rs b/src/tools/miri/tests/fail/breakpoint.rs index 2dd87ea6083..42943d58191 100644 --- a/src/tools/miri/tests/fail/breakpoint.rs +++ b/src/tools/miri/tests/fail/breakpoint.rs @@ -1,7 +1,5 @@ #![feature(core_intrinsics)] fn main() { - unsafe { - core::intrinsics::breakpoint() //~ ERROR: trace/breakpoint trap - }; + core::intrinsics::breakpoint(); //~ ERROR: trace/breakpoint trap } diff --git a/src/tools/miri/tests/fail/breakpoint.stderr b/src/tools/miri/tests/fail/breakpoint.stderr index ca98e81f1f4..f203cb0c15f 100644 --- a/src/tools/miri/tests/fail/breakpoint.stderr +++ b/src/tools/miri/tests/fail/breakpoint.stderr @@ -1,8 +1,8 @@ error: abnormal termination: trace/breakpoint trap --> tests/fail/breakpoint.rs:LL:CC | -LL | core::intrinsics::breakpoint() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trace/breakpoint trap +LL | core::intrinsics::breakpoint(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trace/breakpoint trap | = note: BACKTRACE: = note: inside `main` at tests/fail/breakpoint.rs:LL:CC diff --git a/src/tools/miri/tests/fail/enum-untagged-variant-invalid-encoding.rs b/src/tools/miri/tests/fail/enum-untagged-variant-invalid-encoding.rs new file mode 100644 index 00000000000..bd02e7f5fb4 --- /dev/null +++ b/src/tools/miri/tests/fail/enum-untagged-variant-invalid-encoding.rs @@ -0,0 +1,27 @@ +// Validity makes this fail at the wrong place. +//@compile-flags: -Zmiri-disable-validation +use std::mem; + +// This enum has untagged variant idx 1, with niche_variants being 0..=2 +// and niche_start being 2. +// That means the untagged variants is in the niche variant range! +// However, using the corresponding value (2+1 = 3) is not a valid encoding of this variant. +#[derive(Copy, Clone, PartialEq)] +enum Foo { + Var1, + Var2(bool), + Var3, +} + +fn main() { + unsafe { + assert!(Foo::Var2(false) == mem::transmute(0u8)); + assert!(Foo::Var2(true) == mem::transmute(1u8)); + assert!(Foo::Var1 == mem::transmute(2u8)); + assert!(Foo::Var3 == mem::transmute(4u8)); + + let invalid: Foo = mem::transmute(3u8); + assert!(matches!(invalid, Foo::Var2(_))); + //~^ ERROR: invalid tag + } +} diff --git a/src/tools/miri/tests/fail/enum-untagged-variant-invalid-encoding.stderr b/src/tools/miri/tests/fail/enum-untagged-variant-invalid-encoding.stderr new file mode 100644 index 00000000000..759dbc36380 --- /dev/null +++ b/src/tools/miri/tests/fail/enum-untagged-variant-invalid-encoding.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: enum value has invalid tag: 0x03 + --> tests/fail/enum-untagged-variant-invalid-encoding.rs:LL:CC + | +LL | assert!(matches!(invalid, Foo::Var2(_))); + | ^^^^^^^ enum value has invalid tag: 0x03 + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/enum-untagged-variant-invalid-encoding.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs index a35c92636ce..4b49e105562 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs @@ -47,9 +47,8 @@ fn test_readlink() { assert_eq!(res, small_buf.len() as isize); // Test that we report a proper error for a missing path. - let bad_path = CString::new("MIRI_MISSING_FILE_NAME").unwrap(); let res = unsafe { - libc::readlink(bad_path.as_ptr(), small_buf.as_mut_ptr().cast(), small_buf.len()) + libc::readlink(c"MIRI_MISSING_FILE_NAME".as_ptr(), small_buf.as_mut_ptr().cast(), small_buf.len()) }; assert_eq!(res, -1); assert_eq!(Error::last_os_error().kind(), ErrorKind::NotFound); diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.rs index ab3fd6733ff..cffcf4a867f 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.rs @@ -2,7 +2,6 @@ //@compile-flags: -Zmiri-isolation-error=warn-nobacktrace //@normalize-stderr-test: "(stat(x)?)" -> "$$STAT" -use std::ffi::CString; use std::fs; use std::io::{Error, ErrorKind}; @@ -13,10 +12,9 @@ fn main() { } // test `readlink` - let symlink_c_str = CString::new("foo.txt").unwrap(); let mut buf = vec![0; "foo_link.txt".len() + 1]; unsafe { - assert_eq!(libc::readlink(symlink_c_str.as_ptr(), buf.as_mut_ptr(), buf.len()), -1); + assert_eq!(libc::readlink(c"foo.txt".as_ptr(), buf.as_mut_ptr(), buf.len()), -1); assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EACCES)); } diff --git a/src/tools/miri/tests/pass-dep/libc/libc-mem.rs b/src/tools/miri/tests/pass-dep/libc/libc-mem.rs index 10be78798a6..727533a9de6 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-mem.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-mem.rs @@ -55,12 +55,12 @@ fn test_memcpy() { } fn test_strcpy() { - use std::ffi::{CStr, CString}; + use std::ffi::CStr; // case: src_size equals dest_size unsafe { - let src = CString::new("rust").unwrap(); - let size = src.as_bytes_with_nul().len(); + let src = c"rust"; + let size = src.to_bytes_with_nul().len(); let dest = libc::malloc(size); libc::strcpy(dest as *mut libc::c_char, src.as_ptr()); assert_eq!(CStr::from_ptr(dest as *const libc::c_char), src.as_ref()); @@ -69,8 +69,8 @@ fn test_strcpy() { // case: src_size is less than dest_size unsafe { - let src = CString::new("rust").unwrap(); - let size = src.as_bytes_with_nul().len(); + let src = c"rust"; + let size = src.to_bytes_with_nul().len(); let dest = libc::malloc(size + 1); libc::strcpy(dest as *mut libc::c_char, src.as_ptr()); assert_eq!(CStr::from_ptr(dest as *const libc::c_char), src.as_ref()); diff --git a/src/tools/miri/tests/pass/async-closure-captures.rs b/src/tools/miri/tests/pass/async-closure-captures.rs index cac26bfe146..423ef7a5cf7 100644 --- a/src/tools/miri/tests/pass/async-closure-captures.rs +++ b/src/tools/miri/tests/pass/async-closure-captures.rs @@ -1,6 +1,6 @@ // Same as rustc's `tests/ui/async-await/async-closures/captures.rs`, keep in sync -#![feature(async_closure, noop_waker)] +#![feature(async_closure, noop_waker, async_trait_bounds)] use std::future::Future; use std::pin::pin; diff --git a/src/tools/miri/tests/pass/async-closure-drop.rs b/src/tools/miri/tests/pass/async-closure-drop.rs index 9b2fc2948bf..264da5a9518 100644 --- a/src/tools/miri/tests/pass/async-closure-drop.rs +++ b/src/tools/miri/tests/pass/async-closure-drop.rs @@ -1,4 +1,4 @@ -#![feature(async_closure, noop_waker, async_fn_traits)] +#![feature(async_closure, noop_waker, async_trait_bounds)] use std::future::Future; use std::pin::pin; diff --git a/src/tools/miri/tests/pass/function_pointers.rs b/src/tools/miri/tests/pass/function_pointers.rs index a5c4bc5e0d9..7145be334a1 100644 --- a/src/tools/miri/tests/pass/function_pointers.rs +++ b/src/tools/miri/tests/pass/function_pointers.rs @@ -1,3 +1,5 @@ +#![allow(unpredictable_function_pointer_comparisons)] + use std::mem; trait Answer { diff --git a/src/tools/miri/tests/pass/issues/issue-91636.rs b/src/tools/miri/tests/pass/issues/issue-91636.rs index 00370165812..d0cadcd2c70 100644 --- a/src/tools/miri/tests/pass/issues/issue-91636.rs +++ b/src/tools/miri/tests/pass/issues/issue-91636.rs @@ -1,3 +1,5 @@ +#![allow(unpredictable_function_pointer_comparisons)] + type BuiltIn = for<'a> fn(&str); struct Function { diff --git a/src/tools/rust-analyzer/crates/profile/src/memory_usage.rs b/src/tools/rust-analyzer/crates/profile/src/memory_usage.rs index 660afff3dca..006748ddb08 100644 --- a/src/tools/rust-analyzer/crates/profile/src/memory_usage.rs +++ b/src/tools/rust-analyzer/crates/profile/src/memory_usage.rs @@ -62,15 +62,13 @@ fn memusage_linux() -> MemoryUsage { // mallinfo2 is very recent, so its presence needs to be detected at runtime. // Both are abysmally slow. - use std::ffi::CStr; use std::sync::atomic::{AtomicUsize, Ordering}; static MALLINFO2: AtomicUsize = AtomicUsize::new(1); let mut mallinfo2 = MALLINFO2.load(Ordering::Relaxed); if mallinfo2 == 1 { - let cstr = CStr::from_bytes_with_nul(b"mallinfo2\0").unwrap(); - mallinfo2 = unsafe { libc::dlsym(libc::RTLD_DEFAULT, cstr.as_ptr()) } as usize; + mallinfo2 = unsafe { libc::dlsym(libc::RTLD_DEFAULT, c"mallinfo2".as_ptr()) } as usize; // NB: races don't matter here, since they'll always store the same value MALLINFO2.store(mallinfo2, Ordering::Relaxed); } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index e065f01ebba..afa0b9a6760 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -307,7 +307,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "intl_pluralrules", "itertools", "itoa", - "jemalloc-sys", "jobserver", "lazy_static", "leb128", @@ -392,6 +391,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "thiserror-impl", "thorin-dwp", "thread_local", + "tikv-jemalloc-sys", "time", "time-core", "time-macros", diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index e2d1b85797f..9dc49b57d59 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -38,7 +38,7 @@ const IGNORE_UI_TEST_CHECK: &[&str] = macro_rules! verbose_print { ($verbose:expr, $($fmt:tt)*) => { if $verbose { - println!("{}", format_args!($($fmt)*)); + eprintln!("{}", format_args!($($fmt)*)); } }; } @@ -49,8 +49,8 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut // Stage 1: create list let error_codes = extract_error_codes(root_path, &mut errors); if verbose { - println!("Found {} error codes", error_codes.len()); - println!("Highest error code: `{}`", error_codes.iter().max().unwrap()); + eprintln!("Found {} error codes", error_codes.len()); + eprintln!("Highest error code: `{}`", error_codes.iter().max().unwrap()); } // Stage 2: check list has docs diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 4f24eb21242..4607d041577 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -158,14 +158,14 @@ pub fn check( .collect::<Vec<_>>(); for &(name, _) in gate_untested.iter() { - println!("Expected a gate test for the feature '{name}'."); - println!( + eprintln!("Expected a gate test for the feature '{name}'."); + eprintln!( "Hint: create a failing test file named 'tests/ui/feature-gates/feature-gate-{}.rs',\ \n with its failures due to missing usage of `#![feature({})]`.", name.replace("_", "-"), name ); - println!( + eprintln!( "Hint: If you already have such a test and don't want to rename it,\ \n you can also add a // gate-test-{} line to the test file.", name @@ -218,7 +218,7 @@ pub fn check( lines.sort(); for line in lines { - println!("* {line}"); + eprintln!("* {line}"); } } diff --git a/src/tools/tidy/src/fluent_period.rs b/src/tools/tidy/src/fluent_period.rs index 8bc404dc858..6a136e5aec6 100644 --- a/src/tools/tidy/src/fluent_period.rs +++ b/src/tools/tidy/src/fluent_period.rs @@ -18,7 +18,6 @@ const ALLOWLIST: &[&str] = &[ "const_eval_validation_failure_note", "driver_impl_ice", "incremental_corrupt_file", - "mir_build_pointer_pattern", ]; fn check_period(filename: &str, contents: &str, bad: &mut bool) { diff --git a/src/tools/tidy/src/unstable_book.rs b/src/tools/tidy/src/unstable_book.rs index 8be25b98df0..06d238ef5e4 100644 --- a/src/tools/tidy/src/unstable_book.rs +++ b/src/tools/tidy/src/unstable_book.rs @@ -118,16 +118,16 @@ pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) { // List unstable features that don't have Unstable Book sections. // Remove the comment marker if you want the list printed. /* - println!("Lib features without unstable book sections:"); + eprintln!("Lib features without unstable book sections:"); for feature_name in &unstable_lang_feature_names - &unstable_book_lang_features_section_file_names { - println!(" * {} {:?}", feature_name, lib_features[&feature_name].tracking_issue); + eprintln!(" * {} {:?}", feature_name, lib_features[&feature_name].tracking_issue); } - println!("Lang features without unstable book sections:"); + eprintln!("Lang features without unstable book sections:"); for feature_name in &unstable_lib_feature_names- &unstable_book_lib_features_section_file_names { - println!(" * {} {:?}", feature_name, lang_features[&feature_name].tracking_issue); + eprintln!(" * {} {:?}", feature_name, lang_features[&feature_name].tracking_issue); } // */ } diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index 489343561e1..b43d56202c9 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -42,7 +42,7 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { if let Some(expected) = get_x_wrapper_version(root, cargo) { if installed < expected { - return println!( + return eprintln!( "Current version of x is {installed}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" ); } diff --git a/src/tools/wasm-component-ld/Cargo.toml b/src/tools/wasm-component-ld/Cargo.toml index acdb1aa1ab7..965e9b01a44 100644 --- a/src/tools/wasm-component-ld/Cargo.toml +++ b/src/tools/wasm-component-ld/Cargo.toml @@ -10,4 +10,4 @@ name = "wasm-component-ld" path = "src/main.rs" [dependencies] -wasm-component-ld = "0.5.10" +wasm-component-ld = "0.5.11" diff --git a/tests/assembly/breakpoint.rs b/tests/assembly/breakpoint.rs new file mode 100644 index 00000000000..e0cc2d1eebb --- /dev/null +++ b/tests/assembly/breakpoint.rs @@ -0,0 +1,14 @@ +//@ revisions: aarch64 x86_64 +//@ assembly-output: emit-asm +//@[aarch64] only-aarch64 +//@[x86_64] only-x86_64 + +#![feature(breakpoint)] +#![crate_type = "lib"] + +// CHECK-LABEL: use_bp +// aarch64: brk #0xf000 +// x86_64: int3 +pub fn use_bp() { + core::arch::breakpoint(); +} diff --git a/tests/assembly/x86_64-bigint-add.rs b/tests/assembly/x86_64-bigint-helpers.rs index 4bcb9732c64..198e5543539 100644 --- a/tests/assembly/x86_64-bigint-add.rs +++ b/tests/assembly/x86_64-bigint-helpers.rs @@ -6,8 +6,8 @@ #![no_std] #![feature(bigint_helper_methods)] -// This checks that the `carrying_add` implementation successfully chains, to catch -// issues like <https://github.com/rust-lang/rust/issues/85532#issuecomment-2495119815> +// This checks that the `carrying_add` and `borrowing_sub` implementation successfully chain, +// to catch issues like <https://github.com/rust-lang/rust/issues/85532#issuecomment-2495119815> // This forces the ABI to avoid the windows-vs-linux ABI differences. @@ -31,3 +31,24 @@ pub unsafe extern "sysv64" fn bigint_chain_carrying_add( } carry } + +// CHECK-LABEL: bigint_chain_borrowing_sub: +#[no_mangle] +pub unsafe extern "sysv64" fn bigint_chain_borrowing_sub( + dest: *mut u64, + src1: *const u64, + src2: *const u64, + n: usize, + mut carry: bool, +) -> bool { + // CHECK: mov [[TEMP:r..]], qword ptr [rsi + 8*[[IND:r..]] + 8] + // CHECK: sbb [[TEMP]], qword ptr [rdx + 8*[[IND]] + 8] + // CHECK: mov qword ptr [rdi + 8*[[IND]] + 8], [[TEMP]] + // CHECK: mov [[TEMP]], qword ptr [rsi + 8*[[IND]] + 16] + // CHECK: sbb [[TEMP]], qword ptr [rdx + 8*[[IND]] + 16] + // CHECK: mov qword ptr [rdi + 8*[[IND]] + 16], [[TEMP]] + for i in 0..n { + (*dest.add(i), carry) = u64::borrowing_sub(*src1.add(i), *src2.add(i), carry); + } + carry +} diff --git a/tests/codegen/async-closure-debug.rs b/tests/codegen/async-closure-debug.rs index 9cb1e623295..644df169a36 100644 --- a/tests/codegen/async-closure-debug.rs +++ b/tests/codegen/async-closure-debug.rs @@ -9,7 +9,7 @@ #![feature(async_closure)] -fn async_closure_test(upvar: &str) -> impl async Fn() + '_ { +fn async_closure_test(upvar: &str) -> impl AsyncFn() + '_ { async move || { let hello = String::from("hello"); println!("{hello}, {upvar}"); diff --git a/tests/codegen/issues/issue-98678-async.rs b/tests/codegen/issues/issue-98678-async.rs new file mode 100644 index 00000000000..75f5d82eee5 --- /dev/null +++ b/tests/codegen/issues/issue-98678-async.rs @@ -0,0 +1,25 @@ +// This test verifies the accuracy of emitted file and line debuginfo metadata for async blocks and +// async functions. +// +//@ edition:2021 +//@ compile-flags: --crate-type=lib -Copt-level=0 -Cdebuginfo=2 -Zdebug-info-type-line-numbers=true + +// ignore-tidy-linelength + +// NONMSVC-DAG: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*[/\\]}}issue-98678-async.rs{{".*}}) +// MSVC: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*}}\\issue-98678-async.rs{{".*}}) + +// NONMSVC-DAG: !DISubprogram(name: "foo",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], +// MSVC-DAG: !DISubprogram(name: "foo",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], +pub async fn foo() -> u8 { + 5 +} + +pub fn bar() -> impl std::future::Future<Output = u8> { + // NONMSVC: !DICompositeType({{.*"}}{async_block_env#0}{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], + // MSVC-DAG: !DICompositeType({{.*"}}enum2$<issue_98678_async::bar::async_block_env$0>{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], + async { + let x: u8 = foo().await; + x + 5 + } +} diff --git a/tests/codegen/issues/issue-98678-closure-coroutine.rs b/tests/codegen/issues/issue-98678-closure-coroutine.rs new file mode 100644 index 00000000000..0730e56bf31 --- /dev/null +++ b/tests/codegen/issues/issue-98678-closure-coroutine.rs @@ -0,0 +1,22 @@ +// This test verifies the accuracy of emitted file and line debuginfo metadata for closures and +// coroutines. +// +//@ compile-flags: --crate-type=lib -Copt-level=0 -Cdebuginfo=2 -Zdebug-info-type-line-numbers=true +#![feature(coroutines, stmt_expr_attributes)] + +// ignore-tidy-linelength + +// NONMSVC-DAG: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*[/\\]}}issue-98678-closure-coroutine.rs{{".*}}) +// MSVC-DAG: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*}}\\issue-98678-closure-coroutine.rs{{".*}}) + +pub fn foo() { + // NONMSVC-DAG: !DICompositeType({{.*"}}{closure_env#0}{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], + // MSVC-DAG: !DICompositeType({{.*"}}closure_env$0{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], + let closure = |x| x; + closure(0); + + // NONMSVC-DAG: !DICompositeType({{.*"[{]}}coroutine_env#1{{[}]".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 3]], + // MSVC-DAG: !DICompositeType({{.*".*foo::}}coroutine_env$1>{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], + let _coroutine = #[coroutine] + || yield 1; +} diff --git a/tests/codegen/issues/issue-98678-enum.rs b/tests/codegen/issues/issue-98678-enum.rs new file mode 100644 index 00000000000..62c6cded866 --- /dev/null +++ b/tests/codegen/issues/issue-98678-enum.rs @@ -0,0 +1,40 @@ +// This test verifies the accuracy of emitted file and line debuginfo metadata enums. +// +//@ compile-flags: --crate-type=lib -Copt-level=0 -Cdebuginfo=2 -Zdebug-info-type-line-numbers=true + +// ignore-tidy-linelength + +// NONMSVC: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*[/\\]}}issue-98678-enum.rs{{".*}}) +// MSVC: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*}}\\issue-98678-enum.rs{{".*}}) + +// NONMSVC: !DICompositeType({{.*"}}SingleCase{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], +// MSVC: !DICompositeType({{.*"}}enum2$<issue_98678_enum::SingleCase>{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], +pub enum SingleCase { + // NONMSVC: !DIDerivedType(tag: DW_TAG_member, name: "One",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], + // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "One",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], + One, +} + +// NONMSVC: !DICompositeType({{.*"}}MultipleDataCases{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], +// MSVC: !DICompositeType({{.*"}}enum2$<issue_98678_enum::MultipleDataCases>{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], +pub enum MultipleDataCases { + // NONMSVC: !DIDerivedType(tag: DW_TAG_member, name: "Case1",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], + // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Case1",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], + Case1(u32), + // NONMSVC: !DIDerivedType(tag: DW_TAG_member, name: "Case2",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], + // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Case2",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], + Case2(i64), +} + +// NONMSVC: !DICompositeType({{.*"}}NicheLayout{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], +// MSVC: !DICompositeType({{.*"}}enum2$<issue_98678_enum::NicheLayout>{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], +pub enum NicheLayout { + // NONMSVC: !DIDerivedType(tag: DW_TAG_member, name: "Something",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], + // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Something",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], + Something(&'static u32), + // NONMSVC: !DIDerivedType(tag: DW_TAG_member, name: "Nothing",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]], + // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Nothing",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], + Nothing, +} + +pub fn foo(_: SingleCase, _: MultipleDataCases, _: NicheLayout) {} diff --git a/tests/codegen/issues/issue-98678-struct-union.rs b/tests/codegen/issues/issue-98678-struct-union.rs new file mode 100644 index 00000000000..bf2d6e731aa --- /dev/null +++ b/tests/codegen/issues/issue-98678-struct-union.rs @@ -0,0 +1,25 @@ +// This test verifies the accuracy of emitted file and line debuginfo metadata for structs and +// unions. +// +//@ compile-flags: --crate-type=lib -Copt-level=0 -Cdebuginfo=2 -Zdebug-info-type-line-numbers=true + +// ignore-tidy-linelength + +// NONMSVC: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*[/\\]}}issue-98678-struct-union.rs{{".*}}) +// MSVC: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*}}\\issue-98678-struct-union.rs{{".*}}) + +// CHECK: !DICompositeType({{.*"}}MyType{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], +pub struct MyType { + // CHECK: !DIDerivedType({{.*"}}i{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], + i: i32, +} + +// CHECK: !DICompositeType({{.*"}}MyUnion{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], +pub union MyUnion { + // CHECK: !DIDerivedType({{.*"}}i{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], + i: i32, + // CHECK: !DIDerivedType({{.*"}}f{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]], + f: f32, +} + +pub fn foo(_: MyType, _: MyUnion) {} diff --git a/tests/coverage/abort.cov-map b/tests/coverage/abort.cov-map index c121fa551dc..396edec275d 100644 --- a/tests/coverage/abort.cov-map +++ b/tests/coverage/abort.cov-map @@ -1,34 +1,34 @@ Function name: abort::main -Raw bytes (89): 0x[01, 01, 0a, 01, 27, 05, 09, 03, 0d, 22, 11, 03, 0d, 03, 0d, 22, 15, 03, 0d, 03, 0d, 05, 09, 0d, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 22, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 0e, 02, 09, 00, 0a, 22, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 1a, 00, 30, 00, 31, 22, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 30, 00, 31, 27, 01, 09, 00, 17, 0d, 02, 05, 01, 02] +Raw bytes (89): 0x[01, 01, 0a, 07, 09, 01, 05, 03, 0d, 03, 13, 0d, 11, 03, 0d, 03, 1f, 0d, 15, 03, 0d, 05, 09, 0d, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 22, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 0e, 02, 09, 00, 0a, 22, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 1a, 00, 30, 00, 31, 22, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 30, 00, 31, 27, 01, 09, 00, 17, 0d, 02, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 10 -- expression 0 operands: lhs = Counter(0), rhs = Expression(9, Add) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2) +- expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 3 operands: lhs = Expression(8, Sub), rhs = Counter(4) -- expression 4 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 3 operands: lhs = Expression(0, Add), rhs = Expression(4, Add) +- expression 4 operands: lhs = Counter(3), rhs = Counter(4) - expression 5 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 6 operands: lhs = Expression(8, Sub), rhs = Counter(5) -- expression 7 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 6 operands: lhs = Expression(0, Add), rhs = Expression(7, Add) +- expression 7 operands: lhs = Counter(3), rhs = Counter(5) - expression 8 operands: lhs = Expression(0, Add), rhs = Counter(3) - expression 9 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 13 - Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27) - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24) - = (c0 + (c1 + c2)) + = ((c0 + c1) + c2) - Code(Expression(8, Sub)) at (prev + 1, 12) to (start + 0, 25) - = ((c0 + (c1 + c2)) - c3) + = (((c0 + c1) + c2) - c3) - Code(Counter(4)) at (prev + 0, 26) to (start + 2, 10) - Code(Expression(3, Sub)) at (prev + 2, 9) to (start + 0, 10) - = (((c0 + (c1 + c2)) - c3) - c4) + = (((c0 + c1) + c2) - (c3 + c4)) - Code(Expression(8, Sub)) at (prev + 2, 12) to (start + 0, 25) - = ((c0 + (c1 + c2)) - c3) + = (((c0 + c1) + c2) - c3) - Code(Counter(5)) at (prev + 0, 26) to (start + 0, 49) - Code(Expression(6, Sub)) at (prev + 0, 48) to (start + 0, 49) - = (((c0 + (c1 + c2)) - c3) - c5) + = (((c0 + c1) + c2) - (c3 + c5)) - Code(Expression(8, Sub)) at (prev + 4, 12) to (start + 0, 25) - = ((c0 + (c1 + c2)) - c3) + = (((c0 + c1) + c2) - c3) - Code(Counter(1)) at (prev + 0, 26) to (start + 0, 49) - Code(Counter(2)) at (prev + 0, 48) to (start + 0, 49) - Code(Expression(9, Add)) at (prev + 1, 9) to (start + 0, 23) diff --git a/tests/coverage/assert.cov-map b/tests/coverage/assert.cov-map index b3cec390119..3bbf7a43e6d 100644 --- a/tests/coverage/assert.cov-map +++ b/tests/coverage/assert.cov-map @@ -1,29 +1,30 @@ Function name: assert::main -Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 09, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 09, 00, 0a, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02] +Raw bytes (67): 0x[01, 01, 09, 07, 0d, 0b, 09, 01, 05, 03, 11, 17, 11, 1b, 0d, 01, 09, 23, 0d, 05, 09, 09, 01, 09, 01, 01, 1b, 03, 02, 0b, 00, 18, 0e, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 09, 00, 0a, 1f, 01, 09, 00, 17, 11, 02, 05, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 8 -- expression 0 operands: lhs = Counter(0), rhs = Expression(6, Add) -- expression 1 operands: lhs = Counter(1), rhs = Expression(7, Add) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +Number of expressions: 9 +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(2) +- expression 2 operands: lhs = Counter(0), rhs = Counter(1) - expression 3 operands: lhs = Expression(0, Add), rhs = Counter(4) -- expression 4 operands: lhs = Expression(5, Sub), rhs = Counter(1) -- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(4) -- expression 6 operands: lhs = Counter(1), rhs = Expression(7, Add) -- expression 7 operands: lhs = Counter(2), rhs = Counter(3) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(4) +- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(3) +- expression 6 operands: lhs = Counter(0), rhs = Counter(2) +- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(3) +- expression 8 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 9, 1) to (start + 1, 27) - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24) - = (c0 + (c1 + (c2 + c3))) -- Code(Expression(5, Sub)) at (prev + 1, 12) to (start + 0, 26) - = ((c0 + (c1 + (c2 + c3))) - c4) + = (((c0 + c1) + c2) + c3) +- Code(Expression(3, Sub)) at (prev + 1, 12) to (start + 0, 26) + = ((((c0 + c1) + c2) + c3) - c4) - Code(Counter(1)) at (prev + 0, 27) to (start + 2, 10) - Code(Expression(4, Sub)) at (prev + 2, 19) to (start + 0, 32) - = (((c0 + (c1 + (c2 + c3))) - c4) - c1) + = (((c0 + c2) + c3) - c4) - Code(Counter(2)) at (prev + 0, 33) to (start + 2, 10) - Code(Counter(3)) at (prev + 2, 9) to (start + 0, 10) -- Code(Expression(6, Add)) at (prev + 1, 9) to (start + 0, 23) - = (c1 + (c2 + c3)) +- Code(Expression(7, Add)) at (prev + 1, 9) to (start + 0, 23) + = ((c1 + c2) + c3) - Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2) Highest counter ID seen: c4 diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map index 9a67cefcf98..c51bc6eb621 100644 --- a/tests/coverage/async.cov-map +++ b/tests/coverage/async.cov-map @@ -155,25 +155,25 @@ Number of file 0 mappings: 1 Highest counter ID seen: c0 Function name: async::i::{closure#0} -Raw bytes (63): 0x[01, 01, 02, 07, 19, 11, 15, 0b, 01, 2d, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 15, 01, 09, 00, 0a, 0d, 00, 0e, 00, 17, 1d, 00, 1b, 00, 20, 15, 00, 24, 00, 26, 19, 01, 0e, 00, 10, 03, 02, 01, 00, 02] +Raw bytes (63): 0x[01, 01, 02, 07, 15, 0d, 11, 0b, 01, 2d, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 11, 01, 09, 00, 0a, 19, 00, 0e, 00, 17, 1d, 00, 1b, 00, 20, 11, 00, 24, 00, 26, 15, 01, 0e, 00, 10, 03, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 -- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(6) -- expression 1 operands: lhs = Counter(4), rhs = Counter(5) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(5) +- expression 1 operands: lhs = Counter(3), rhs = Counter(4) Number of file 0 mappings: 11 - Code(Counter(0)) at (prev + 45, 19) to (start + 4, 12) - Code(Counter(2)) at (prev + 5, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 24) - Code(Counter(1)) at (prev + 0, 28) to (start + 0, 33) - Code(Counter(2)) at (prev + 0, 39) to (start + 0, 48) -- Code(Counter(5)) at (prev + 1, 9) to (start + 0, 10) -- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 23) +- Code(Counter(4)) at (prev + 1, 9) to (start + 0, 10) +- Code(Counter(6)) at (prev + 0, 14) to (start + 0, 23) - Code(Counter(7)) at (prev + 0, 27) to (start + 0, 32) -- Code(Counter(5)) at (prev + 0, 36) to (start + 0, 38) -- Code(Counter(6)) at (prev + 1, 14) to (start + 0, 16) +- Code(Counter(4)) at (prev + 0, 36) to (start + 0, 38) +- Code(Counter(5)) at (prev + 1, 14) to (start + 0, 16) - Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2) - = ((c4 + c5) + c6) + = ((c3 + c4) + c5) Highest counter ID seen: c7 Function name: async::j @@ -243,22 +243,19 @@ Number of file 0 mappings: 5 Highest counter ID seen: (none) Function name: async::l -Raw bytes (37): 0x[01, 01, 04, 01, 07, 05, 09, 0f, 02, 09, 05, 05, 01, 52, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02] +Raw bytes (33): 0x[01, 01, 02, 01, 07, 05, 09, 05, 01, 52, 01, 01, 0c, 02, 02, 0e, 00, 10, 09, 01, 0e, 00, 10, 05, 01, 0e, 00, 10, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 4 +Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) -- expression 2 operands: lhs = Expression(3, Add), rhs = Expression(0, Sub) -- expression 3 operands: lhs = Counter(2), rhs = Counter(1) Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 82, 1) to (start + 1, 12) - Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16) = (c0 - (c1 + c2)) -- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16) - Code(Counter(2)) at (prev + 1, 14) to (start + 0, 16) -- Code(Expression(2, Add)) at (prev + 2, 1) to (start + 0, 2) - = ((c2 + c1) + (c0 - (c1 + c2))) +- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16) +- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c2 Function name: async::m diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map index 4d00f0d9b33..9ff29af8e8e 100644 --- a/tests/coverage/async_closure.cov-map +++ b/tests/coverage/async_closure.cov-map @@ -1,19 +1,19 @@ Function name: async_closure::call_once::<async_closure::main::{closure#0}> -Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 2c] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 2b] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 44) +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 43) Highest counter ID seen: c0 Function name: async_closure::call_once::<async_closure::main::{closure#0}>::{closure#0} -Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 2c, 01, 0e, 05, 02, 01, 00, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 2b, 01, 0e, 05, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 7, 44) to (start + 1, 14) +- Code(Counter(0)) at (prev + 7, 43) to (start + 1, 14) - Code(Counter(1)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c1 diff --git a/tests/coverage/async_closure.coverage b/tests/coverage/async_closure.coverage index fd6edf7c29e..75da1a01fc1 100644 --- a/tests/coverage/async_closure.coverage +++ b/tests/coverage/async_closure.coverage @@ -4,7 +4,7 @@ LL| |//@ aux-build: executor.rs LL| |extern crate executor; LL| | - LL| 1|async fn call_once(f: impl async FnOnce()) { + LL| 1|async fn call_once(f: impl AsyncFnOnce()) { LL| 1| f().await; LL| 1|} LL| | diff --git a/tests/coverage/async_closure.rs b/tests/coverage/async_closure.rs index c076d03eef4..cbac592d957 100644 --- a/tests/coverage/async_closure.rs +++ b/tests/coverage/async_closure.rs @@ -4,7 +4,7 @@ //@ aux-build: executor.rs extern crate executor; -async fn call_once(f: impl async FnOnce()) { +async fn call_once(f: impl AsyncFnOnce()) { f().await; } diff --git a/tests/coverage/branch/guard.cov-map b/tests/coverage/branch/guard.cov-map index 0f33ed17a0a..1ba1c6e1228 100644 --- a/tests/coverage/branch/guard.cov-map +++ b/tests/coverage/branch/guard.cov-map @@ -1,5 +1,5 @@ Function name: guard::branch_match_guard -Raw bytes (85): 0x[01, 01, 06, 19, 0d, 05, 09, 0f, 15, 13, 11, 17, 0d, 05, 09, 0d, 01, 0c, 01, 01, 10, 1d, 03, 0b, 00, 0c, 15, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 19, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 1d, 00, 14, 00, 19, 20, 11, 09, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 17, 03, 0e, 02, 0a, 0b, 04, 01, 00, 02] +Raw bytes (85): 0x[01, 01, 06, 19, 0d, 05, 09, 0f, 15, 13, 11, 17, 0d, 05, 09, 0d, 01, 0c, 01, 01, 10, 02, 03, 0b, 00, 0c, 15, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 19, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 05, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 17, 03, 0e, 02, 0a, 0b, 04, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 6 @@ -11,7 +11,8 @@ Number of expressions: 6 - expression 5 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 13 - Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16) -- Code(Counter(7)) at (prev + 3, 11) to (start + 0, 12) +- Code(Expression(0, Sub)) at (prev + 3, 11) to (start + 0, 12) + = (c6 - c3) - Code(Counter(5)) at (prev + 1, 20) to (start + 2, 10) - Code(Counter(3)) at (prev + 3, 14) to (start + 0, 15) - Code(Counter(6)) at (prev + 0, 20) to (start + 0, 25) @@ -20,14 +21,15 @@ Number of file 0 mappings: 13 false = (c6 - c3) - Code(Counter(3)) at (prev + 0, 29) to (start + 2, 10) - Code(Counter(4)) at (prev + 3, 14) to (start + 0, 15) -- Code(Counter(7)) at (prev + 0, 20) to (start + 0, 25) -- Branch { true: Counter(4), false: Counter(2) } at (prev + 0, 20) to (start + 0, 30) +- Code(Expression(0, Sub)) at (prev + 0, 20) to (start + 0, 25) + = (c6 - c3) +- Branch { true: Counter(4), false: Counter(1) } at (prev + 0, 20) to (start + 0, 30) true = c4 - false = c2 + false = c1 - Code(Counter(4)) at (prev + 0, 29) to (start + 2, 10) - Code(Expression(5, Add)) at (prev + 3, 14) to (start + 2, 10) = (c1 + c2) - Code(Expression(2, Add)) at (prev + 4, 1) to (start + 0, 2) = ((((c1 + c2) + c3) + c4) + c5) -Highest counter ID seen: c7 +Highest counter ID seen: c6 diff --git a/tests/coverage/branch/if.cov-map b/tests/coverage/branch/if.cov-map index 0ad78a720a7..bab982dd44c 100644 --- a/tests/coverage/branch/if.cov-map +++ b/tests/coverage/branch/if.cov-map @@ -1,12 +1,14 @@ Function name: if::branch_and -Raw bytes (56): 0x[01, 01, 04, 05, 09, 0d, 02, 11, 0f, 0d, 02, 08, 01, 2b, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 00, 0d, 00, 0e, 20, 11, 0d, 00, 0d, 00, 0e, 11, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] +Raw bytes (60): 0x[01, 01, 06, 05, 09, 0b, 09, 05, 11, 13, 09, 17, 11, 05, 0d, 08, 01, 2b, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 00, 0d, 00, 0e, 20, 0d, 11, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 06, 02, 0c, 02, 06, 0e, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 4 +Number of expressions: 6 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) -- expression 1 operands: lhs = Counter(3), rhs = Expression(0, Sub) -- expression 2 operands: lhs = Counter(4), rhs = Expression(3, Add) -- expression 3 operands: lhs = Counter(3), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(2) +- expression 2 operands: lhs = Counter(1), rhs = Counter(4) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(2) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(4) +- expression 5 operands: lhs = Counter(1), rhs = Counter(3) Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 43, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 8) to (start + 0, 9) @@ -14,14 +16,14 @@ Number of file 0 mappings: 8 true = c2 false = (c1 - c2) - Code(Counter(2)) at (prev + 0, 13) to (start + 0, 14) -- Branch { true: Counter(4), false: Counter(3) } at (prev + 0, 13) to (start + 0, 14) - true = c4 - false = c3 -- Code(Counter(4)) at (prev + 0, 15) to (start + 2, 6) -- Code(Expression(3, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c3 + (c1 - c2)) -- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c4 + (c3 + (c1 - c2))) +- Branch { true: Counter(3), false: Counter(4) } at (prev + 0, 13) to (start + 0, 14) + true = c3 + false = c4 +- Code(Counter(3)) at (prev + 0, 15) to (start + 2, 6) +- Code(Expression(1, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c1 + c4) - c2) +- Code(Expression(3, Sub)) at (prev + 3, 1) to (start + 0, 2) + = (((c1 + c3) + c4) - c2) Highest counter ID seen: c4 Function name: if::branch_not diff --git a/tests/coverage/branch/lazy-boolean.cov-map b/tests/coverage/branch/lazy-boolean.cov-map index c2b6a5b8df2..decb847f60e 100644 --- a/tests/coverage/branch/lazy-boolean.cov-map +++ b/tests/coverage/branch/lazy-boolean.cov-map @@ -34,39 +34,49 @@ Number of file 0 mappings: 6 Highest counter ID seen: c2 Function name: lazy_boolean::chain -Raw bytes (149): 0x[01, 01, 13, 11, 07, 0b, 16, 15, 1a, 09, 0d, 05, 09, 05, 09, 09, 0d, 47, 25, 4b, 21, 19, 1d, 03, 19, 03, 19, 3e, 1d, 03, 19, 3e, 1d, 03, 19, 47, 25, 4b, 21, 19, 1d, 13, 01, 24, 01, 01, 10, 03, 04, 09, 00, 0a, 05, 00, 0d, 00, 12, 20, 09, 16, 00, 0d, 00, 12, 09, 00, 16, 00, 1b, 20, 0d, 1a, 00, 16, 00, 1b, 0d, 00, 1f, 00, 24, 20, 11, 15, 00, 1f, 00, 24, 11, 00, 28, 00, 2d, 03, 01, 05, 00, 11, 43, 03, 09, 00, 0a, 03, 00, 0d, 00, 12, 20, 19, 3e, 00, 0d, 00, 12, 3e, 00, 16, 00, 1b, 20, 1d, 3a, 00, 16, 00, 1b, 3a, 00, 1f, 00, 24, 20, 21, 25, 00, 1f, 00, 24, 25, 00, 28, 00, 2d, 43, 01, 05, 01, 02] +Raw bytes (169): 0x[01, 01, 1d, 5b, 0d, 5f, 15, 05, 11, 05, 09, 09, 0d, 6f, 25, 73, 21, 19, 1d, 5b, 67, 5f, 15, 05, 11, 0d, 19, 5b, 67, 5f, 15, 05, 11, 0d, 19, 5b, 63, 5f, 15, 05, 11, 67, 1d, 0d, 19, 5b, 63, 5f, 15, 05, 11, 67, 1d, 0d, 19, 6f, 25, 73, 21, 19, 1d, 13, 01, 24, 01, 01, 10, 02, 04, 09, 00, 0a, 05, 00, 0d, 00, 12, 20, 09, 0e, 00, 0d, 00, 12, 09, 00, 16, 00, 1b, 20, 0d, 12, 00, 16, 00, 1b, 0d, 00, 1f, 00, 24, 20, 11, 15, 00, 1f, 00, 24, 11, 00, 28, 00, 2d, 02, 01, 05, 00, 11, 6b, 03, 09, 00, 0a, 02, 00, 0d, 00, 12, 20, 19, 32, 00, 0d, 00, 12, 32, 00, 16, 00, 1b, 20, 1d, 56, 00, 16, 00, 1b, 56, 00, 1f, 00, 24, 20, 21, 25, 00, 1f, 00, 24, 25, 00, 28, 00, 2d, 6b, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 19 -- expression 0 operands: lhs = Counter(4), rhs = Expression(1, Add) -- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(5, Sub) -- expression 2 operands: lhs = Counter(5), rhs = Expression(6, Sub) -- expression 3 operands: lhs = Counter(2), rhs = Counter(3) -- expression 4 operands: lhs = Counter(1), rhs = Counter(2) -- expression 5 operands: lhs = Counter(1), rhs = Counter(2) -- expression 6 operands: lhs = Counter(2), rhs = Counter(3) -- expression 7 operands: lhs = Expression(17, Add), rhs = Counter(9) -- expression 8 operands: lhs = Expression(18, Add), rhs = Counter(8) -- expression 9 operands: lhs = Counter(6), rhs = Counter(7) -- expression 10 operands: lhs = Expression(0, Add), rhs = Counter(6) -- expression 11 operands: lhs = Expression(0, Add), rhs = Counter(6) -- expression 12 operands: lhs = Expression(15, Sub), rhs = Counter(7) -- expression 13 operands: lhs = Expression(0, Add), rhs = Counter(6) -- expression 14 operands: lhs = Expression(15, Sub), rhs = Counter(7) -- expression 15 operands: lhs = Expression(0, Add), rhs = Counter(6) -- expression 16 operands: lhs = Expression(17, Add), rhs = Counter(9) -- expression 17 operands: lhs = Expression(18, Add), rhs = Counter(8) -- expression 18 operands: lhs = Counter(6), rhs = Counter(7) +Number of expressions: 29 +- expression 0 operands: lhs = Expression(22, Add), rhs = Counter(3) +- expression 1 operands: lhs = Expression(23, Add), rhs = Counter(5) +- expression 2 operands: lhs = Counter(1), rhs = Counter(4) +- expression 3 operands: lhs = Counter(1), rhs = Counter(2) +- expression 4 operands: lhs = Counter(2), rhs = Counter(3) +- expression 5 operands: lhs = Expression(27, Add), rhs = Counter(9) +- expression 6 operands: lhs = Expression(28, Add), rhs = Counter(8) +- expression 7 operands: lhs = Counter(6), rhs = Counter(7) +- expression 8 operands: lhs = Expression(22, Add), rhs = Expression(25, Add) +- expression 9 operands: lhs = Expression(23, Add), rhs = Counter(5) +- expression 10 operands: lhs = Counter(1), rhs = Counter(4) +- expression 11 operands: lhs = Counter(3), rhs = Counter(6) +- expression 12 operands: lhs = Expression(22, Add), rhs = Expression(25, Add) +- expression 13 operands: lhs = Expression(23, Add), rhs = Counter(5) +- expression 14 operands: lhs = Counter(1), rhs = Counter(4) +- expression 15 operands: lhs = Counter(3), rhs = Counter(6) +- expression 16 operands: lhs = Expression(22, Add), rhs = Expression(24, Add) +- expression 17 operands: lhs = Expression(23, Add), rhs = Counter(5) +- expression 18 operands: lhs = Counter(1), rhs = Counter(4) +- expression 19 operands: lhs = Expression(25, Add), rhs = Counter(7) +- expression 20 operands: lhs = Counter(3), rhs = Counter(6) +- expression 21 operands: lhs = Expression(22, Add), rhs = Expression(24, Add) +- expression 22 operands: lhs = Expression(23, Add), rhs = Counter(5) +- expression 23 operands: lhs = Counter(1), rhs = Counter(4) +- expression 24 operands: lhs = Expression(25, Add), rhs = Counter(7) +- expression 25 operands: lhs = Counter(3), rhs = Counter(6) +- expression 26 operands: lhs = Expression(27, Add), rhs = Counter(9) +- expression 27 operands: lhs = Expression(28, Add), rhs = Counter(8) +- expression 28 operands: lhs = Counter(6), rhs = Counter(7) Number of file 0 mappings: 19 - Code(Counter(0)) at (prev + 36, 1) to (start + 1, 16) -- Code(Expression(0, Add)) at (prev + 4, 9) to (start + 0, 10) - = (c4 + ((c5 + (c2 - c3)) + (c1 - c2))) +- Code(Expression(0, Sub)) at (prev + 4, 9) to (start + 0, 10) + = (((c1 + c4) + c5) - c3) - Code(Counter(1)) at (prev + 0, 13) to (start + 0, 18) -- Branch { true: Counter(2), false: Expression(5, Sub) } at (prev + 0, 13) to (start + 0, 18) +- Branch { true: Counter(2), false: Expression(3, Sub) } at (prev + 0, 13) to (start + 0, 18) true = c2 false = (c1 - c2) - Code(Counter(2)) at (prev + 0, 22) to (start + 0, 27) -- Branch { true: Counter(3), false: Expression(6, Sub) } at (prev + 0, 22) to (start + 0, 27) +- Branch { true: Counter(3), false: Expression(4, Sub) } at (prev + 0, 22) to (start + 0, 27) true = c3 false = (c2 - c3) - Code(Counter(3)) at (prev + 0, 31) to (start + 0, 36) @@ -74,97 +84,87 @@ Number of file 0 mappings: 19 true = c4 false = c5 - Code(Counter(4)) at (prev + 0, 40) to (start + 0, 45) -- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 0, 17) - = (c4 + ((c5 + (c2 - c3)) + (c1 - c2))) -- Code(Expression(16, Add)) at (prev + 3, 9) to (start + 0, 10) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 17) + = (((c1 + c4) + c5) - c3) +- Code(Expression(26, Add)) at (prev + 3, 9) to (start + 0, 10) = (((c6 + c7) + c8) + c9) -- Code(Expression(0, Add)) at (prev + 0, 13) to (start + 0, 18) - = (c4 + ((c5 + (c2 - c3)) + (c1 - c2))) -- Branch { true: Counter(6), false: Expression(15, Sub) } at (prev + 0, 13) to (start + 0, 18) +- Code(Expression(0, Sub)) at (prev + 0, 13) to (start + 0, 18) + = (((c1 + c4) + c5) - c3) +- Branch { true: Counter(6), false: Expression(12, Sub) } at (prev + 0, 13) to (start + 0, 18) true = c6 - false = ((c4 + ((c5 + (c2 - c3)) + (c1 - c2))) - c6) -- Code(Expression(15, Sub)) at (prev + 0, 22) to (start + 0, 27) - = ((c4 + ((c5 + (c2 - c3)) + (c1 - c2))) - c6) -- Branch { true: Counter(7), false: Expression(14, Sub) } at (prev + 0, 22) to (start + 0, 27) + false = (((c1 + c4) + c5) - (c3 + c6)) +- Code(Expression(12, Sub)) at (prev + 0, 22) to (start + 0, 27) + = (((c1 + c4) + c5) - (c3 + c6)) +- Branch { true: Counter(7), false: Expression(21, Sub) } at (prev + 0, 22) to (start + 0, 27) true = c7 - false = (((c4 + ((c5 + (c2 - c3)) + (c1 - c2))) - c6) - c7) -- Code(Expression(14, Sub)) at (prev + 0, 31) to (start + 0, 36) - = (((c4 + ((c5 + (c2 - c3)) + (c1 - c2))) - c6) - c7) + false = (((c1 + c4) + c5) - ((c3 + c6) + c7)) +- Code(Expression(21, Sub)) at (prev + 0, 31) to (start + 0, 36) + = (((c1 + c4) + c5) - ((c3 + c6) + c7)) - Branch { true: Counter(8), false: Counter(9) } at (prev + 0, 31) to (start + 0, 36) true = c8 false = c9 - Code(Counter(9)) at (prev + 0, 40) to (start + 0, 45) -- Code(Expression(16, Add)) at (prev + 1, 5) to (start + 1, 2) +- Code(Expression(26, Add)) at (prev + 1, 5) to (start + 1, 2) = (((c6 + c7) + c8) + c9) Highest counter ID seen: c9 Function name: lazy_boolean::nested_mixed -Raw bytes (155): 0x[01, 01, 16, 33, 1a, 09, 0d, 1e, 0d, 05, 09, 05, 09, 05, 09, 1e, 0d, 05, 09, 09, 0d, 33, 11, 09, 0d, 33, 11, 09, 0d, 19, 57, 1d, 21, 03, 15, 15, 19, 4a, 4e, 15, 19, 03, 15, 19, 57, 1d, 21, 13, 01, 31, 01, 01, 10, 03, 04, 09, 00, 0a, 05, 00, 0e, 00, 13, 20, 09, 1e, 00, 0e, 00, 13, 1e, 00, 17, 00, 1d, 20, 0d, 1a, 00, 17, 00, 1d, 33, 00, 23, 00, 28, 20, 11, 2e, 00, 23, 00, 28, 2e, 00, 2c, 00, 33, 03, 01, 05, 00, 11, 53, 03, 09, 00, 0a, 03, 00, 0e, 00, 13, 20, 15, 4e, 00, 0e, 00, 13, 15, 00, 17, 00, 1c, 20, 19, 4a, 00, 17, 00, 1c, 47, 00, 22, 00, 28, 20, 1d, 21, 00, 22, 00, 28, 1d, 00, 2c, 00, 33, 53, 01, 05, 01, 02] +Raw bytes (141): 0x[01, 01, 0f, 05, 09, 05, 1f, 09, 0d, 09, 0d, 1f, 11, 09, 0d, 1f, 11, 09, 0d, 3b, 21, 19, 1d, 05, 15, 15, 19, 05, 19, 3b, 21, 19, 1d, 13, 01, 31, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0e, 00, 13, 20, 09, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 0d, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 11, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 05, 01, 05, 00, 11, 37, 03, 09, 00, 0a, 05, 00, 0e, 00, 13, 20, 15, 2a, 00, 0e, 00, 13, 15, 00, 17, 00, 1c, 20, 19, 2e, 00, 17, 00, 1c, 32, 00, 22, 00, 28, 20, 1d, 21, 00, 22, 00, 28, 1d, 00, 2c, 00, 33, 37, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 22 -- expression 0 operands: lhs = Expression(12, Add), rhs = Expression(6, Sub) -- expression 1 operands: lhs = Counter(2), rhs = Counter(3) -- expression 2 operands: lhs = Expression(7, Sub), rhs = Counter(3) -- expression 3 operands: lhs = Counter(1), rhs = Counter(2) -- expression 4 operands: lhs = Counter(1), rhs = Counter(2) -- expression 5 operands: lhs = Counter(1), rhs = Counter(2) -- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(3) -- expression 7 operands: lhs = Counter(1), rhs = Counter(2) -- expression 8 operands: lhs = Counter(2), rhs = Counter(3) -- expression 9 operands: lhs = Expression(12, Add), rhs = Counter(4) -- expression 10 operands: lhs = Counter(2), rhs = Counter(3) -- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(4) -- expression 12 operands: lhs = Counter(2), rhs = Counter(3) -- expression 13 operands: lhs = Counter(6), rhs = Expression(21, Add) -- expression 14 operands: lhs = Counter(7), rhs = Counter(8) -- expression 15 operands: lhs = Expression(0, Add), rhs = Counter(5) -- expression 16 operands: lhs = Counter(5), rhs = Counter(6) -- expression 17 operands: lhs = Expression(18, Sub), rhs = Expression(19, Sub) -- expression 18 operands: lhs = Counter(5), rhs = Counter(6) -- expression 19 operands: lhs = Expression(0, Add), rhs = Counter(5) -- expression 20 operands: lhs = Counter(6), rhs = Expression(21, Add) -- expression 21 operands: lhs = Counter(7), rhs = Counter(8) +Number of expressions: 15 +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +- expression 1 operands: lhs = Counter(1), rhs = Expression(7, Add) +- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +- expression 3 operands: lhs = Counter(2), rhs = Counter(3) +- expression 4 operands: lhs = Expression(7, Add), rhs = Counter(4) +- expression 5 operands: lhs = Counter(2), rhs = Counter(3) +- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4) +- expression 7 operands: lhs = Counter(2), rhs = Counter(3) +- expression 8 operands: lhs = Expression(14, Add), rhs = Counter(8) +- expression 9 operands: lhs = Counter(6), rhs = Counter(7) +- expression 10 operands: lhs = Counter(1), rhs = Counter(5) +- expression 11 operands: lhs = Counter(5), rhs = Counter(6) +- expression 12 operands: lhs = Counter(1), rhs = Counter(6) +- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(8) +- expression 14 operands: lhs = Counter(6), rhs = Counter(7) Number of file 0 mappings: 19 - Code(Counter(0)) at (prev + 49, 1) to (start + 1, 16) -- Code(Expression(0, Add)) at (prev + 4, 9) to (start + 0, 10) - = ((c2 + c3) + ((c1 - c2) - c3)) +- Code(Counter(1)) at (prev + 4, 9) to (start + 0, 10) - Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19) -- Branch { true: Counter(2), false: Expression(7, Sub) } at (prev + 0, 14) to (start + 0, 19) +- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 14) to (start + 0, 19) true = c2 false = (c1 - c2) -- Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 29) +- Code(Expression(0, Sub)) at (prev + 0, 23) to (start + 0, 29) = (c1 - c2) -- Branch { true: Counter(3), false: Expression(6, Sub) } at (prev + 0, 23) to (start + 0, 29) +- Branch { true: Counter(3), false: Expression(1, Sub) } at (prev + 0, 23) to (start + 0, 29) true = c3 - false = ((c1 - c2) - c3) -- Code(Expression(12, Add)) at (prev + 0, 35) to (start + 0, 40) + false = (c1 - (c2 + c3)) +- Code(Expression(7, Add)) at (prev + 0, 35) to (start + 0, 40) = (c2 + c3) -- Branch { true: Counter(4), false: Expression(11, Sub) } at (prev + 0, 35) to (start + 0, 40) +- Branch { true: Counter(4), false: Expression(6, Sub) } at (prev + 0, 35) to (start + 0, 40) true = c4 false = ((c2 + c3) - c4) -- Code(Expression(11, Sub)) at (prev + 0, 44) to (start + 0, 51) +- Code(Expression(6, Sub)) at (prev + 0, 44) to (start + 0, 51) = ((c2 + c3) - c4) -- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 0, 17) - = ((c2 + c3) + ((c1 - c2) - c3)) -- Code(Expression(20, Add)) at (prev + 3, 9) to (start + 0, 10) - = (c6 + (c7 + c8)) -- Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 19) - = ((c2 + c3) + ((c1 - c2) - c3)) -- Branch { true: Counter(5), false: Expression(19, Sub) } at (prev + 0, 14) to (start + 0, 19) +- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 17) +- Code(Expression(13, Add)) at (prev + 3, 9) to (start + 0, 10) + = ((c6 + c7) + c8) +- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19) +- Branch { true: Counter(5), false: Expression(10, Sub) } at (prev + 0, 14) to (start + 0, 19) true = c5 - false = (((c2 + c3) + ((c1 - c2) - c3)) - c5) + false = (c1 - c5) - Code(Counter(5)) at (prev + 0, 23) to (start + 0, 28) -- Branch { true: Counter(6), false: Expression(18, Sub) } at (prev + 0, 23) to (start + 0, 28) +- Branch { true: Counter(6), false: Expression(11, Sub) } at (prev + 0, 23) to (start + 0, 28) true = c6 false = (c5 - c6) -- Code(Expression(17, Add)) at (prev + 0, 34) to (start + 0, 40) - = ((c5 - c6) + (((c2 + c3) + ((c1 - c2) - c3)) - c5)) +- Code(Expression(12, Sub)) at (prev + 0, 34) to (start + 0, 40) + = (c1 - c6) - Branch { true: Counter(7), false: Counter(8) } at (prev + 0, 34) to (start + 0, 40) true = c7 false = c8 - Code(Counter(7)) at (prev + 0, 44) to (start + 0, 51) -- Code(Expression(20, Add)) at (prev + 1, 5) to (start + 1, 2) - = (c6 + (c7 + c8)) +- Code(Expression(13, Add)) at (prev + 1, 5) to (start + 1, 2) + = ((c6 + c7) + c8) Highest counter ID seen: c8 diff --git a/tests/coverage/branch/match-arms.cov-map b/tests/coverage/branch/match-arms.cov-map index fd0366ee818..a93df9814ee 100644 --- a/tests/coverage/branch/match-arms.cov-map +++ b/tests/coverage/branch/match-arms.cov-map @@ -1,12 +1,12 @@ Function name: match_arms::guards -Raw bytes (88): 0x[01, 01, 08, 07, 15, 0b, 11, 0f, 0d, 00, 09, 17, 25, 1b, 21, 1f, 1d, 03, 19, 0c, 01, 30, 01, 01, 10, 29, 03, 0b, 00, 10, 19, 01, 11, 00, 29, 20, 19, 09, 00, 17, 00, 1b, 1d, 01, 11, 00, 29, 20, 1d, 0d, 00, 17, 00, 1b, 21, 01, 11, 00, 29, 20, 21, 11, 00, 17, 00, 1b, 25, 01, 11, 00, 29, 20, 25, 15, 00, 17, 00, 1b, 03, 01, 0e, 00, 18, 13, 03, 05, 01, 02] +Raw bytes (88): 0x[01, 01, 08, 07, 00, 0b, 11, 0f, 0d, 05, 09, 17, 25, 1b, 21, 1f, 1d, 03, 19, 0c, 01, 30, 01, 01, 10, 29, 03, 0b, 00, 10, 19, 01, 11, 00, 29, 20, 19, 05, 00, 17, 00, 1b, 1d, 01, 11, 00, 29, 20, 1d, 09, 00, 17, 00, 1b, 21, 01, 11, 00, 29, 20, 21, 0d, 00, 17, 00, 1b, 25, 01, 11, 00, 29, 20, 25, 11, 00, 17, 00, 1b, 03, 01, 0e, 00, 18, 13, 03, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 8 -- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(5) +- expression 0 operands: lhs = Expression(1, Add), rhs = Zero - expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4) - expression 2 operands: lhs = Expression(3, Add), rhs = Counter(3) -- expression 3 operands: lhs = Zero, rhs = Counter(2) +- expression 3 operands: lhs = Counter(1), rhs = Counter(2) - expression 4 operands: lhs = Expression(5, Add), rhs = Counter(9) - expression 5 operands: lhs = Expression(6, Add), rhs = Counter(8) - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(7) @@ -15,81 +15,67 @@ Number of file 0 mappings: 12 - Code(Counter(0)) at (prev + 48, 1) to (start + 1, 16) - Code(Counter(10)) at (prev + 3, 11) to (start + 0, 16) - Code(Counter(6)) at (prev + 1, 17) to (start + 0, 41) -- Branch { true: Counter(6), false: Counter(2) } at (prev + 0, 23) to (start + 0, 27) +- Branch { true: Counter(6), false: Counter(1) } at (prev + 0, 23) to (start + 0, 27) true = c6 - false = c2 + false = c1 - Code(Counter(7)) at (prev + 1, 17) to (start + 0, 41) -- Branch { true: Counter(7), false: Counter(3) } at (prev + 0, 23) to (start + 0, 27) +- Branch { true: Counter(7), false: Counter(2) } at (prev + 0, 23) to (start + 0, 27) true = c7 - false = c3 + false = c2 - Code(Counter(8)) at (prev + 1, 17) to (start + 0, 41) -- Branch { true: Counter(8), false: Counter(4) } at (prev + 0, 23) to (start + 0, 27) +- Branch { true: Counter(8), false: Counter(3) } at (prev + 0, 23) to (start + 0, 27) true = c8 - false = c4 + false = c3 - Code(Counter(9)) at (prev + 1, 17) to (start + 0, 41) -- Branch { true: Counter(9), false: Counter(5) } at (prev + 0, 23) to (start + 0, 27) +- Branch { true: Counter(9), false: Counter(4) } at (prev + 0, 23) to (start + 0, 27) true = c9 - false = c5 + false = c4 - Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 24) - = ((((Zero + c2) + c3) + c4) + c5) + = ((((c1 + c2) + c3) + c4) + Zero) - Code(Expression(4, Add)) at (prev + 3, 5) to (start + 1, 2) - = ((((((((Zero + c2) + c3) + c4) + c5) + c6) + c7) + c8) + c9) + = ((((((((c1 + c2) + c3) + c4) + Zero) + c6) + c7) + c8) + c9) Highest counter ID seen: c10 Function name: match_arms::match_arms -Raw bytes (51): 0x[01, 01, 06, 05, 07, 0b, 11, 09, 0d, 13, 02, 17, 09, 11, 0d, 07, 01, 18, 01, 01, 10, 05, 03, 0b, 00, 10, 11, 01, 11, 00, 21, 0d, 01, 11, 00, 21, 09, 01, 11, 00, 21, 02, 01, 11, 00, 21, 0f, 03, 05, 01, 02] +Raw bytes (45): 0x[01, 01, 03, 05, 07, 0b, 11, 09, 0d, 07, 01, 18, 01, 01, 10, 05, 03, 0b, 00, 10, 09, 01, 11, 00, 21, 0d, 01, 11, 00, 21, 11, 01, 11, 00, 21, 02, 01, 11, 00, 21, 05, 03, 05, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 6 +Number of expressions: 3 - expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add) - expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4) - expression 2 operands: lhs = Counter(2), rhs = Counter(3) -- expression 3 operands: lhs = Expression(4, Add), rhs = Expression(0, Sub) -- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(2) -- expression 5 operands: lhs = Counter(4), rhs = Counter(3) Number of file 0 mappings: 7 - Code(Counter(0)) at (prev + 24, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 11) to (start + 0, 16) -- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 33) -- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33) - Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33) +- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33) +- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 33) - Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 33) = (c1 - ((c2 + c3) + c4)) -- Code(Expression(3, Add)) at (prev + 3, 5) to (start + 1, 2) - = (((c4 + c3) + c2) + (c1 - ((c2 + c3) + c4))) +- Code(Counter(1)) at (prev + 3, 5) to (start + 1, 2) Highest counter ID seen: c4 Function name: match_arms::or_patterns -Raw bytes (75): 0x[01, 01, 0d, 11, 0d, 05, 2f, 33, 11, 09, 0d, 09, 2a, 05, 2f, 33, 11, 09, 0d, 03, 27, 09, 2a, 05, 2f, 33, 11, 09, 0d, 09, 01, 25, 01, 01, 10, 05, 03, 0b, 00, 10, 11, 01, 11, 00, 12, 0d, 00, 1e, 00, 1f, 03, 00, 24, 00, 2e, 09, 01, 11, 00, 12, 2a, 00, 1e, 00, 1f, 27, 00, 24, 00, 2e, 23, 03, 05, 01, 02] +Raw bytes (57): 0x[01, 01, 04, 09, 0d, 05, 0b, 03, 11, 05, 03, 09, 01, 25, 01, 01, 10, 05, 03, 0b, 00, 10, 09, 01, 11, 00, 12, 0d, 00, 1e, 00, 1f, 03, 00, 24, 00, 2e, 11, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2e, 05, 03, 05, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 13 -- expression 0 operands: lhs = Counter(4), rhs = Counter(3) -- expression 1 operands: lhs = Counter(1), rhs = Expression(11, Add) -- expression 2 operands: lhs = Expression(12, Add), rhs = Counter(4) -- expression 3 operands: lhs = Counter(2), rhs = Counter(3) -- expression 4 operands: lhs = Counter(2), rhs = Expression(10, Sub) -- expression 5 operands: lhs = Counter(1), rhs = Expression(11, Add) -- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(4) -- expression 7 operands: lhs = Counter(2), rhs = Counter(3) -- expression 8 operands: lhs = Expression(0, Add), rhs = Expression(9, Add) -- expression 9 operands: lhs = Counter(2), rhs = Expression(10, Sub) -- expression 10 operands: lhs = Counter(1), rhs = Expression(11, Add) -- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(4) -- expression 12 operands: lhs = Counter(2), rhs = Counter(3) +Number of expressions: 4 +- expression 0 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) +- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(4) +- expression 3 operands: lhs = Counter(1), rhs = Expression(0, Add) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 37, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 11) to (start + 0, 16) -- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 18) +- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18) - Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31) - Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 46) - = (c4 + c3) -- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18) -- Code(Expression(10, Sub)) at (prev + 0, 30) to (start + 0, 31) + = (c2 + c3) +- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 18) +- Code(Expression(1, Sub)) at (prev + 0, 30) to (start + 0, 31) = (c1 - ((c2 + c3) + c4)) -- Code(Expression(9, Add)) at (prev + 0, 36) to (start + 0, 46) - = (c2 + (c1 - ((c2 + c3) + c4))) -- Code(Expression(8, Add)) at (prev + 3, 5) to (start + 1, 2) - = ((c4 + c3) + (c2 + (c1 - ((c2 + c3) + c4)))) +- Code(Expression(3, Sub)) at (prev + 0, 36) to (start + 0, 46) + = (c1 - (c2 + c3)) +- Code(Counter(1)) at (prev + 3, 5) to (start + 1, 2) Highest counter ID seen: c4 diff --git a/tests/coverage/branch/no-mir-spans.cov-map b/tests/coverage/branch/no-mir-spans.cov-map index ab12732b1ed..6003efc36ca 100644 --- a/tests/coverage/branch/no-mir-spans.cov-map +++ b/tests/coverage/branch/no-mir-spans.cov-map @@ -23,19 +23,19 @@ Number of file 0 mappings: 2 Highest counter ID seen: c2 Function name: no_mir_spans::while_op_and -Raw bytes (25): 0x[01, 01, 01, 09, 0d, 03, 01, 22, 01, 00, 13, 20, 09, 05, 05, 0b, 00, 10, 20, 02, 0d, 00, 14, 00, 19] +Raw bytes (25): 0x[01, 01, 01, 05, 09, 03, 01, 22, 01, 00, 13, 20, 05, 0d, 05, 0b, 00, 10, 20, 02, 09, 00, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 -- expression 0 operands: lhs = Counter(2), rhs = Counter(3) +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 34, 1) to (start + 0, 19) -- Branch { true: Counter(2), false: Counter(1) } at (prev + 5, 11) to (start + 0, 16) - true = c2 - false = c1 -- Branch { true: Expression(0, Sub), false: Counter(3) } at (prev + 0, 20) to (start + 0, 25) - true = (c2 - c3) +- Branch { true: Counter(1), false: Counter(3) } at (prev + 5, 11) to (start + 0, 16) + true = c1 false = c3 +- Branch { true: Expression(0, Sub), false: Counter(2) } at (prev + 0, 20) to (start + 0, 25) + true = (c1 - c2) + false = c2 Highest counter ID seen: c3 Function name: no_mir_spans::while_op_or diff --git a/tests/coverage/branch/while.cov-map b/tests/coverage/branch/while.cov-map index d5840a2c320..305f6bc74d8 100644 --- a/tests/coverage/branch/while.cov-map +++ b/tests/coverage/branch/while.cov-map @@ -35,14 +35,14 @@ Number of file 0 mappings: 6 Highest counter ID seen: c2 Function name: while::while_op_and -Raw bytes (56): 0x[01, 01, 04, 05, 09, 03, 0d, 03, 0d, 11, 0d, 08, 01, 1e, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 0a, 0d, 00, 0b, 00, 10, 0a, 00, 14, 00, 19, 20, 09, 11, 00, 14, 00, 19, 09, 00, 1a, 03, 06, 0f, 04, 01, 00, 02] +Raw bytes (56): 0x[01, 01, 04, 05, 09, 03, 0d, 03, 0d, 0d, 11, 08, 01, 1e, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 0a, 0d, 00, 0b, 00, 10, 0a, 00, 14, 00, 19, 20, 09, 11, 00, 14, 00, 19, 09, 00, 1a, 03, 06, 0f, 04, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Expression(0, Add), rhs = Counter(3) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 3 operands: lhs = Counter(4), rhs = Counter(3) +- expression 3 operands: lhs = Counter(3), rhs = Counter(4) Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 30, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 9) to (start + 1, 18) @@ -58,39 +58,34 @@ Number of file 0 mappings: 8 false = c4 - Code(Counter(2)) at (prev + 0, 26) to (start + 3, 6) - Code(Expression(3, Add)) at (prev + 4, 1) to (start + 0, 2) - = (c4 + c3) + = (c3 + c4) Highest counter ID seen: c4 Function name: while::while_op_or -Raw bytes (66): 0x[01, 01, 09, 05, 1b, 09, 0d, 03, 09, 03, 09, 22, 0d, 03, 09, 09, 0d, 22, 0d, 03, 09, 08, 01, 29, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 09, 22, 00, 0b, 00, 10, 22, 00, 14, 00, 19, 20, 0d, 1e, 00, 14, 00, 19, 1b, 00, 1a, 03, 06, 1e, 04, 01, 00, 02] +Raw bytes (58): 0x[01, 01, 05, 07, 0d, 05, 09, 05, 0d, 05, 0d, 09, 0d, 08, 01, 29, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 09, 0f, 00, 0b, 00, 10, 0f, 00, 14, 00, 19, 20, 0d, 05, 00, 14, 00, 19, 13, 00, 1a, 03, 06, 05, 04, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 9 -- expression 0 operands: lhs = Counter(1), rhs = Expression(6, Add) -- expression 1 operands: lhs = Counter(2), rhs = Counter(3) -- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(2) -- expression 3 operands: lhs = Expression(0, Add), rhs = Counter(2) -- expression 4 operands: lhs = Expression(8, Sub), rhs = Counter(3) -- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(2) -- expression 6 operands: lhs = Counter(2), rhs = Counter(3) -- expression 7 operands: lhs = Expression(8, Sub), rhs = Counter(3) -- expression 8 operands: lhs = Expression(0, Add), rhs = Counter(2) +Number of expressions: 5 +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 2 operands: lhs = Counter(1), rhs = Counter(3) +- expression 3 operands: lhs = Counter(1), rhs = Counter(3) +- expression 4 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 41, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 9) to (start + 1, 18) - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 16) - = (c1 + (c2 + c3)) -- Branch { true: Counter(2), false: Expression(8, Sub) } at (prev + 0, 11) to (start + 0, 16) + = ((c1 + c2) + c3) +- Branch { true: Counter(2), false: Expression(3, Add) } at (prev + 0, 11) to (start + 0, 16) true = c2 - false = ((c1 + (c2 + c3)) - c2) -- Code(Expression(8, Sub)) at (prev + 0, 20) to (start + 0, 25) - = ((c1 + (c2 + c3)) - c2) -- Branch { true: Counter(3), false: Expression(7, Sub) } at (prev + 0, 20) to (start + 0, 25) + false = (c1 + c3) +- Code(Expression(3, Add)) at (prev + 0, 20) to (start + 0, 25) + = (c1 + c3) +- Branch { true: Counter(3), false: Counter(1) } at (prev + 0, 20) to (start + 0, 25) true = c3 - false = (((c1 + (c2 + c3)) - c2) - c3) -- Code(Expression(6, Add)) at (prev + 0, 26) to (start + 3, 6) + false = c1 +- Code(Expression(4, Add)) at (prev + 0, 26) to (start + 3, 6) = (c2 + c3) -- Code(Expression(7, Sub)) at (prev + 4, 1) to (start + 0, 2) - = (((c1 + (c2 + c3)) - c2) - c3) +- Code(Counter(1)) at (prev + 4, 1) to (start + 0, 2) Highest counter ID seen: c3 diff --git a/tests/coverage/closure_macro.cov-map b/tests/coverage/closure_macro.cov-map index 7c9d3292f98..aedb924eca8 100644 --- a/tests/coverage/closure_macro.cov-map +++ b/tests/coverage/closure_macro.cov-map @@ -25,13 +25,13 @@ Number of file 0 mappings: 6 Highest counter ID seen: c1 Function name: closure_macro::main::{closure#0} -Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 0d, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 0d, 00, 17, 00, 1e, 07, 02, 09, 00, 0a] +Raw bytes (35): 0x[01, 01, 03, 01, 05, 0b, 0d, 05, 09, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 0d, 00, 17, 00, 1e, 07, 02, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3) +- expression 2 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 16, 28) to (start + 3, 33) - Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39) @@ -39,6 +39,6 @@ Number of file 0 mappings: 5 = (c0 - c1) - Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30) - Code(Expression(1, Add)) at (prev + 2, 9) to (start + 0, 10) - = (c1 + (c2 + c3)) + = ((c1 + c2) + c3) Highest counter ID seen: c3 diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map index e2a52e57015..5b99889514c 100644 --- a/tests/coverage/closure_macro_async.cov-map +++ b/tests/coverage/closure_macro_async.cov-map @@ -34,13 +34,13 @@ Number of file 0 mappings: 6 Highest counter ID seen: c1 Function name: closure_macro_async::test::{closure#0}::{closure#0} -Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 0d, 05, 01, 15, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 0d, 00, 17, 00, 1e, 07, 02, 09, 00, 0a] +Raw bytes (35): 0x[01, 01, 03, 01, 05, 0b, 0d, 05, 09, 05, 01, 15, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 0d, 00, 17, 00, 1e, 07, 02, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3) +- expression 2 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 21, 28) to (start + 3, 33) - Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39) @@ -48,6 +48,6 @@ Number of file 0 mappings: 5 = (c0 - c1) - Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30) - Code(Expression(1, Add)) at (prev + 2, 9) to (start + 0, 10) - = (c1 + (c2 + c3)) + = ((c1 + c2) + c3) Highest counter ID seen: c3 diff --git a/tests/coverage/condition/conditions.cov-map b/tests/coverage/condition/conditions.cov-map index 208d671919c..72f39b88c6a 100644 --- a/tests/coverage/condition/conditions.cov-map +++ b/tests/coverage/condition/conditions.cov-map @@ -1,29 +1,27 @@ Function name: conditions::assign_3_and_or -Raw bytes (69): 0x[01, 01, 07, 07, 11, 09, 0d, 01, 05, 05, 09, 16, 1a, 05, 09, 01, 05, 09, 01, 1c, 01, 00, 2f, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 1a, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 16, 00, 12, 00, 13, 13, 00, 17, 00, 18, 20, 0d, 11, 00, 17, 00, 18, 03, 01, 05, 01, 02] +Raw bytes (65): 0x[01, 01, 05, 07, 11, 09, 0d, 01, 05, 05, 09, 01, 09, 09, 01, 1c, 01, 00, 2f, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 0a, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 0e, 00, 12, 00, 13, 12, 00, 17, 00, 18, 20, 0d, 11, 00, 17, 00, 18, 03, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 7 +Number of expressions: 5 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(4) - expression 1 operands: lhs = Counter(2), rhs = Counter(3) - expression 2 operands: lhs = Counter(0), rhs = Counter(1) - expression 3 operands: lhs = Counter(1), rhs = Counter(2) -- expression 4 operands: lhs = Expression(5, Sub), rhs = Expression(6, Sub) -- expression 5 operands: lhs = Counter(1), rhs = Counter(2) -- expression 6 operands: lhs = Counter(0), rhs = Counter(1) +- expression 4 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 28, 1) to (start + 0, 47) - Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) = ((c2 + c3) + c4) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) -- Branch { true: Counter(1), false: Expression(6, Sub) } at (prev + 0, 13) to (start + 0, 14) +- Branch { true: Counter(1), false: Expression(2, Sub) } at (prev + 0, 13) to (start + 0, 14) true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) -- Branch { true: Counter(2), false: Expression(5, Sub) } at (prev + 0, 18) to (start + 0, 19) +- Branch { true: Counter(2), false: Expression(3, Sub) } at (prev + 0, 18) to (start + 0, 19) true = c2 false = (c1 - c2) -- Code(Expression(4, Add)) at (prev + 0, 23) to (start + 0, 24) - = ((c1 - c2) + (c0 - c1)) +- Code(Expression(4, Sub)) at (prev + 0, 23) to (start + 0, 24) + = (c0 - c2) - Branch { true: Counter(3), false: Counter(4) } at (prev + 0, 23) to (start + 0, 24) true = c3 false = c4 @@ -32,54 +30,54 @@ Number of file 0 mappings: 9 Highest counter ID seen: c4 Function name: conditions::assign_3_or_and -Raw bytes (73): 0x[01, 01, 09, 05, 07, 0b, 11, 09, 0d, 01, 05, 01, 05, 22, 11, 01, 05, 22, 11, 01, 05, 09, 01, 17, 01, 00, 2f, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 22, 00, 0d, 00, 0e, 22, 00, 12, 00, 13, 20, 1e, 11, 00, 12, 00, 13, 1e, 00, 17, 00, 18, 20, 09, 0d, 00, 17, 00, 18, 03, 01, 05, 01, 02] +Raw bytes (73): 0x[01, 01, 09, 07, 11, 0b, 0d, 05, 09, 01, 05, 01, 05, 01, 23, 05, 11, 01, 23, 05, 11, 09, 01, 17, 01, 00, 2f, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 12, 00, 0d, 00, 0e, 12, 00, 12, 00, 13, 20, 1e, 11, 00, 12, 00, 13, 1e, 00, 17, 00, 18, 20, 09, 0d, 00, 17, 00, 18, 03, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 9 -- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add) -- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(4) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3) +- expression 2 operands: lhs = Counter(1), rhs = Counter(2) - expression 3 operands: lhs = Counter(0), rhs = Counter(1) - expression 4 operands: lhs = Counter(0), rhs = Counter(1) -- expression 5 operands: lhs = Expression(8, Sub), rhs = Counter(4) -- expression 6 operands: lhs = Counter(0), rhs = Counter(1) -- expression 7 operands: lhs = Expression(8, Sub), rhs = Counter(4) -- expression 8 operands: lhs = Counter(0), rhs = Counter(1) +- expression 5 operands: lhs = Counter(0), rhs = Expression(8, Add) +- expression 6 operands: lhs = Counter(1), rhs = Counter(4) +- expression 7 operands: lhs = Counter(0), rhs = Expression(8, Add) +- expression 8 operands: lhs = Counter(1), rhs = Counter(4) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 23, 1) to (start + 0, 47) - Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) - = (c1 + ((c2 + c3) + c4)) + = (((c1 + c2) + c3) + c4) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) -- Branch { true: Counter(1), false: Expression(8, Sub) } at (prev + 0, 13) to (start + 0, 14) +- Branch { true: Counter(1), false: Expression(4, Sub) } at (prev + 0, 13) to (start + 0, 14) true = c1 false = (c0 - c1) -- Code(Expression(8, Sub)) at (prev + 0, 18) to (start + 0, 19) +- Code(Expression(4, Sub)) at (prev + 0, 18) to (start + 0, 19) = (c0 - c1) - Branch { true: Expression(7, Sub), false: Counter(4) } at (prev + 0, 18) to (start + 0, 19) - true = ((c0 - c1) - c4) + true = (c0 - (c1 + c4)) false = c4 - Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 24) - = ((c0 - c1) - c4) + = (c0 - (c1 + c4)) - Branch { true: Counter(2), false: Counter(3) } at (prev + 0, 23) to (start + 0, 24) true = c2 false = c3 - Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) - = (c1 + ((c2 + c3) + c4)) + = (((c1 + c2) + c3) + c4) Highest counter ID seen: c4 Function name: conditions::assign_and -Raw bytes (51): 0x[01, 01, 04, 07, 0e, 09, 0d, 01, 05, 01, 05, 07, 01, 0d, 01, 00, 21, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 0e, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 0d, 00, 12, 00, 13, 03, 01, 05, 01, 02] +Raw bytes (51): 0x[01, 01, 04, 07, 05, 0b, 0d, 01, 09, 01, 05, 07, 01, 0d, 01, 00, 21, 02, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 0e, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 0d, 00, 12, 00, 13, 02, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 -- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(3, Sub) -- expression 1 operands: lhs = Counter(2), rhs = Counter(3) -- expression 2 operands: lhs = Counter(0), rhs = Counter(1) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(1) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3) +- expression 2 operands: lhs = Counter(0), rhs = Counter(2) - expression 3 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 7 - Code(Counter(0)) at (prev + 13, 1) to (start + 0, 33) -- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) - = ((c2 + c3) + (c0 - c1)) +- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10) + = (((c0 + c2) + c3) - c1) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(3, Sub) } at (prev + 0, 13) to (start + 0, 14) true = c1 @@ -88,8 +86,8 @@ Number of file 0 mappings: 7 - Branch { true: Counter(2), false: Counter(3) } at (prev + 0, 18) to (start + 0, 19) true = c2 false = c3 -- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) - = ((c2 + c3) + (c0 - c1)) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 1, 2) + = (((c0 + c2) + c3) - c1) Highest counter ID seen: c3 Function name: conditions::assign_or @@ -128,13 +126,14 @@ Number of file 0 mappings: 1 Highest counter ID seen: c0 Function name: conditions::func_call -Raw bytes (39): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 05, 01, 25, 01, 01, 0a, 20, 05, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 0d, 00, 0e, 00, 0f, 07, 01, 01, 00, 02] +Raw bytes (41): 0x[01, 01, 04, 01, 05, 0b, 05, 0f, 0d, 01, 09, 05, 01, 25, 01, 01, 0a, 20, 05, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 0d, 00, 0e, 00, 0f, 06, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 3 +Number of expressions: 4 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(0, Sub) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(1) +- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(3) +- expression 3 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 37, 1) to (start + 1, 10) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 9) to (start + 0, 10) @@ -144,8 +143,8 @@ Number of file 0 mappings: 5 - Branch { true: Counter(2), false: Counter(3) } at (prev + 0, 14) to (start + 0, 15) true = c2 false = c3 -- Code(Expression(1, Add)) at (prev + 1, 1) to (start + 0, 2) - = ((c2 + c3) + (c0 - c1)) +- Code(Expression(1, Sub)) at (prev + 1, 1) to (start + 0, 2) + = (((c0 + c2) + c3) - c1) Highest counter ID seen: c3 Function name: conditions::simple_assign diff --git a/tests/coverage/conditions.cov-map b/tests/coverage/conditions.cov-map index 938e4404013..21b2ec9a19e 100644 --- a/tests/coverage/conditions.cov-map +++ b/tests/coverage/conditions.cov-map @@ -1,264 +1,294 @@ Function name: conditions::main -Raw bytes (799): 0x[01, 01, 94, 01, 09, 2b, 2f, 41, 33, 3d, 35, 39, 01, 09, 0d, 35, 1e, 39, 0d, 35, 33, 3d, 35, 39, 2f, 41, 33, 3d, 35, 39, ce, 04, 0d, 01, 09, 03, 49, 62, 31, 03, 49, 5e, 4d, 62, 31, 03, 49, 5a, 51, 5e, 4d, 62, 31, 03, 49, 87, 01, 55, 4d, 51, 83, 01, 59, 87, 01, 55, 4d, 51, 49, 7f, 83, 01, 59, 87, 01, 55, 4d, 51, 5d, 65, ae, 01, 2d, 5d, 65, aa, 01, 69, ae, 01, 2d, 5d, 65, a6, 01, 6d, aa, 01, 69, ae, 01, 2d, 5d, 65, f3, 02, 71, 69, 6d, ef, 02, 75, f3, 02, 71, 69, 6d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, de, 02, 29, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, da, 02, 81, 01, de, 02, 29, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, d6, 02, 85, 01, da, 02, 81, 01, de, 02, 29, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, 8f, 04, 89, 01, 81, 01, 85, 01, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, 11, af, 04, b3, 04, 21, b7, 04, 1d, 15, 19, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, fe, 03, 25, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, fa, 03, 15, fe, 03, 25, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, f6, 03, 19, fa, 03, 15, fe, 03, 25, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, b7, 04, 1d, 15, 19, b3, 04, 21, b7, 04, 1d, 15, 19, ab, 04, bb, 04, 11, af, 04, b3, 04, 21, b7, 04, 1d, 15, 19, bf, 04, ca, 04, c3, 04, 31, c7, 04, 2d, 25, 29, ce, 04, 0d, 01, 09, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, ce, 04, 02, 0f, 00, 1c, 0d, 01, 0c, 00, 19, 1e, 00, 1d, 00, 2a, 1a, 00, 2e, 00, 3c, 2f, 00, 3d, 02, 0a, 41, 02, 09, 00, 0a, 2b, 01, 09, 01, 12, ca, 04, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 45, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 49, 00, 16, 02, 06, 62, 02, 0f, 00, 1c, 5e, 01, 0c, 00, 19, 5a, 00, 1d, 00, 2a, 56, 00, 2e, 00, 3c, 83, 01, 00, 3d, 02, 0a, 59, 02, 09, 00, 0a, 7f, 01, 09, 00, 17, 31, 02, 09, 00, 0f, 7b, 03, 08, 00, 0c, 5d, 01, 0d, 01, 10, 61, 01, 11, 02, 0a, 00, 02, 09, 00, 0a, 5d, 02, 0c, 00, 19, 65, 00, 1a, 02, 0a, ae, 01, 04, 11, 00, 1e, aa, 01, 01, 10, 00, 1d, a6, 01, 00, 21, 00, 2e, a2, 01, 00, 32, 00, 40, ef, 02, 00, 41, 02, 0e, 75, 02, 0d, 00, 0e, eb, 02, 01, 0d, 00, 1b, 2d, 02, 0d, 00, 13, 00, 02, 05, 00, 06, e3, 02, 02, 09, 01, 0c, 79, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 83, 04, 02, 09, 00, 0a, e3, 02, 00, 10, 00, 1d, 7d, 00, 1e, 02, 06, de, 02, 02, 0f, 00, 1c, da, 02, 01, 0c, 00, 19, d6, 02, 00, 1d, 00, 2a, d2, 02, 00, 2e, 00, 3c, 8b, 04, 00, 3d, 02, 0a, 8d, 01, 02, 09, 00, 0a, 87, 04, 01, 09, 00, 17, 29, 02, 0d, 02, 0f, ab, 04, 05, 09, 00, 0a, 83, 04, 00, 10, 00, 1d, 11, 00, 1e, 02, 06, fe, 03, 02, 0f, 00, 1c, fa, 03, 01, 0c, 00, 19, f6, 03, 00, 1d, 00, 2a, f2, 03, 00, 2e, 00, 3c, b3, 04, 00, 3d, 02, 0a, 21, 02, 09, 00, 0a, af, 04, 01, 09, 00, 17, 25, 02, 09, 00, 0f, a7, 04, 02, 01, 00, 02] +Raw bytes (873): 0x[01, 01, b2, 01, 07, 19, 0b, 15, 0f, 11, 09, 0d, 01, 09, 8d, 01, 0d, 8d, 01, 33, 0d, 11, 33, 15, 0d, 11, 2f, 19, 33, 15, 0d, 11, 01, c7, 05, 09, 8d, 01, 03, 21, 03, 47, 21, 89, 01, 03, 4f, db, 03, 89, 01, 21, 25, 03, 5b, d7, 03, 89, 01, db, 03, 29, 21, 25, 77, 2d, 25, 29, 73, 31, 77, 2d, 25, 29, d3, 03, 31, d7, 03, 2d, db, 03, 29, 21, 25, 35, 3d, 35, 93, 01, 3d, 85, 01, 35, 9b, 01, af, 01, 85, 01, 3d, 41, 35, a7, 01, ab, 01, 85, 01, af, 01, 45, 3d, 41, c3, 01, 49, 41, 45, bf, 01, 4d, c3, 01, 49, 41, 45, bb, 03, 35, bf, 03, 4d, c3, 03, 49, c7, 03, 45, cb, 03, 41, cf, 03, 3d, d3, 03, 31, d7, 03, 2d, db, 03, 29, 21, 25, f3, 04, 65, f7, 04, 61, fb, 04, 5d, 55, 59, bb, 03, 35, bf, 03, 4d, c3, 03, 49, c7, 03, 45, cb, 03, 41, cf, 03, 3d, d3, 03, 31, d7, 03, 2d, db, 03, 29, 21, 25, bb, 03, eb, 03, bf, 03, 4d, c3, 03, 49, c7, 03, 45, cb, 03, 41, cf, 03, 3d, d3, 03, 31, d7, 03, 2d, db, 03, 29, 21, 25, 35, 55, bb, 03, fb, 02, bf, 03, 4d, c3, 03, 49, c7, 03, 45, cb, 03, 41, cf, 03, 3d, d3, 03, 31, d7, 03, 2d, db, 03, 29, 21, 25, eb, 03, 81, 01, 35, 55, bb, 03, ab, 03, bf, 03, 4d, c3, 03, 49, c7, 03, 45, cb, 03, 41, cf, 03, 3d, d3, 03, 31, d7, 03, 2d, db, 03, 29, 21, 25, e7, 03, 81, 01, eb, 03, 59, 35, 55, bb, 03, df, 03, bf, 03, 4d, c3, 03, 49, c7, 03, 45, cb, 03, 41, cf, 03, 3d, d3, 03, 31, d7, 03, 2d, db, 03, 29, 21, 25, e3, 03, 81, 01, e7, 03, 5d, eb, 03, 59, 35, 55, ff, 03, 61, 59, 5d, fb, 03, 65, ff, 03, 61, 59, 5d, 87, 04, 79, 83, 05, 75, 87, 05, 71, 69, 6d, f3, 04, 65, f7, 04, 61, fb, 04, 5d, 55, 59, ef, 04, 69, f3, 04, 65, f7, 04, 61, fb, 04, 5d, 55, 59, ef, 04, cb, 04, f3, 04, 65, f7, 04, 61, fb, 04, 5d, 55, 59, 69, 7d, ef, 04, e3, 04, f3, 04, 65, f7, 04, 61, fb, 04, 5d, 55, 59, 87, 05, 7d, 69, 6d, ef, 04, ff, 04, f3, 04, 65, f7, 04, 61, fb, 04, 5d, 55, 59, 83, 05, 7d, 87, 05, 71, 69, 6d, 9b, 05, 75, 6d, 71, 97, 05, 79, 9b, 05, 75, 6d, 71, a3, 05, c7, 05, a7, 05, 89, 01, ab, 05, 85, 01, af, 05, 81, 01, b3, 05, 7d, b7, 05, 79, bb, 05, 75, bf, 05, 71, c3, 05, 6d, 01, 69, 09, 8d, 01, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, 12, 02, 0f, 00, 1c, 8d, 01, 01, 0c, 00, 19, 16, 00, 1d, 00, 2a, 1a, 00, 2e, 00, 3c, 2f, 00, 3d, 02, 0a, 19, 02, 09, 00, 0a, 2b, 01, 09, 01, 12, 36, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 1d, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 21, 00, 16, 02, 06, 3e, 02, 0f, 00, 1c, 42, 01, 0c, 00, 19, 4a, 00, 1d, 00, 2a, 56, 00, 2e, 00, 3c, 73, 00, 3d, 02, 0a, 31, 02, 09, 00, 0a, 6f, 01, 09, 00, 17, 89, 01, 02, 09, 00, 0f, cf, 03, 03, 08, 00, 0c, 35, 01, 0d, 01, 10, 39, 01, 11, 02, 0a, 00, 02, 09, 00, 0a, 35, 02, 0c, 00, 19, 3d, 00, 1a, 02, 0a, 8a, 01, 04, 11, 00, 1e, 8e, 01, 01, 10, 00, 1d, 96, 01, 00, 21, 00, 2e, a2, 01, 00, 32, 00, 40, bf, 01, 00, 41, 02, 0e, 4d, 02, 0d, 00, 0e, bb, 01, 01, 0d, 00, 1b, 85, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, fe, 01, 02, 09, 01, 0c, 51, 01, 0d, 02, 06, 00, 02, 05, 00, 06, ef, 04, 02, 09, 00, 0a, fe, 01, 00, 10, 00, 1d, 55, 00, 1e, 02, 06, a6, 02, 02, 0f, 00, 1c, d2, 02, 01, 0c, 00, 19, 82, 03, 00, 1d, 00, 2a, b6, 03, 00, 2e, 00, 3c, fb, 03, 00, 3d, 02, 0a, 65, 02, 09, 00, 0a, f7, 03, 01, 09, 00, 17, 81, 01, 02, 0d, 02, 0f, 83, 04, 05, 09, 00, 0a, ef, 04, 00, 10, 00, 1d, 69, 00, 1e, 02, 06, a2, 04, 02, 0f, 00, 1c, b6, 04, 01, 0c, 00, 19, ce, 04, 00, 1d, 00, 2a, ea, 04, 00, 2e, 00, 3c, 97, 05, 00, 3d, 02, 0a, 79, 02, 09, 00, 0a, 93, 05, 01, 09, 00, 17, 7d, 02, 09, 00, 0f, 9e, 05, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 148 -- expression 0 operands: lhs = Counter(2), rhs = Expression(10, Add) -- expression 1 operands: lhs = Expression(11, Add), rhs = Counter(16) -- expression 2 operands: lhs = Expression(12, Add), rhs = Counter(15) -- expression 3 operands: lhs = Counter(13), rhs = Counter(14) +Number of expressions: 178 +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(6) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(5) +- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(4) +- expression 3 operands: lhs = Counter(2), rhs = Counter(3) - expression 4 operands: lhs = Counter(0), rhs = Counter(2) -- expression 5 operands: lhs = Counter(3), rhs = Counter(13) -- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(14) -- expression 7 operands: lhs = Counter(3), rhs = Counter(13) -- expression 8 operands: lhs = Expression(12, Add), rhs = Counter(15) -- expression 9 operands: lhs = Counter(13), rhs = Counter(14) -- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(16) -- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(15) -- expression 12 operands: lhs = Counter(13), rhs = Counter(14) -- expression 13 operands: lhs = Expression(147, Sub), rhs = Counter(3) -- expression 14 operands: lhs = Counter(0), rhs = Counter(2) -- expression 15 operands: lhs = Expression(0, Add), rhs = Counter(18) -- expression 16 operands: lhs = Expression(24, Sub), rhs = Counter(12) -- expression 17 operands: lhs = Expression(0, Add), rhs = Counter(18) -- expression 18 operands: lhs = Expression(23, Sub), rhs = Counter(19) -- expression 19 operands: lhs = Expression(24, Sub), rhs = Counter(12) -- expression 20 operands: lhs = Expression(0, Add), rhs = Counter(18) -- expression 21 operands: lhs = Expression(22, Sub), rhs = Counter(20) -- expression 22 operands: lhs = Expression(23, Sub), rhs = Counter(19) -- expression 23 operands: lhs = Expression(24, Sub), rhs = Counter(12) -- expression 24 operands: lhs = Expression(0, Add), rhs = Counter(18) -- expression 25 operands: lhs = Expression(33, Add), rhs = Counter(21) -- expression 26 operands: lhs = Counter(19), rhs = Counter(20) -- expression 27 operands: lhs = Expression(32, Add), rhs = Counter(22) -- expression 28 operands: lhs = Expression(33, Add), rhs = Counter(21) -- expression 29 operands: lhs = Counter(19), rhs = Counter(20) -- expression 30 operands: lhs = Counter(18), rhs = Expression(31, Add) -- expression 31 operands: lhs = Expression(32, Add), rhs = Counter(22) -- expression 32 operands: lhs = Expression(33, Add), rhs = Counter(21) -- expression 33 operands: lhs = Counter(19), rhs = Counter(20) -- expression 34 operands: lhs = Counter(23), rhs = Counter(25) -- expression 35 operands: lhs = Expression(43, Sub), rhs = Counter(11) -- expression 36 operands: lhs = Counter(23), rhs = Counter(25) -- expression 37 operands: lhs = Expression(42, Sub), rhs = Counter(26) -- expression 38 operands: lhs = Expression(43, Sub), rhs = Counter(11) -- expression 39 operands: lhs = Counter(23), rhs = Counter(25) -- expression 40 operands: lhs = Expression(41, Sub), rhs = Counter(27) -- expression 41 operands: lhs = Expression(42, Sub), rhs = Counter(26) -- expression 42 operands: lhs = Expression(43, Sub), rhs = Counter(11) -- expression 43 operands: lhs = Counter(23), rhs = Counter(25) -- expression 44 operands: lhs = Expression(92, Add), rhs = Counter(28) -- expression 45 operands: lhs = Counter(26), rhs = Counter(27) -- expression 46 operands: lhs = Expression(91, Add), rhs = Counter(29) -- expression 47 operands: lhs = Expression(92, Add), rhs = Counter(28) -- expression 48 operands: lhs = Counter(26), rhs = Counter(27) -- expression 49 operands: lhs = Expression(89, Add), rhs = Zero -- expression 50 operands: lhs = Counter(25), rhs = Expression(90, Add) -- expression 51 operands: lhs = Expression(91, Add), rhs = Counter(29) -- expression 52 operands: lhs = Expression(92, Add), rhs = Counter(28) -- expression 53 operands: lhs = Counter(26), rhs = Counter(27) -- expression 54 operands: lhs = Counter(31), rhs = Expression(129, Add) -- expression 55 operands: lhs = Expression(130, Add), rhs = Counter(35) -- expression 56 operands: lhs = Expression(131, Add), rhs = Counter(34) -- expression 57 operands: lhs = Counter(32), rhs = Counter(33) -- expression 58 operands: lhs = Expression(89, Add), rhs = Zero -- expression 59 operands: lhs = Counter(25), rhs = Expression(90, Add) -- expression 60 operands: lhs = Expression(91, Add), rhs = Counter(29) -- expression 61 operands: lhs = Expression(92, Add), rhs = Counter(28) -- expression 62 operands: lhs = Counter(26), rhs = Counter(27) -- expression 63 operands: lhs = Expression(88, Add), rhs = Counter(31) -- expression 64 operands: lhs = Expression(89, Add), rhs = Zero -- expression 65 operands: lhs = Counter(25), rhs = Expression(90, Add) -- expression 66 operands: lhs = Expression(91, Add), rhs = Counter(29) -- expression 67 operands: lhs = Expression(92, Add), rhs = Counter(28) -- expression 68 operands: lhs = Counter(26), rhs = Counter(27) -- expression 69 operands: lhs = Expression(87, Sub), rhs = Counter(10) -- expression 70 operands: lhs = Expression(88, Add), rhs = Counter(31) -- expression 71 operands: lhs = Expression(89, Add), rhs = Zero -- expression 72 operands: lhs = Counter(25), rhs = Expression(90, Add) -- expression 73 operands: lhs = Expression(91, Add), rhs = Counter(29) -- expression 74 operands: lhs = Expression(92, Add), rhs = Counter(28) -- expression 75 operands: lhs = Counter(26), rhs = Counter(27) -- expression 76 operands: lhs = Expression(86, Sub), rhs = Counter(32) -- expression 77 operands: lhs = Expression(87, Sub), rhs = Counter(10) -- expression 78 operands: lhs = Expression(88, Add), rhs = Counter(31) -- expression 79 operands: lhs = Expression(89, Add), rhs = Zero -- expression 80 operands: lhs = Counter(25), rhs = Expression(90, Add) -- expression 81 operands: lhs = Expression(91, Add), rhs = Counter(29) -- expression 82 operands: lhs = Expression(92, Add), rhs = Counter(28) -- expression 83 operands: lhs = Counter(26), rhs = Counter(27) -- expression 84 operands: lhs = Expression(85, Sub), rhs = Counter(33) -- expression 85 operands: lhs = Expression(86, Sub), rhs = Counter(32) -- expression 86 operands: lhs = Expression(87, Sub), rhs = Counter(10) -- expression 87 operands: lhs = Expression(88, Add), rhs = Counter(31) -- expression 88 operands: lhs = Expression(89, Add), rhs = Zero -- expression 89 operands: lhs = Counter(25), rhs = Expression(90, Add) -- expression 90 operands: lhs = Expression(91, Add), rhs = Counter(29) -- expression 91 operands: lhs = Expression(92, Add), rhs = Counter(28) -- expression 92 operands: lhs = Counter(26), rhs = Counter(27) -- expression 93 operands: lhs = Expression(131, Add), rhs = Counter(34) -- expression 94 operands: lhs = Counter(32), rhs = Counter(33) -- expression 95 operands: lhs = Expression(130, Add), rhs = Counter(35) -- expression 96 operands: lhs = Expression(131, Add), rhs = Counter(34) -- expression 97 operands: lhs = Counter(32), rhs = Counter(33) -- expression 98 operands: lhs = Counter(4), rhs = Expression(139, Add) -- expression 99 operands: lhs = Expression(140, Add), rhs = Counter(8) -- expression 100 operands: lhs = Expression(141, Add), rhs = Counter(7) -- expression 101 operands: lhs = Counter(5), rhs = Counter(6) -- expression 102 operands: lhs = Counter(31), rhs = Expression(129, Add) -- expression 103 operands: lhs = Expression(130, Add), rhs = Counter(35) -- expression 104 operands: lhs = Expression(131, Add), rhs = Counter(34) -- expression 105 operands: lhs = Counter(32), rhs = Counter(33) -- expression 106 operands: lhs = Expression(128, Add), rhs = Counter(4) -- expression 107 operands: lhs = Counter(31), rhs = Expression(129, Add) -- expression 108 operands: lhs = Expression(130, Add), rhs = Counter(35) -- expression 109 operands: lhs = Expression(131, Add), rhs = Counter(34) -- expression 110 operands: lhs = Counter(32), rhs = Counter(33) -- expression 111 operands: lhs = Expression(127, Sub), rhs = Counter(9) -- expression 112 operands: lhs = Expression(128, Add), rhs = Counter(4) -- expression 113 operands: lhs = Counter(31), rhs = Expression(129, Add) -- expression 114 operands: lhs = Expression(130, Add), rhs = Counter(35) -- expression 115 operands: lhs = Expression(131, Add), rhs = Counter(34) -- expression 116 operands: lhs = Counter(32), rhs = Counter(33) -- expression 117 operands: lhs = Expression(126, Sub), rhs = Counter(5) -- expression 118 operands: lhs = Expression(127, Sub), rhs = Counter(9) -- expression 119 operands: lhs = Expression(128, Add), rhs = Counter(4) -- expression 120 operands: lhs = Counter(31), rhs = Expression(129, Add) -- expression 121 operands: lhs = Expression(130, Add), rhs = Counter(35) -- expression 122 operands: lhs = Expression(131, Add), rhs = Counter(34) -- expression 123 operands: lhs = Counter(32), rhs = Counter(33) -- expression 124 operands: lhs = Expression(125, Sub), rhs = Counter(6) -- expression 125 operands: lhs = Expression(126, Sub), rhs = Counter(5) -- expression 126 operands: lhs = Expression(127, Sub), rhs = Counter(9) -- expression 127 operands: lhs = Expression(128, Add), rhs = Counter(4) -- expression 128 operands: lhs = Counter(31), rhs = Expression(129, Add) -- expression 129 operands: lhs = Expression(130, Add), rhs = Counter(35) -- expression 130 operands: lhs = Expression(131, Add), rhs = Counter(34) -- expression 131 operands: lhs = Counter(32), rhs = Counter(33) -- expression 132 operands: lhs = Expression(141, Add), rhs = Counter(7) -- expression 133 operands: lhs = Counter(5), rhs = Counter(6) -- expression 134 operands: lhs = Expression(140, Add), rhs = Counter(8) -- expression 135 operands: lhs = Expression(141, Add), rhs = Counter(7) -- expression 136 operands: lhs = Counter(5), rhs = Counter(6) -- expression 137 operands: lhs = Expression(138, Add), rhs = Expression(142, Add) -- expression 138 operands: lhs = Counter(4), rhs = Expression(139, Add) -- expression 139 operands: lhs = Expression(140, Add), rhs = Counter(8) -- expression 140 operands: lhs = Expression(141, Add), rhs = Counter(7) -- expression 141 operands: lhs = Counter(5), rhs = Counter(6) -- expression 142 operands: lhs = Expression(143, Add), rhs = Expression(146, Sub) -- expression 143 operands: lhs = Expression(144, Add), rhs = Counter(12) -- expression 144 operands: lhs = Expression(145, Add), rhs = Counter(11) -- expression 145 operands: lhs = Counter(9), rhs = Counter(10) -- expression 146 operands: lhs = Expression(147, Sub), rhs = Counter(3) -- expression 147 operands: lhs = Counter(0), rhs = Counter(2) +- expression 5 operands: lhs = Counter(35), rhs = Counter(3) +- expression 6 operands: lhs = Counter(35), rhs = Expression(12, Add) +- expression 7 operands: lhs = Counter(3), rhs = Counter(4) +- expression 8 operands: lhs = Expression(12, Add), rhs = Counter(5) +- expression 9 operands: lhs = Counter(3), rhs = Counter(4) +- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(6) +- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(5) +- expression 12 operands: lhs = Counter(3), rhs = Counter(4) +- expression 13 operands: lhs = Counter(0), rhs = Expression(177, Add) +- expression 14 operands: lhs = Counter(2), rhs = Counter(35) +- expression 15 operands: lhs = Expression(0, Add), rhs = Counter(8) +- expression 16 operands: lhs = Expression(0, Add), rhs = Expression(17, Add) +- expression 17 operands: lhs = Counter(8), rhs = Counter(34) +- expression 18 operands: lhs = Expression(0, Add), rhs = Expression(19, Add) +- expression 19 operands: lhs = Expression(118, Add), rhs = Counter(34) +- expression 20 operands: lhs = Counter(8), rhs = Counter(9) +- expression 21 operands: lhs = Expression(0, Add), rhs = Expression(22, Add) +- expression 22 operands: lhs = Expression(117, Add), rhs = Counter(34) +- expression 23 operands: lhs = Expression(118, Add), rhs = Counter(10) +- expression 24 operands: lhs = Counter(8), rhs = Counter(9) +- expression 25 operands: lhs = Expression(29, Add), rhs = Counter(11) +- expression 26 operands: lhs = Counter(9), rhs = Counter(10) +- expression 27 operands: lhs = Expression(28, Add), rhs = Counter(12) +- expression 28 operands: lhs = Expression(29, Add), rhs = Counter(11) +- expression 29 operands: lhs = Counter(9), rhs = Counter(10) +- expression 30 operands: lhs = Expression(116, Add), rhs = Counter(12) +- expression 31 operands: lhs = Expression(117, Add), rhs = Counter(11) +- expression 32 operands: lhs = Expression(118, Add), rhs = Counter(10) +- expression 33 operands: lhs = Counter(8), rhs = Counter(9) +- expression 34 operands: lhs = Counter(13), rhs = Counter(15) +- expression 35 operands: lhs = Counter(13), rhs = Expression(36, Add) +- expression 36 operands: lhs = Counter(15), rhs = Counter(33) +- expression 37 operands: lhs = Counter(13), rhs = Expression(38, Add) +- expression 38 operands: lhs = Expression(43, Add), rhs = Counter(33) +- expression 39 operands: lhs = Counter(15), rhs = Counter(16) +- expression 40 operands: lhs = Counter(13), rhs = Expression(41, Add) +- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(33) +- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(17) +- expression 43 operands: lhs = Counter(15), rhs = Counter(16) +- expression 44 operands: lhs = Expression(48, Add), rhs = Counter(18) +- expression 45 operands: lhs = Counter(16), rhs = Counter(17) +- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(19) +- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(18) +- expression 48 operands: lhs = Counter(16), rhs = Counter(17) +- expression 49 operands: lhs = Expression(110, Add), rhs = Counter(13) +- expression 50 operands: lhs = Expression(111, Add), rhs = Counter(19) +- expression 51 operands: lhs = Expression(112, Add), rhs = Counter(18) +- expression 52 operands: lhs = Expression(113, Add), rhs = Counter(17) +- expression 53 operands: lhs = Expression(114, Add), rhs = Counter(16) +- expression 54 operands: lhs = Expression(115, Add), rhs = Counter(15) +- expression 55 operands: lhs = Expression(116, Add), rhs = Counter(12) +- expression 56 operands: lhs = Expression(117, Add), rhs = Counter(11) +- expression 57 operands: lhs = Expression(118, Add), rhs = Counter(10) +- expression 58 operands: lhs = Counter(8), rhs = Counter(9) +- expression 59 operands: lhs = Expression(156, Add), rhs = Counter(25) +- expression 60 operands: lhs = Expression(157, Add), rhs = Counter(24) +- expression 61 operands: lhs = Expression(158, Add), rhs = Counter(23) +- expression 62 operands: lhs = Counter(21), rhs = Counter(22) +- expression 63 operands: lhs = Expression(110, Add), rhs = Counter(13) +- expression 64 operands: lhs = Expression(111, Add), rhs = Counter(19) +- expression 65 operands: lhs = Expression(112, Add), rhs = Counter(18) +- expression 66 operands: lhs = Expression(113, Add), rhs = Counter(17) +- expression 67 operands: lhs = Expression(114, Add), rhs = Counter(16) +- expression 68 operands: lhs = Expression(115, Add), rhs = Counter(15) +- expression 69 operands: lhs = Expression(116, Add), rhs = Counter(12) +- expression 70 operands: lhs = Expression(117, Add), rhs = Counter(11) +- expression 71 operands: lhs = Expression(118, Add), rhs = Counter(10) +- expression 72 operands: lhs = Counter(8), rhs = Counter(9) +- expression 73 operands: lhs = Expression(110, Add), rhs = Expression(122, Add) +- expression 74 operands: lhs = Expression(111, Add), rhs = Counter(19) +- expression 75 operands: lhs = Expression(112, Add), rhs = Counter(18) +- expression 76 operands: lhs = Expression(113, Add), rhs = Counter(17) +- expression 77 operands: lhs = Expression(114, Add), rhs = Counter(16) +- expression 78 operands: lhs = Expression(115, Add), rhs = Counter(15) +- expression 79 operands: lhs = Expression(116, Add), rhs = Counter(12) +- expression 80 operands: lhs = Expression(117, Add), rhs = Counter(11) +- expression 81 operands: lhs = Expression(118, Add), rhs = Counter(10) +- expression 82 operands: lhs = Counter(8), rhs = Counter(9) +- expression 83 operands: lhs = Counter(13), rhs = Counter(21) +- expression 84 operands: lhs = Expression(110, Add), rhs = Expression(94, Add) +- expression 85 operands: lhs = Expression(111, Add), rhs = Counter(19) +- expression 86 operands: lhs = Expression(112, Add), rhs = Counter(18) +- expression 87 operands: lhs = Expression(113, Add), rhs = Counter(17) +- expression 88 operands: lhs = Expression(114, Add), rhs = Counter(16) +- expression 89 operands: lhs = Expression(115, Add), rhs = Counter(15) +- expression 90 operands: lhs = Expression(116, Add), rhs = Counter(12) +- expression 91 operands: lhs = Expression(117, Add), rhs = Counter(11) +- expression 92 operands: lhs = Expression(118, Add), rhs = Counter(10) +- expression 93 operands: lhs = Counter(8), rhs = Counter(9) +- expression 94 operands: lhs = Expression(122, Add), rhs = Counter(32) +- expression 95 operands: lhs = Counter(13), rhs = Counter(21) +- expression 96 operands: lhs = Expression(110, Add), rhs = Expression(106, Add) +- expression 97 operands: lhs = Expression(111, Add), rhs = Counter(19) +- expression 98 operands: lhs = Expression(112, Add), rhs = Counter(18) +- expression 99 operands: lhs = Expression(113, Add), rhs = Counter(17) +- expression 100 operands: lhs = Expression(114, Add), rhs = Counter(16) +- expression 101 operands: lhs = Expression(115, Add), rhs = Counter(15) +- expression 102 operands: lhs = Expression(116, Add), rhs = Counter(12) +- expression 103 operands: lhs = Expression(117, Add), rhs = Counter(11) +- expression 104 operands: lhs = Expression(118, Add), rhs = Counter(10) +- expression 105 operands: lhs = Counter(8), rhs = Counter(9) +- expression 106 operands: lhs = Expression(121, Add), rhs = Counter(32) +- expression 107 operands: lhs = Expression(122, Add), rhs = Counter(22) +- expression 108 operands: lhs = Counter(13), rhs = Counter(21) +- expression 109 operands: lhs = Expression(110, Add), rhs = Expression(119, Add) +- expression 110 operands: lhs = Expression(111, Add), rhs = Counter(19) +- expression 111 operands: lhs = Expression(112, Add), rhs = Counter(18) +- expression 112 operands: lhs = Expression(113, Add), rhs = Counter(17) +- expression 113 operands: lhs = Expression(114, Add), rhs = Counter(16) +- expression 114 operands: lhs = Expression(115, Add), rhs = Counter(15) +- expression 115 operands: lhs = Expression(116, Add), rhs = Counter(12) +- expression 116 operands: lhs = Expression(117, Add), rhs = Counter(11) +- expression 117 operands: lhs = Expression(118, Add), rhs = Counter(10) +- expression 118 operands: lhs = Counter(8), rhs = Counter(9) +- expression 119 operands: lhs = Expression(120, Add), rhs = Counter(32) +- expression 120 operands: lhs = Expression(121, Add), rhs = Counter(23) +- expression 121 operands: lhs = Expression(122, Add), rhs = Counter(22) +- expression 122 operands: lhs = Counter(13), rhs = Counter(21) +- expression 123 operands: lhs = Expression(127, Add), rhs = Counter(24) +- expression 124 operands: lhs = Counter(22), rhs = Counter(23) +- expression 125 operands: lhs = Expression(126, Add), rhs = Counter(25) +- expression 126 operands: lhs = Expression(127, Add), rhs = Counter(24) +- expression 127 operands: lhs = Counter(22), rhs = Counter(23) +- expression 128 operands: lhs = Expression(129, Add), rhs = Counter(30) +- expression 129 operands: lhs = Expression(160, Add), rhs = Counter(29) +- expression 130 operands: lhs = Expression(161, Add), rhs = Counter(28) +- expression 131 operands: lhs = Counter(26), rhs = Counter(27) +- expression 132 operands: lhs = Expression(156, Add), rhs = Counter(25) +- expression 133 operands: lhs = Expression(157, Add), rhs = Counter(24) +- expression 134 operands: lhs = Expression(158, Add), rhs = Counter(23) +- expression 135 operands: lhs = Counter(21), rhs = Counter(22) +- expression 136 operands: lhs = Expression(155, Add), rhs = Counter(26) +- expression 137 operands: lhs = Expression(156, Add), rhs = Counter(25) +- expression 138 operands: lhs = Expression(157, Add), rhs = Counter(24) +- expression 139 operands: lhs = Expression(158, Add), rhs = Counter(23) +- expression 140 operands: lhs = Counter(21), rhs = Counter(22) +- expression 141 operands: lhs = Expression(155, Add), rhs = Expression(146, Add) +- expression 142 operands: lhs = Expression(156, Add), rhs = Counter(25) +- expression 143 operands: lhs = Expression(157, Add), rhs = Counter(24) +- expression 144 operands: lhs = Expression(158, Add), rhs = Counter(23) +- expression 145 operands: lhs = Counter(21), rhs = Counter(22) +- expression 146 operands: lhs = Counter(26), rhs = Counter(31) +- expression 147 operands: lhs = Expression(155, Add), rhs = Expression(152, Add) +- expression 148 operands: lhs = Expression(156, Add), rhs = Counter(25) +- expression 149 operands: lhs = Expression(157, Add), rhs = Counter(24) +- expression 150 operands: lhs = Expression(158, Add), rhs = Counter(23) +- expression 151 operands: lhs = Counter(21), rhs = Counter(22) +- expression 152 operands: lhs = Expression(161, Add), rhs = Counter(31) +- expression 153 operands: lhs = Counter(26), rhs = Counter(27) +- expression 154 operands: lhs = Expression(155, Add), rhs = Expression(159, Add) +- expression 155 operands: lhs = Expression(156, Add), rhs = Counter(25) +- expression 156 operands: lhs = Expression(157, Add), rhs = Counter(24) +- expression 157 operands: lhs = Expression(158, Add), rhs = Counter(23) +- expression 158 operands: lhs = Counter(21), rhs = Counter(22) +- expression 159 operands: lhs = Expression(160, Add), rhs = Counter(31) +- expression 160 operands: lhs = Expression(161, Add), rhs = Counter(28) +- expression 161 operands: lhs = Counter(26), rhs = Counter(27) +- expression 162 operands: lhs = Expression(166, Add), rhs = Counter(29) +- expression 163 operands: lhs = Counter(27), rhs = Counter(28) +- expression 164 operands: lhs = Expression(165, Add), rhs = Counter(30) +- expression 165 operands: lhs = Expression(166, Add), rhs = Counter(29) +- expression 166 operands: lhs = Counter(27), rhs = Counter(28) +- expression 167 operands: lhs = Expression(168, Add), rhs = Expression(177, Add) +- expression 168 operands: lhs = Expression(169, Add), rhs = Counter(34) +- expression 169 operands: lhs = Expression(170, Add), rhs = Counter(33) +- expression 170 operands: lhs = Expression(171, Add), rhs = Counter(32) +- expression 171 operands: lhs = Expression(172, Add), rhs = Counter(31) +- expression 172 operands: lhs = Expression(173, Add), rhs = Counter(30) +- expression 173 operands: lhs = Expression(174, Add), rhs = Counter(29) +- expression 174 operands: lhs = Expression(175, Add), rhs = Counter(28) +- expression 175 operands: lhs = Expression(176, Add), rhs = Counter(27) +- expression 176 operands: lhs = Counter(0), rhs = Counter(26) +- expression 177 operands: lhs = Counter(2), rhs = Counter(35) Number of file 0 mappings: 68 - Code(Counter(0)) at (prev + 3, 1) to (start + 2, 12) - Code(Counter(1)) at (prev + 2, 13) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 10) - = (c2 + (((c13 + c14) + c15) + c16)) + = ((((c2 + c3) + c4) + c5) + c6) - Code(Counter(0)) at (prev + 0, 16) to (start + 0, 29) - Code(Counter(2)) at (prev + 1, 9) to (start + 1, 10) -- Code(Expression(147, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Expression(4, Sub)) at (prev + 2, 15) to (start + 0, 28) = (c0 - c2) -- Code(Counter(3)) at (prev + 1, 12) to (start + 0, 25) -- Code(Expression(7, Sub)) at (prev + 0, 29) to (start + 0, 42) - = (c3 - c13) +- Code(Counter(35)) at (prev + 1, 12) to (start + 0, 25) +- Code(Expression(5, Sub)) at (prev + 0, 29) to (start + 0, 42) + = (c35 - c3) - Code(Expression(6, Sub)) at (prev + 0, 46) to (start + 0, 60) - = ((c3 - c13) - c14) + = (c35 - (c3 + c4)) - Code(Expression(11, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c13 + c14) + c15) -- Code(Counter(16)) at (prev + 2, 9) to (start + 0, 10) + = ((c3 + c4) + c5) +- Code(Counter(6)) at (prev + 2, 9) to (start + 0, 10) - Code(Expression(10, Add)) at (prev + 1, 9) to (start + 1, 18) - = (((c13 + c14) + c15) + c16) -- Code(Expression(146, Sub)) at (prev + 3, 9) to (start + 0, 15) - = ((c0 - c2) - c3) + = (((c3 + c4) + c5) + c6) +- Code(Expression(13, Sub)) at (prev + 3, 9) to (start + 0, 15) + = (c0 - (c2 + c35)) - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 1, 12) - = (c2 + (((c13 + c14) + c15) + c16)) -- Code(Counter(17)) at (prev + 1, 13) to (start + 2, 6) + = ((((c2 + c3) + c4) + c5) + c6) +- Code(Counter(7)) at (prev + 1, 13) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Expression(0, Add)) at (prev + 2, 8) to (start + 0, 21) - = (c2 + (((c13 + c14) + c15) + c16)) -- Code(Counter(18)) at (prev + 0, 22) to (start + 2, 6) -- Code(Expression(24, Sub)) at (prev + 2, 15) to (start + 0, 28) - = ((c2 + (((c13 + c14) + c15) + c16)) - c18) -- Code(Expression(23, Sub)) at (prev + 1, 12) to (start + 0, 25) - = (((c2 + (((c13 + c14) + c15) + c16)) - c18) - c12) -- Code(Expression(22, Sub)) at (prev + 0, 29) to (start + 0, 42) - = ((((c2 + (((c13 + c14) + c15) + c16)) - c18) - c12) - c19) + = ((((c2 + c3) + c4) + c5) + c6) +- Code(Counter(8)) at (prev + 0, 22) to (start + 2, 6) +- Code(Expression(15, Sub)) at (prev + 2, 15) to (start + 0, 28) + = (((((c2 + c3) + c4) + c5) + c6) - c8) +- Code(Expression(16, Sub)) at (prev + 1, 12) to (start + 0, 25) + = (((((c2 + c3) + c4) + c5) + c6) - (c8 + c34)) +- Code(Expression(18, Sub)) at (prev + 0, 29) to (start + 0, 42) + = (((((c2 + c3) + c4) + c5) + c6) - ((c8 + c9) + c34)) - Code(Expression(21, Sub)) at (prev + 0, 46) to (start + 0, 60) - = (((((c2 + (((c13 + c14) + c15) + c16)) - c18) - c12) - c19) - c20) -- Code(Expression(32, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c19 + c20) + c21) -- Code(Counter(22)) at (prev + 2, 9) to (start + 0, 10) -- Code(Expression(31, Add)) at (prev + 1, 9) to (start + 0, 23) - = (((c19 + c20) + c21) + c22) -- Code(Counter(12)) at (prev + 2, 9) to (start + 0, 15) -- Code(Expression(30, Add)) at (prev + 3, 8) to (start + 0, 12) - = (c18 + (((c19 + c20) + c21) + c22)) -- Code(Counter(23)) at (prev + 1, 13) to (start + 1, 16) -- Code(Counter(24)) at (prev + 1, 17) to (start + 2, 10) + = (((((c2 + c3) + c4) + c5) + c6) - (((c8 + c9) + c10) + c34)) +- Code(Expression(28, Add)) at (prev + 0, 61) to (start + 2, 10) + = ((c9 + c10) + c11) +- Code(Counter(12)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(27, Add)) at (prev + 1, 9) to (start + 0, 23) + = (((c9 + c10) + c11) + c12) +- Code(Counter(34)) at (prev + 2, 9) to (start + 0, 15) +- Code(Expression(115, Add)) at (prev + 3, 8) to (start + 0, 12) + = ((((c8 + c9) + c10) + c11) + c12) +- Code(Counter(13)) at (prev + 1, 13) to (start + 1, 16) +- Code(Counter(14)) at (prev + 1, 17) to (start + 2, 10) - Code(Zero) at (prev + 2, 9) to (start + 0, 10) -- Code(Counter(23)) at (prev + 2, 12) to (start + 0, 25) -- Code(Counter(25)) at (prev + 0, 26) to (start + 2, 10) -- Code(Expression(43, Sub)) at (prev + 4, 17) to (start + 0, 30) - = (c23 - c25) -- Code(Expression(42, Sub)) at (prev + 1, 16) to (start + 0, 29) - = ((c23 - c25) - c11) -- Code(Expression(41, Sub)) at (prev + 0, 33) to (start + 0, 46) - = (((c23 - c25) - c11) - c26) +- Code(Counter(13)) at (prev + 2, 12) to (start + 0, 25) +- Code(Counter(15)) at (prev + 0, 26) to (start + 2, 10) +- Code(Expression(34, Sub)) at (prev + 4, 17) to (start + 0, 30) + = (c13 - c15) +- Code(Expression(35, Sub)) at (prev + 1, 16) to (start + 0, 29) + = (c13 - (c15 + c33)) +- Code(Expression(37, Sub)) at (prev + 0, 33) to (start + 0, 46) + = (c13 - ((c15 + c16) + c33)) - Code(Expression(40, Sub)) at (prev + 0, 50) to (start + 0, 64) - = ((((c23 - c25) - c11) - c26) - c27) -- Code(Expression(91, Add)) at (prev + 0, 65) to (start + 2, 14) - = ((c26 + c27) + c28) -- Code(Counter(29)) at (prev + 2, 13) to (start + 0, 14) -- Code(Expression(90, Add)) at (prev + 1, 13) to (start + 0, 27) - = (((c26 + c27) + c28) + c29) -- Code(Counter(11)) at (prev + 2, 13) to (start + 0, 19) + = (c13 - (((c15 + c16) + c17) + c33)) +- Code(Expression(47, Add)) at (prev + 0, 65) to (start + 2, 14) + = ((c16 + c17) + c18) +- Code(Counter(19)) at (prev + 2, 13) to (start + 0, 14) +- Code(Expression(46, Add)) at (prev + 1, 13) to (start + 0, 27) + = (((c16 + c17) + c18) + c19) +- Code(Counter(33)) at (prev + 2, 13) to (start + 0, 19) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) -- Code(Expression(88, Add)) at (prev + 2, 9) to (start + 1, 12) - = ((c25 + (((c26 + c27) + c28) + c29)) + Zero) -- Code(Counter(30)) at (prev + 1, 13) to (start + 2, 6) +- Code(Expression(63, Sub)) at (prev + 2, 9) to (start + 1, 12) + = ((((((((((c8 + c9) + c10) + c11) + c12) + c15) + c16) + c17) + c18) + c19) - c13) +- Code(Counter(20)) at (prev + 1, 13) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) -- Code(Expression(128, Add)) at (prev + 2, 9) to (start + 0, 10) - = (c31 + (((c32 + c33) + c34) + c35)) -- Code(Expression(88, Add)) at (prev + 0, 16) to (start + 0, 29) - = ((c25 + (((c26 + c27) + c28) + c29)) + Zero) -- Code(Counter(31)) at (prev + 0, 30) to (start + 2, 6) -- Code(Expression(87, Sub)) at (prev + 2, 15) to (start + 0, 28) - = (((c25 + (((c26 + c27) + c28) + c29)) + Zero) - c31) -- Code(Expression(86, Sub)) at (prev + 1, 12) to (start + 0, 25) - = ((((c25 + (((c26 + c27) + c28) + c29)) + Zero) - c31) - c10) -- Code(Expression(85, Sub)) at (prev + 0, 29) to (start + 0, 42) - = (((((c25 + (((c26 + c27) + c28) + c29)) + Zero) - c31) - c10) - c32) -- Code(Expression(84, Sub)) at (prev + 0, 46) to (start + 0, 60) - = ((((((c25 + (((c26 + c27) + c28) + c29)) + Zero) - c31) - c10) - c32) - c33) -- Code(Expression(130, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c32 + c33) + c34) -- Code(Counter(35)) at (prev + 2, 9) to (start + 0, 10) -- Code(Expression(129, Add)) at (prev + 1, 9) to (start + 0, 23) - = (((c32 + c33) + c34) + c35) -- Code(Counter(10)) at (prev + 2, 13) to (start + 2, 15) -- Code(Expression(138, Add)) at (prev + 5, 9) to (start + 0, 10) - = (c4 + (((c5 + c6) + c7) + c8)) -- Code(Expression(128, Add)) at (prev + 0, 16) to (start + 0, 29) - = (c31 + (((c32 + c33) + c34) + c35)) -- Code(Counter(4)) at (prev + 0, 30) to (start + 2, 6) -- Code(Expression(127, Sub)) at (prev + 2, 15) to (start + 0, 28) - = ((c31 + (((c32 + c33) + c34) + c35)) - c4) -- Code(Expression(126, Sub)) at (prev + 1, 12) to (start + 0, 25) - = (((c31 + (((c32 + c33) + c34) + c35)) - c4) - c9) -- Code(Expression(125, Sub)) at (prev + 0, 29) to (start + 0, 42) - = ((((c31 + (((c32 + c33) + c34) + c35)) - c4) - c9) - c5) -- Code(Expression(124, Sub)) at (prev + 0, 46) to (start + 0, 60) - = (((((c31 + (((c32 + c33) + c34) + c35)) - c4) - c9) - c5) - c6) -- Code(Expression(140, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c5 + c6) + c7) -- Code(Counter(8)) at (prev + 2, 9) to (start + 0, 10) -- Code(Expression(139, Add)) at (prev + 1, 9) to (start + 0, 23) - = (((c5 + c6) + c7) + c8) -- Code(Counter(9)) at (prev + 2, 9) to (start + 0, 15) -- Code(Expression(137, Add)) at (prev + 2, 1) to (start + 0, 2) - = ((c4 + (((c5 + c6) + c7) + c8)) + ((((c9 + c10) + c11) + c12) + ((c0 - c2) - c3))) +- Code(Expression(155, Add)) at (prev + 2, 9) to (start + 0, 10) + = ((((c21 + c22) + c23) + c24) + c25) +- Code(Expression(63, Sub)) at (prev + 0, 16) to (start + 0, 29) + = ((((((((((c8 + c9) + c10) + c11) + c12) + c15) + c16) + c17) + c18) + c19) - c13) +- Code(Counter(21)) at (prev + 0, 30) to (start + 2, 6) +- Code(Expression(73, Sub)) at (prev + 2, 15) to (start + 0, 28) + = ((((((((((c8 + c9) + c10) + c11) + c12) + c15) + c16) + c17) + c18) + c19) - (c13 + c21)) +- Code(Expression(84, Sub)) at (prev + 1, 12) to (start + 0, 25) + = ((((((((((c8 + c9) + c10) + c11) + c12) + c15) + c16) + c17) + c18) + c19) - ((c13 + c21) + c32)) +- Code(Expression(96, Sub)) at (prev + 0, 29) to (start + 0, 42) + = ((((((((((c8 + c9) + c10) + c11) + c12) + c15) + c16) + c17) + c18) + c19) - (((c13 + c21) + c22) + c32)) +- Code(Expression(109, Sub)) at (prev + 0, 46) to (start + 0, 60) + = ((((((((((c8 + c9) + c10) + c11) + c12) + c15) + c16) + c17) + c18) + c19) - ((((c13 + c21) + c22) + c23) + c32)) +- Code(Expression(126, Add)) at (prev + 0, 61) to (start + 2, 10) + = ((c22 + c23) + c24) +- Code(Counter(25)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(125, Add)) at (prev + 1, 9) to (start + 0, 23) + = (((c22 + c23) + c24) + c25) +- Code(Counter(32)) at (prev + 2, 13) to (start + 2, 15) +- Code(Expression(128, Add)) at (prev + 5, 9) to (start + 0, 10) + = ((((c26 + c27) + c28) + c29) + c30) +- Code(Expression(155, Add)) at (prev + 0, 16) to (start + 0, 29) + = ((((c21 + c22) + c23) + c24) + c25) +- Code(Counter(26)) at (prev + 0, 30) to (start + 2, 6) +- Code(Expression(136, Sub)) at (prev + 2, 15) to (start + 0, 28) + = (((((c21 + c22) + c23) + c24) + c25) - c26) +- Code(Expression(141, Sub)) at (prev + 1, 12) to (start + 0, 25) + = (((((c21 + c22) + c23) + c24) + c25) - (c26 + c31)) +- Code(Expression(147, Sub)) at (prev + 0, 29) to (start + 0, 42) + = (((((c21 + c22) + c23) + c24) + c25) - ((c26 + c27) + c31)) +- Code(Expression(154, Sub)) at (prev + 0, 46) to (start + 0, 60) + = (((((c21 + c22) + c23) + c24) + c25) - (((c26 + c27) + c28) + c31)) +- Code(Expression(165, Add)) at (prev + 0, 61) to (start + 2, 10) + = ((c27 + c28) + c29) +- Code(Counter(30)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(164, Add)) at (prev + 1, 9) to (start + 0, 23) + = (((c27 + c28) + c29) + c30) +- Code(Counter(31)) at (prev + 2, 9) to (start + 0, 15) +- Code(Expression(167, Sub)) at (prev + 2, 1) to (start + 0, 2) + = ((((((((((c0 + c26) + c27) + c28) + c29) + c30) + c31) + c32) + c33) + c34) - (c2 + c35)) Highest counter ID seen: c35 diff --git a/tests/coverage/continue.cov-map b/tests/coverage/continue.cov-map index 7781d2d2544..55313d7db49 100644 --- a/tests/coverage/continue.cov-map +++ b/tests/coverage/continue.cov-map @@ -1,5 +1,5 @@ Function name: continue::main -Raw bytes (210): 0x[01, 01, 1c, 07, 09, 01, 05, 03, 0d, 1f, 15, 0d, 11, 1b, 19, 1f, 15, 0d, 11, 33, 21, 19, 1d, 2f, 25, 33, 21, 19, 1d, 47, 2d, 25, 29, 43, 31, 47, 2d, 25, 29, 31, 5f, 35, 39, 57, 3d, 31, 5f, 35, 39, 35, 39, 3d, 41, 6b, 45, 3d, 41, 49, 45, 1e, 01, 03, 01, 03, 12, 03, 04, 0e, 00, 13, 0a, 01, 0f, 00, 16, 05, 02, 11, 00, 19, 09, 02, 12, 04, 0e, 1b, 06, 0e, 00, 13, 16, 01, 0f, 00, 16, 15, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 15, 03, 09, 00, 0e, 2f, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 1d, 01, 15, 02, 0e, 21, 04, 11, 00, 19, 1d, 03, 09, 00, 0e, 43, 02, 0e, 00, 13, 3e, 01, 0c, 00, 13, 29, 01, 0d, 00, 15, 2d, 01, 0a, 01, 0e, 57, 03, 0e, 00, 13, 52, 01, 0f, 00, 16, 39, 01, 16, 02, 0e, 35, 03, 12, 02, 0e, 5f, 04, 09, 00, 0e, 6b, 02, 0e, 00, 13, 66, 01, 0f, 00, 16, 41, 01, 16, 02, 0e, 49, 04, 11, 00, 16, 41, 03, 09, 00, 0e, 6f, 02, 0d, 01, 02] +Raw bytes (210): 0x[01, 01, 1c, 07, 09, 01, 05, 03, 0d, 1f, 15, 0d, 11, 1b, 19, 1f, 15, 0d, 11, 33, 21, 19, 1d, 2f, 25, 33, 21, 19, 1d, 47, 2d, 25, 29, 43, 31, 47, 2d, 25, 29, 5b, 39, 31, 35, 57, 3d, 5b, 39, 31, 35, 35, 39, 3d, 41, 6b, 45, 3d, 41, 45, 49, 1e, 01, 03, 01, 03, 12, 03, 04, 0e, 00, 13, 0a, 01, 0f, 00, 16, 05, 02, 11, 00, 19, 09, 02, 12, 04, 0e, 1b, 06, 0e, 00, 13, 16, 01, 0f, 00, 16, 15, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 15, 03, 09, 00, 0e, 2f, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 1d, 01, 15, 02, 0e, 21, 04, 11, 00, 19, 1d, 03, 09, 00, 0e, 43, 02, 0e, 00, 13, 3e, 01, 0c, 00, 13, 29, 01, 0d, 00, 15, 2d, 01, 0a, 01, 0e, 57, 03, 0e, 00, 13, 52, 01, 0f, 00, 16, 39, 01, 16, 02, 0e, 35, 03, 12, 02, 0e, 5f, 04, 09, 00, 0e, 6b, 02, 0e, 00, 13, 66, 01, 0f, 00, 16, 41, 01, 16, 02, 0e, 49, 04, 11, 00, 16, 41, 03, 09, 00, 0e, 6f, 02, 0d, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 28 @@ -21,16 +21,16 @@ Number of expressions: 28 - expression 15 operands: lhs = Expression(16, Add), rhs = Counter(12) - expression 16 operands: lhs = Expression(17, Add), rhs = Counter(11) - expression 17 operands: lhs = Counter(9), rhs = Counter(10) -- expression 18 operands: lhs = Counter(12), rhs = Expression(23, Add) -- expression 19 operands: lhs = Counter(13), rhs = Counter(14) +- expression 18 operands: lhs = Expression(22, Add), rhs = Counter(14) +- expression 19 operands: lhs = Counter(12), rhs = Counter(13) - expression 20 operands: lhs = Expression(21, Add), rhs = Counter(15) -- expression 21 operands: lhs = Counter(12), rhs = Expression(23, Add) -- expression 22 operands: lhs = Counter(13), rhs = Counter(14) +- expression 21 operands: lhs = Expression(22, Add), rhs = Counter(14) +- expression 22 operands: lhs = Counter(12), rhs = Counter(13) - expression 23 operands: lhs = Counter(13), rhs = Counter(14) - expression 24 operands: lhs = Counter(15), rhs = Counter(16) - expression 25 operands: lhs = Expression(26, Add), rhs = Counter(17) - expression 26 operands: lhs = Counter(15), rhs = Counter(16) -- expression 27 operands: lhs = Counter(18), rhs = Counter(17) +- expression 27 operands: lhs = Counter(17), rhs = Counter(18) Number of file 0 mappings: 30 - Code(Counter(0)) at (prev + 3, 1) to (start + 3, 18) - Code(Expression(0, Add)) at (prev + 4, 14) to (start + 0, 19) @@ -60,9 +60,9 @@ Number of file 0 mappings: 30 - Code(Counter(10)) at (prev + 1, 13) to (start + 0, 21) - Code(Counter(11)) at (prev + 1, 10) to (start + 1, 14) - Code(Expression(21, Add)) at (prev + 3, 14) to (start + 0, 19) - = (c12 + (c13 + c14)) + = ((c12 + c13) + c14) - Code(Expression(20, Sub)) at (prev + 1, 15) to (start + 0, 22) - = ((c12 + (c13 + c14)) - c15) + = (((c12 + c13) + c14) - c15) - Code(Counter(14)) at (prev + 1, 22) to (start + 2, 14) - Code(Counter(13)) at (prev + 3, 18) to (start + 2, 14) - Code(Expression(23, Add)) at (prev + 4, 9) to (start + 0, 14) @@ -75,6 +75,6 @@ Number of file 0 mappings: 30 - Code(Counter(18)) at (prev + 4, 17) to (start + 0, 22) - Code(Counter(16)) at (prev + 3, 9) to (start + 0, 14) - Code(Expression(27, Add)) at (prev + 2, 13) to (start + 1, 2) - = (c18 + c17) + = (c17 + c18) Highest counter ID seen: c18 diff --git a/tests/coverage/coroutine.cov-map b/tests/coverage/coroutine.cov-map index 2fdc3220c19..21f6787e9f2 100644 --- a/tests/coverage/coroutine.cov-map +++ b/tests/coverage/coroutine.cov-map @@ -13,18 +13,18 @@ Number of file 0 mappings: 4 Highest counter ID seen: c1 Function name: coroutine::main -Raw bytes (65): 0x[01, 01, 08, 07, 0d, 05, 09, 11, 15, 1e, 19, 11, 15, 15, 19, 1e, 19, 11, 15, 09, 01, 13, 01, 02, 16, 01, 08, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 03, 01, 0e, 00, 35, 11, 02, 0b, 00, 2e, 1e, 01, 22, 00, 27, 1a, 00, 2c, 00, 2e, 17, 01, 0e, 00, 35, 1a, 02, 01, 00, 02] +Raw bytes (65): 0x[01, 01, 08, 07, 0d, 05, 09, 11, 15, 11, 1f, 15, 19, 15, 19, 11, 1f, 15, 19, 09, 01, 13, 01, 02, 16, 01, 08, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 03, 01, 0e, 00, 35, 11, 02, 0b, 00, 2e, 0a, 01, 22, 00, 27, 1a, 00, 2c, 00, 2e, 1f, 01, 0e, 00, 35, 1a, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 8 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Counter(4), rhs = Counter(5) -- expression 3 operands: lhs = Expression(7, Sub), rhs = Counter(6) -- expression 4 operands: lhs = Counter(4), rhs = Counter(5) +- expression 3 operands: lhs = Counter(4), rhs = Expression(7, Add) +- expression 4 operands: lhs = Counter(5), rhs = Counter(6) - expression 5 operands: lhs = Counter(5), rhs = Counter(6) -- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(6) -- expression 7 operands: lhs = Counter(4), rhs = Counter(5) +- expression 6 operands: lhs = Counter(4), rhs = Expression(7, Add) +- expression 7 operands: lhs = Counter(5), rhs = Counter(6) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 19, 1) to (start + 2, 22) - Code(Counter(0)) at (prev + 8, 11) to (start + 0, 46) @@ -32,14 +32,14 @@ Number of file 0 mappings: 9 - Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 53) = ((c1 + c2) + c3) - Code(Counter(4)) at (prev + 2, 11) to (start + 0, 46) -- Code(Expression(7, Sub)) at (prev + 1, 34) to (start + 0, 39) +- Code(Expression(2, Sub)) at (prev + 1, 34) to (start + 0, 39) = (c4 - c5) - Code(Expression(6, Sub)) at (prev + 0, 44) to (start + 0, 46) - = ((c4 - c5) - c6) -- Code(Expression(5, Add)) at (prev + 1, 14) to (start + 0, 53) + = (c4 - (c5 + c6)) +- Code(Expression(7, Add)) at (prev + 1, 14) to (start + 0, 53) = (c5 + c6) - Code(Expression(6, Sub)) at (prev + 2, 1) to (start + 0, 2) - = ((c4 - c5) - c6) + = (c4 - (c5 + c6)) Highest counter ID seen: c4 Function name: coroutine::main::{closure#0} diff --git a/tests/coverage/inline-dead.cov-map b/tests/coverage/inline-dead.cov-map index 5a20de3d4d4..3e2ca2bc992 100644 --- a/tests/coverage/inline-dead.cov-map +++ b/tests/coverage/inline-dead.cov-map @@ -32,16 +32,16 @@ Number of file 0 mappings: 2 Highest counter ID seen: c0 Function name: inline_dead::main::{closure#0} -Raw bytes (23): 0x[01, 01, 02, 00, 06, 01, 00, 03, 01, 07, 17, 01, 16, 00, 01, 17, 00, 18, 03, 01, 05, 00, 06] +Raw bytes (23): 0x[01, 01, 02, 07, 00, 01, 00, 03, 01, 07, 17, 01, 16, 00, 01, 17, 00, 18, 02, 01, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 -- expression 0 operands: lhs = Zero, rhs = Expression(1, Sub) +- expression 0 operands: lhs = Expression(1, Add), rhs = Zero - expression 1 operands: lhs = Counter(0), rhs = Zero Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 7, 23) to (start + 1, 22) - Code(Zero) at (prev + 1, 23) to (start + 0, 24) -- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 0, 6) - = (Zero + (c0 - Zero)) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6) + = ((c0 + Zero) - Zero) Highest counter ID seen: c0 diff --git a/tests/coverage/inline.cov-map b/tests/coverage/inline.cov-map index ab3a505e925..1b5b45695dc 100644 --- a/tests/coverage/inline.cov-map +++ b/tests/coverage/inline.cov-map @@ -41,14 +41,15 @@ Number of file 0 mappings: 1 Highest counter ID seen: c0 Function name: inline::permutate::<char> -Raw bytes (52): 0x[01, 01, 04, 01, 05, 02, 0d, 05, 0f, 09, 0d, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 11, 01, 0d, 00, 0e, 06, 00, 12, 00, 16, 11, 00, 17, 04, 0a, 0d, 05, 0c, 02, 06, 0b, 03, 01, 00, 02] +Raw bytes (54): 0x[01, 01, 05, 01, 05, 01, 0b, 05, 0d, 13, 0d, 05, 09, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 11, 01, 0d, 00, 0e, 06, 00, 12, 00, 16, 11, 00, 17, 04, 0a, 0d, 05, 0c, 02, 06, 0f, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 4 +Number of expressions: 5 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(0, Sub), rhs = Counter(3) -- expression 2 operands: lhs = Counter(1), rhs = Expression(3, Add) -- expression 3 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) +- expression 2 operands: lhs = Counter(1), rhs = Counter(3) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(3) +- expression 4 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 15, 1) to (start + 2, 14) - Code(Counter(1)) at (prev + 2, 15) to (start + 2, 6) @@ -56,11 +57,11 @@ Number of file 0 mappings: 8 = (c0 - c1) - Code(Counter(4)) at (prev + 1, 13) to (start + 0, 14) - Code(Expression(1, Sub)) at (prev + 0, 18) to (start + 0, 22) - = ((c0 - c1) - c3) + = (c0 - (c1 + c3)) - Code(Counter(4)) at (prev + 0, 23) to (start + 4, 10) - Code(Counter(3)) at (prev + 5, 12) to (start + 2, 6) -- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c1 + (c2 + c3)) +- Code(Expression(3, Add)) at (prev + 3, 1) to (start + 0, 2) + = ((c1 + c2) + c3) Highest counter ID seen: c4 Function name: inline::permutations::<char> diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map index 64870c434b3..a2ab558f960 100644 --- a/tests/coverage/issue-84561.cov-map +++ b/tests/coverage/issue-84561.cov-map @@ -59,69 +59,69 @@ Number of file 0 mappings: 1 Highest counter ID seen: c0 Function name: issue_84561::test3 -Raw bytes (414): 0x[01, 01, 3b, 05, 09, 0d, 11, 15, 19, 1e, 1d, 15, 19, 1a, 21, 1e, 1d, 15, 19, 25, 2d, 21, 25, 29, 35, 32, 29, 21, 25, 31, 39, 3d, 41, 42, 45, 3d, 41, 66, 49, 45, 4d, 63, 51, 66, 49, 45, 4d, 5e, 55, 63, 51, 66, 49, 45, 4d, 9e, 01, 55, 51, 59, 9e, 01, 55, 51, 59, 9b, 01, 5d, 9e, 01, 55, 51, 59, 9b, 01, 61, 9e, 01, 55, 51, 59, 96, 01, 65, 9b, 01, 61, 9e, 01, 55, 51, 59, 75, e2, 01, e6, 01, 79, 69, 6d, 69, 6d, 69, 6d, e6, 01, 00, 69, 6d, e6, 01, 79, 69, 6d, df, 01, 7d, 75, e2, 01, e6, 01, 79, 69, 6d, da, 01, 81, 01, df, 01, 7d, 75, e2, 01, e6, 01, 79, 69, 6d, 81, 01, 85, 01, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 1e, 02, 05, 00, 1f, 1a, 01, 05, 00, 0f, 16, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 25, 03, 20, 00, 30, 2d, 00, 33, 00, 41, 22, 00, 4b, 00, 5a, 32, 01, 05, 00, 0f, 29, 05, 09, 03, 10, 35, 05, 0d, 00, 1b, 2a, 02, 0d, 00, 1c, 2e, 04, 09, 05, 06, 31, 06, 05, 03, 06, 36, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 42, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 3e, 05, 09, 03, 0a, 63, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 59, 03, 0d, 00, 1d, 5e, 03, 09, 00, 13, 5a, 03, 0d, 00, 1d, 9b, 01, 03, 05, 00, 0f, 9b, 01, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 7a, 02, 0d, 00, 13, 96, 01, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 92, 01, 02, 0d, 00, 13, df, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, e6, 01, 02, 0d, 00, 17, e6, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, b6, 01, 02, 15, 00, 1b, e2, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, da, 01, 02, 05, 00, 0f, d6, 01, 03, 09, 00, 22, 81, 01, 02, 05, 00, 0f, ea, 01, 03, 09, 00, 2c, 85, 01, 02, 01, 00, 02] +Raw bytes (409): 0x[01, 01, 3b, 05, 09, 0d, 11, 15, 19, 15, 1f, 19, 1d, 15, 1b, 1f, 21, 19, 1d, 25, 29, 21, 25, 2d, 31, 21, 33, 25, 2d, 35, 39, 3d, 41, 3d, 43, 41, 45, 5f, 4d, 45, 49, 5f, 67, 45, 49, 4d, 51, 5f, 63, 45, 49, 67, 59, 4d, 51, 97, 01, 55, 51, 59, 97, 01, 55, 51, 59, 97, 01, 83, 01, 51, 59, 55, 5d, 97, 01, 9f, 01, 51, 59, 55, 61, 97, 01, 9b, 01, 51, 59, 9f, 01, 65, 55, 61, db, 01, e7, 01, 69, 71, 6d, 75, 69, 6d, 69, 6d, 69, bb, 01, 6d, 00, 69, e7, 01, 6d, 75, db, 01, e3, 01, 69, 71, e7, 01, 79, 6d, 75, db, 01, df, 01, 69, 71, e3, 01, 7d, e7, 01, 79, 6d, 75, 7d, 81, 01, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 0a, 02, 05, 00, 1f, 0e, 01, 05, 00, 0f, 16, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 25, 03, 20, 00, 30, 29, 00, 33, 00, 41, 22, 00, 4b, 00, 5a, 26, 01, 05, 00, 0f, 2d, 05, 09, 03, 10, 31, 05, 0d, 00, 1b, 2a, 02, 0d, 00, 1c, 2e, 04, 09, 05, 06, 35, 06, 05, 03, 06, 36, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 3a, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 3e, 05, 09, 03, 0a, 46, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 55, 03, 0d, 00, 1d, 4e, 03, 09, 00, 13, 5a, 03, 0d, 00, 1d, 72, 03, 05, 00, 0f, 72, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 7a, 02, 0d, 00, 13, 86, 01, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 92, 01, 02, 0d, 00, 13, a2, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 71, 04, 0d, 00, 13, b2, 01, 02, 0d, 00, 17, b2, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, b6, 01, 02, 15, 00, 1b, be, 01, 04, 0d, 00, 13, 79, 03, 09, 00, 19, c6, 01, 02, 05, 00, 0f, d6, 01, 03, 09, 00, 22, 7d, 02, 05, 00, 0f, ea, 01, 03, 09, 00, 2c, 81, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 59 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(3), rhs = Counter(4) - expression 2 operands: lhs = Counter(5), rhs = Counter(6) -- expression 3 operands: lhs = Expression(7, Sub), rhs = Counter(7) -- expression 4 operands: lhs = Counter(5), rhs = Counter(6) -- expression 5 operands: lhs = Expression(6, Sub), rhs = Counter(8) -- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(7) -- expression 7 operands: lhs = Counter(5), rhs = Counter(6) -- expression 8 operands: lhs = Counter(9), rhs = Counter(11) +- expression 3 operands: lhs = Counter(5), rhs = Expression(7, Add) +- expression 4 operands: lhs = Counter(6), rhs = Counter(7) +- expression 5 operands: lhs = Counter(5), rhs = Expression(6, Add) +- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(8) +- expression 7 operands: lhs = Counter(6), rhs = Counter(7) +- expression 8 operands: lhs = Counter(9), rhs = Counter(10) - expression 9 operands: lhs = Counter(8), rhs = Counter(9) -- expression 10 operands: lhs = Counter(10), rhs = Counter(13) -- expression 11 operands: lhs = Expression(12, Sub), rhs = Counter(10) -- expression 12 operands: lhs = Counter(8), rhs = Counter(9) -- expression 13 operands: lhs = Counter(12), rhs = Counter(14) +- expression 10 operands: lhs = Counter(11), rhs = Counter(12) +- expression 11 operands: lhs = Counter(8), rhs = Expression(12, Add) +- expression 12 operands: lhs = Counter(9), rhs = Counter(11) +- expression 13 operands: lhs = Counter(13), rhs = Counter(14) - expression 14 operands: lhs = Counter(15), rhs = Counter(16) -- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(17) -- expression 16 operands: lhs = Counter(15), rhs = Counter(16) -- expression 17 operands: lhs = Expression(25, Sub), rhs = Counter(18) -- expression 18 operands: lhs = Counter(17), rhs = Counter(19) -- expression 19 operands: lhs = Expression(24, Add), rhs = Counter(20) -- expression 20 operands: lhs = Expression(25, Sub), rhs = Counter(18) -- expression 21 operands: lhs = Counter(17), rhs = Counter(19) -- expression 22 operands: lhs = Expression(23, Sub), rhs = Counter(21) -- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(20) -- expression 24 operands: lhs = Expression(25, Sub), rhs = Counter(18) -- expression 25 operands: lhs = Counter(17), rhs = Counter(19) -- expression 26 operands: lhs = Expression(39, Sub), rhs = Counter(21) +- expression 15 operands: lhs = Counter(15), rhs = Expression(16, Add) +- expression 16 operands: lhs = Counter(16), rhs = Counter(17) +- expression 17 operands: lhs = Expression(23, Add), rhs = Counter(19) +- expression 18 operands: lhs = Counter(17), rhs = Counter(18) +- expression 19 operands: lhs = Expression(23, Add), rhs = Expression(25, Add) +- expression 20 operands: lhs = Counter(17), rhs = Counter(18) +- expression 21 operands: lhs = Counter(19), rhs = Counter(20) +- expression 22 operands: lhs = Expression(23, Add), rhs = Expression(24, Add) +- expression 23 operands: lhs = Counter(17), rhs = Counter(18) +- expression 24 operands: lhs = Expression(25, Add), rhs = Counter(22) +- expression 25 operands: lhs = Counter(19), rhs = Counter(20) +- expression 26 operands: lhs = Expression(37, Add), rhs = Counter(21) - expression 27 operands: lhs = Counter(20), rhs = Counter(22) -- expression 28 operands: lhs = Expression(39, Sub), rhs = Counter(21) +- expression 28 operands: lhs = Expression(37, Add), rhs = Counter(21) - expression 29 operands: lhs = Counter(20), rhs = Counter(22) -- expression 30 operands: lhs = Expression(38, Add), rhs = Counter(23) -- expression 31 operands: lhs = Expression(39, Sub), rhs = Counter(21) -- expression 32 operands: lhs = Counter(20), rhs = Counter(22) -- expression 33 operands: lhs = Expression(38, Add), rhs = Counter(24) -- expression 34 operands: lhs = Expression(39, Sub), rhs = Counter(21) -- expression 35 operands: lhs = Counter(20), rhs = Counter(22) -- expression 36 operands: lhs = Expression(37, Sub), rhs = Counter(25) -- expression 37 operands: lhs = Expression(38, Add), rhs = Counter(24) -- expression 38 operands: lhs = Expression(39, Sub), rhs = Counter(21) -- expression 39 operands: lhs = Counter(20), rhs = Counter(22) -- expression 40 operands: lhs = Counter(29), rhs = Expression(56, Sub) -- expression 41 operands: lhs = Expression(57, Sub), rhs = Counter(30) -- expression 42 operands: lhs = Counter(26), rhs = Counter(27) +- expression 30 operands: lhs = Expression(37, Add), rhs = Expression(32, Add) +- expression 31 operands: lhs = Counter(20), rhs = Counter(22) +- expression 32 operands: lhs = Counter(21), rhs = Counter(23) +- expression 33 operands: lhs = Expression(37, Add), rhs = Expression(39, Add) +- expression 34 operands: lhs = Counter(20), rhs = Counter(22) +- expression 35 operands: lhs = Counter(21), rhs = Counter(24) +- expression 36 operands: lhs = Expression(37, Add), rhs = Expression(38, Add) +- expression 37 operands: lhs = Counter(20), rhs = Counter(22) +- expression 38 operands: lhs = Expression(39, Add), rhs = Counter(25) +- expression 39 operands: lhs = Counter(21), rhs = Counter(24) +- expression 40 operands: lhs = Expression(54, Add), rhs = Expression(57, Add) +- expression 41 operands: lhs = Counter(26), rhs = Counter(28) +- expression 42 operands: lhs = Counter(27), rhs = Counter(29) - expression 43 operands: lhs = Counter(26), rhs = Counter(27) - expression 44 operands: lhs = Counter(26), rhs = Counter(27) -- expression 45 operands: lhs = Expression(57, Sub), rhs = Zero -- expression 46 operands: lhs = Counter(26), rhs = Counter(27) -- expression 47 operands: lhs = Expression(57, Sub), rhs = Counter(30) -- expression 48 operands: lhs = Counter(26), rhs = Counter(27) -- expression 49 operands: lhs = Expression(55, Add), rhs = Counter(31) -- expression 50 operands: lhs = Counter(29), rhs = Expression(56, Sub) -- expression 51 operands: lhs = Expression(57, Sub), rhs = Counter(30) -- expression 52 operands: lhs = Counter(26), rhs = Counter(27) -- expression 53 operands: lhs = Expression(54, Sub), rhs = Counter(32) -- expression 54 operands: lhs = Expression(55, Add), rhs = Counter(31) -- expression 55 operands: lhs = Counter(29), rhs = Expression(56, Sub) -- expression 56 operands: lhs = Expression(57, Sub), rhs = Counter(30) -- expression 57 operands: lhs = Counter(26), rhs = Counter(27) -- expression 58 operands: lhs = Counter(32), rhs = Counter(33) +- expression 45 operands: lhs = Counter(26), rhs = Expression(46, Add) +- expression 46 operands: lhs = Counter(27), rhs = Zero +- expression 47 operands: lhs = Counter(26), rhs = Expression(57, Add) +- expression 48 operands: lhs = Counter(27), rhs = Counter(29) +- expression 49 operands: lhs = Expression(54, Add), rhs = Expression(56, Add) +- expression 50 operands: lhs = Counter(26), rhs = Counter(28) +- expression 51 operands: lhs = Expression(57, Add), rhs = Counter(30) +- expression 52 operands: lhs = Counter(27), rhs = Counter(29) +- expression 53 operands: lhs = Expression(54, Add), rhs = Expression(55, Add) +- expression 54 operands: lhs = Counter(26), rhs = Counter(28) +- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(31) +- expression 56 operands: lhs = Expression(57, Add), rhs = Counter(30) +- expression 57 operands: lhs = Counter(27), rhs = Counter(29) +- expression 58 operands: lhs = Counter(31), rhs = Counter(32) Number of file 0 mappings: 51 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28) - Code(Counter(1)) at (prev + 4, 9) to (start + 1, 28) @@ -131,76 +131,76 @@ Number of file 0 mappings: 51 - Code(Expression(1, Sub)) at (prev + 1, 5) to (start + 0, 31) = (c3 - c4) - Code(Counter(5)) at (prev + 1, 9) to (start + 1, 28) -- Code(Expression(7, Sub)) at (prev + 2, 5) to (start + 0, 31) +- Code(Expression(2, Sub)) at (prev + 2, 5) to (start + 0, 31) = (c5 - c6) -- Code(Expression(6, Sub)) at (prev + 1, 5) to (start + 0, 15) - = ((c5 - c6) - c7) +- Code(Expression(3, Sub)) at (prev + 1, 5) to (start + 0, 15) + = (c5 - (c6 + c7)) - Code(Expression(5, Sub)) at (prev + 0, 32) to (start + 0, 48) - = (((c5 - c6) - c7) - c8) + = (c5 - ((c6 + c7) + c8)) - Code(Counter(8)) at (prev + 1, 5) to (start + 3, 15) - Code(Counter(9)) at (prev + 3, 32) to (start + 0, 48) -- Code(Counter(11)) at (prev + 0, 51) to (start + 0, 65) +- Code(Counter(10)) at (prev + 0, 51) to (start + 0, 65) - Code(Expression(8, Sub)) at (prev + 0, 75) to (start + 0, 90) - = (c9 - c11) -- Code(Expression(12, Sub)) at (prev + 1, 5) to (start + 0, 15) + = (c9 - c10) +- Code(Expression(9, Sub)) at (prev + 1, 5) to (start + 0, 15) = (c8 - c9) -- Code(Counter(10)) at (prev + 5, 9) to (start + 3, 16) -- Code(Counter(13)) at (prev + 5, 13) to (start + 0, 27) +- Code(Counter(11)) at (prev + 5, 9) to (start + 3, 16) +- Code(Counter(12)) at (prev + 5, 13) to (start + 0, 27) - Code(Expression(10, Sub)) at (prev + 2, 13) to (start + 0, 28) - = (c10 - c13) + = (c11 - c12) - Code(Expression(11, Sub)) at (prev + 4, 9) to (start + 5, 6) - = ((c8 - c9) - c10) -- Code(Counter(12)) at (prev + 6, 5) to (start + 3, 6) + = (c8 - (c9 + c11)) +- Code(Counter(13)) at (prev + 6, 5) to (start + 3, 6) - Code(Expression(13, Sub)) at (prev + 4, 5) to (start + 3, 6) - = (c12 - c14) + = (c13 - c14) - Code(Counter(15)) at (prev + 4, 9) to (start + 4, 6) -- Code(Expression(16, Sub)) at (prev + 5, 8) to (start + 0, 15) +- Code(Expression(14, Sub)) at (prev + 5, 8) to (start + 0, 15) = (c15 - c16) - Code(Counter(17)) at (prev + 1, 9) to (start + 3, 10) - Code(Expression(15, Sub)) at (prev + 5, 9) to (start + 3, 10) - = ((c15 - c16) - c17) -- Code(Expression(24, Add)) at (prev + 5, 8) to (start + 0, 15) - = ((c17 - c19) + c18) + = (c15 - (c16 + c17)) +- Code(Expression(17, Sub)) at (prev + 5, 8) to (start + 0, 15) + = ((c17 + c18) - c19) - Code(Counter(20)) at (prev + 1, 9) to (start + 0, 19) -- Code(Counter(22)) at (prev + 3, 13) to (start + 0, 29) -- Code(Expression(23, Sub)) at (prev + 3, 9) to (start + 0, 19) - = (((c17 - c19) + c18) - c20) +- Code(Counter(21)) at (prev + 3, 13) to (start + 0, 29) +- Code(Expression(19, Sub)) at (prev + 3, 9) to (start + 0, 19) + = ((c17 + c18) - (c19 + c20)) - Code(Expression(22, Sub)) at (prev + 3, 13) to (start + 0, 29) - = ((((c17 - c19) + c18) - c20) - c21) -- Code(Expression(38, Add)) at (prev + 3, 5) to (start + 0, 15) - = ((c20 - c22) + c21) -- Code(Expression(38, Add)) at (prev + 1, 12) to (start + 0, 19) - = ((c20 - c22) + c21) + = ((c17 + c18) - ((c19 + c20) + c22)) +- Code(Expression(28, Sub)) at (prev + 3, 5) to (start + 0, 15) + = ((c20 + c22) - c21) +- Code(Expression(28, Sub)) at (prev + 1, 12) to (start + 0, 19) + = ((c20 + c22) - c21) - Code(Counter(23)) at (prev + 1, 13) to (start + 0, 19) - Code(Expression(30, Sub)) at (prev + 2, 13) to (start + 0, 19) - = (((c20 - c22) + c21) - c23) -- Code(Expression(37, Sub)) at (prev + 4, 5) to (start + 2, 19) - = (((c20 - c22) + c21) - c24) + = ((c20 + c22) - (c21 + c23)) +- Code(Expression(33, Sub)) at (prev + 4, 5) to (start + 2, 19) + = ((c20 + c22) - (c21 + c24)) - Code(Counter(25)) at (prev + 3, 13) to (start + 0, 19) - Code(Expression(36, Sub)) at (prev + 2, 13) to (start + 0, 19) - = ((((c20 - c22) + c21) - c24) - c25) -- Code(Expression(55, Add)) at (prev + 3, 5) to (start + 0, 15) - = (c29 + ((c26 - c27) - c30)) + = ((c20 + c22) - ((c21 + c24) + c25)) +- Code(Expression(40, Sub)) at (prev + 3, 5) to (start + 0, 15) + = ((c26 + c28) - (c27 + c29)) - Code(Counter(26)) at (prev + 1, 12) to (start + 0, 19) - Code(Counter(27)) at (prev + 1, 13) to (start + 3, 14) -- Code(Counter(29)) at (prev + 4, 13) to (start + 0, 19) -- Code(Expression(57, Sub)) at (prev + 2, 13) to (start + 0, 23) +- Code(Counter(28)) at (prev + 4, 13) to (start + 0, 19) +- Code(Expression(44, Sub)) at (prev + 2, 13) to (start + 0, 23) = (c26 - c27) -- Code(Expression(57, Sub)) at (prev + 1, 20) to (start + 0, 27) +- Code(Expression(44, Sub)) at (prev + 1, 20) to (start + 0, 27) = (c26 - c27) - Code(Zero) at (prev + 1, 21) to (start + 0, 27) - Code(Expression(45, Sub)) at (prev + 2, 21) to (start + 0, 27) - = ((c26 - c27) - Zero) -- Code(Expression(56, Sub)) at (prev + 4, 13) to (start + 0, 19) - = ((c26 - c27) - c30) -- Code(Counter(31)) at (prev + 3, 9) to (start + 0, 25) -- Code(Expression(54, Sub)) at (prev + 2, 5) to (start + 0, 15) - = ((c29 + ((c26 - c27) - c30)) - c31) + = (c26 - (c27 + Zero)) +- Code(Expression(47, Sub)) at (prev + 4, 13) to (start + 0, 19) + = (c26 - (c27 + c29)) +- Code(Counter(30)) at (prev + 3, 9) to (start + 0, 25) +- Code(Expression(49, Sub)) at (prev + 2, 5) to (start + 0, 15) + = ((c26 + c28) - ((c27 + c29) + c30)) - Code(Expression(53, Sub)) at (prev + 3, 9) to (start + 0, 34) - = (((c29 + ((c26 - c27) - c30)) - c31) - c32) -- Code(Counter(32)) at (prev + 2, 5) to (start + 0, 15) + = ((c26 + c28) - (((c27 + c29) + c30) + c31)) +- Code(Counter(31)) at (prev + 2, 5) to (start + 0, 15) - Code(Expression(58, Sub)) at (prev + 3, 9) to (start + 0, 44) - = (c32 - c33) -- Code(Counter(33)) at (prev + 2, 1) to (start + 0, 2) -Highest counter ID seen: c33 + = (c31 - c32) +- Code(Counter(32)) at (prev + 2, 1) to (start + 0, 2) +Highest counter ID seen: c32 diff --git a/tests/coverage/lazy_boolean.cov-map b/tests/coverage/lazy_boolean.cov-map index b0c2d736573..3f7788da1eb 100644 --- a/tests/coverage/lazy_boolean.cov-map +++ b/tests/coverage/lazy_boolean.cov-map @@ -1,15 +1,15 @@ Function name: lazy_boolean::main -Raw bytes (158): 0x[01, 01, 07, 01, 05, 01, 09, 01, 0d, 01, 19, 01, 1d, 01, 21, 01, 25, 1c, 01, 04, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 05, 00, 06, 01, 02, 09, 00, 11, 01, 02, 0d, 00, 12, 06, 02, 0d, 00, 12, 01, 03, 09, 00, 11, 01, 02, 0d, 00, 12, 0a, 02, 0d, 00, 12, 01, 02, 09, 00, 11, 01, 00, 14, 00, 19, 11, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 15, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 19, 03, 05, 00, 06, 01, 03, 09, 00, 10, 1d, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 21, 02, 05, 00, 06, 01, 02, 08, 00, 0f, 25, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (158): 0x[01, 01, 07, 01, 05, 01, 25, 01, 21, 01, 11, 01, 15, 01, 19, 01, 1d, 1c, 01, 04, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 05, 00, 06, 01, 02, 09, 00, 11, 01, 02, 0d, 00, 12, 06, 02, 0d, 00, 12, 01, 03, 09, 00, 11, 01, 02, 0d, 00, 12, 0a, 02, 0d, 00, 12, 01, 02, 09, 00, 11, 01, 00, 14, 00, 19, 09, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 0d, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 11, 03, 05, 00, 06, 01, 03, 09, 00, 10, 15, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 19, 02, 05, 00, 06, 01, 02, 08, 00, 0f, 1d, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 7 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Counter(2) -- expression 2 operands: lhs = Counter(0), rhs = Counter(3) -- expression 3 operands: lhs = Counter(0), rhs = Counter(6) -- expression 4 operands: lhs = Counter(0), rhs = Counter(7) -- expression 5 operands: lhs = Counter(0), rhs = Counter(8) -- expression 6 operands: lhs = Counter(0), rhs = Counter(9) +- expression 1 operands: lhs = Counter(0), rhs = Counter(9) +- expression 2 operands: lhs = Counter(0), rhs = Counter(8) +- expression 3 operands: lhs = Counter(0), rhs = Counter(4) +- expression 4 operands: lhs = Counter(0), rhs = Counter(5) +- expression 5 operands: lhs = Counter(0), rhs = Counter(6) +- expression 6 operands: lhs = Counter(0), rhs = Counter(7) Number of file 0 mappings: 28 - Code(Counter(0)) at (prev + 4, 1) to (start + 7, 15) - Code(Counter(1)) at (prev + 7, 16) to (start + 4, 6) @@ -18,33 +18,33 @@ Number of file 0 mappings: 28 - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 17) - Code(Counter(0)) at (prev + 2, 13) to (start + 0, 18) - Code(Expression(1, Sub)) at (prev + 2, 13) to (start + 0, 18) - = (c0 - c2) + = (c0 - c9) - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 17) - Code(Counter(0)) at (prev + 2, 13) to (start + 0, 18) - Code(Expression(2, Sub)) at (prev + 2, 13) to (start + 0, 18) - = (c0 - c3) + = (c0 - c8) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 17) - Code(Counter(0)) at (prev + 0, 20) to (start + 0, 25) -- Code(Counter(4)) at (prev + 0, 29) to (start + 0, 34) +- Code(Counter(2)) at (prev + 0, 29) to (start + 0, 34) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) - Code(Counter(0)) at (prev + 0, 20) to (start + 0, 25) -- Code(Counter(5)) at (prev + 0, 29) to (start + 0, 34) +- Code(Counter(3)) at (prev + 0, 29) to (start + 0, 34) - Code(Counter(0)) at (prev + 3, 9) to (start + 1, 16) - Code(Expression(3, Sub)) at (prev + 2, 5) to (start + 3, 6) - = (c0 - c6) -- Code(Counter(6)) at (prev + 3, 5) to (start + 0, 6) + = (c0 - c4) +- Code(Counter(4)) at (prev + 3, 5) to (start + 0, 6) - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 16) -- Code(Counter(7)) at (prev + 1, 5) to (start + 3, 6) +- Code(Counter(5)) at (prev + 1, 5) to (start + 3, 6) - Code(Expression(4, Sub)) at (prev + 5, 5) to (start + 3, 6) - = (c0 - c7) + = (c0 - c5) - Code(Counter(0)) at (prev + 5, 8) to (start + 0, 16) - Code(Expression(5, Sub)) at (prev + 0, 17) to (start + 2, 6) - = (c0 - c8) -- Code(Counter(8)) at (prev + 2, 5) to (start + 0, 6) + = (c0 - c6) +- Code(Counter(6)) at (prev + 2, 5) to (start + 0, 6) - Code(Counter(0)) at (prev + 2, 8) to (start + 0, 15) -- Code(Counter(9)) at (prev + 0, 16) to (start + 2, 6) +- Code(Counter(7)) at (prev + 0, 16) to (start + 2, 6) - Code(Expression(6, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - c9) + = (c0 - c7) - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c9 +Highest counter ID seen: c7 diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map index 61a6bda676a..14707701d8a 100644 --- a/tests/coverage/loops_branches.cov-map +++ b/tests/coverage/loops_branches.cov-map @@ -1,50 +1,42 @@ Function name: <loops_branches::DebugTest as core::fmt::Debug>::fmt -Raw bytes (228): 0x[01, 01, 2a, 05, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, a3, 01, a7, 01, 0d, 00, 11, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 96, 01, 00, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 96, 01, 11, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 8f, 01, 19, 25, 92, 01, 96, 01, 11, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0d, 00, 0e, 05, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 9a, 01, 03, 0d, 00, 0e, 9f, 01, 00, 12, 00, 17, 9a, 01, 01, 10, 00, 14, 96, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 46, 01, 11, 00, 12, 96, 01, 01, 11, 00, 22, 92, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, 8b, 01, 01, 05, 00, 06] +Raw bytes (174): 0x[01, 01, 22, 05, 00, 2f, 7b, 67, 00, 77, 19, 01, 15, 05, 21, 2f, 05, 67, 00, 77, 19, 01, 15, 2f, 7b, 67, 00, 77, 19, 01, 15, 05, 21, 67, 7b, 77, 19, 01, 15, 05, 21, 67, 5b, 77, 19, 01, 15, 7b, 00, 05, 21, 67, 7b, 77, 19, 01, 15, 05, 21, 77, 7b, 01, 15, 05, 21, 83, 01, 05, 87, 01, 15, 01, 11, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0d, 00, 0e, 05, 01, 0d, 00, 1e, 11, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 2a, 03, 0d, 00, 0e, 1a, 00, 12, 00, 17, 2a, 01, 10, 00, 14, 62, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 4e, 01, 11, 00, 12, 62, 01, 11, 00, 22, 72, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 21, 03, 09, 00, 0f, 7e, 01, 05, 00, 06] Number of files: 1 - file 0 => global file 1 -Number of expressions: 42 +Number of expressions: 34 - expression 0 operands: lhs = Counter(1), rhs = Zero -- expression 1 operands: lhs = Expression(39, Add), rhs = Counter(6) -- expression 2 operands: lhs = Expression(40, Add), rhs = Expression(41, Add) -- expression 3 operands: lhs = Counter(3), rhs = Zero -- expression 4 operands: lhs = Counter(4), rhs = Zero -- expression 5 operands: lhs = Expression(40, Add), rhs = Expression(41, Add) -- expression 6 operands: lhs = Counter(3), rhs = Zero -- expression 7 operands: lhs = Counter(4), rhs = Zero -- expression 8 operands: lhs = Expression(39, Add), rhs = Counter(6) -- expression 9 operands: lhs = Expression(40, Add), rhs = Expression(41, Add) -- expression 10 operands: lhs = Counter(3), rhs = Zero -- expression 11 operands: lhs = Counter(4), rhs = Zero -- expression 12 operands: lhs = Expression(38, Sub), rhs = Zero -- expression 13 operands: lhs = Expression(39, Add), rhs = Counter(6) -- expression 14 operands: lhs = Expression(40, Add), rhs = Expression(41, Add) -- expression 15 operands: lhs = Counter(3), rhs = Zero -- expression 16 operands: lhs = Counter(4), rhs = Zero -- expression 17 operands: lhs = Expression(37, Sub), rhs = Zero -- expression 18 operands: lhs = Expression(38, Sub), rhs = Zero -- expression 19 operands: lhs = Expression(39, Add), rhs = Counter(6) -- expression 20 operands: lhs = Expression(40, Add), rhs = Expression(41, Add) -- expression 21 operands: lhs = Counter(3), rhs = Zero -- expression 22 operands: lhs = Counter(4), rhs = Zero -- expression 23 operands: lhs = Expression(38, Sub), rhs = Zero -- expression 24 operands: lhs = Expression(39, Add), rhs = Counter(6) -- expression 25 operands: lhs = Expression(40, Add), rhs = Expression(41, Add) -- expression 26 operands: lhs = Counter(3), rhs = Zero -- expression 27 operands: lhs = Counter(4), rhs = Zero -- expression 28 operands: lhs = Expression(37, Sub), rhs = Counter(4) -- expression 29 operands: lhs = Expression(38, Sub), rhs = Zero -- expression 30 operands: lhs = Expression(39, Add), rhs = Counter(6) -- expression 31 operands: lhs = Expression(40, Add), rhs = Expression(41, Add) -- expression 32 operands: lhs = Counter(3), rhs = Zero -- expression 33 operands: lhs = Counter(4), rhs = Zero -- expression 34 operands: lhs = Expression(35, Add), rhs = Counter(6) -- expression 35 operands: lhs = Counter(9), rhs = Expression(36, Sub) -- expression 36 operands: lhs = Expression(37, Sub), rhs = Counter(4) -- expression 37 operands: lhs = Expression(38, Sub), rhs = Zero -- expression 38 operands: lhs = Expression(39, Add), rhs = Counter(6) -- expression 39 operands: lhs = Expression(40, Add), rhs = Expression(41, Add) -- expression 40 operands: lhs = Counter(3), rhs = Zero -- expression 41 operands: lhs = Counter(4), rhs = Zero +- expression 1 operands: lhs = Expression(11, Add), rhs = Expression(30, Add) +- expression 2 operands: lhs = Expression(25, Add), rhs = Zero +- expression 3 operands: lhs = Expression(29, Add), rhs = Counter(6) +- expression 4 operands: lhs = Counter(0), rhs = Counter(5) +- expression 5 operands: lhs = Counter(1), rhs = Counter(8) +- expression 6 operands: lhs = Expression(11, Add), rhs = Counter(1) +- expression 7 operands: lhs = Expression(25, Add), rhs = Zero +- expression 8 operands: lhs = Expression(29, Add), rhs = Counter(6) +- expression 9 operands: lhs = Counter(0), rhs = Counter(5) +- expression 10 operands: lhs = Expression(11, Add), rhs = Expression(30, Add) +- expression 11 operands: lhs = Expression(25, Add), rhs = Zero +- expression 12 operands: lhs = Expression(29, Add), rhs = Counter(6) +- expression 13 operands: lhs = Counter(0), rhs = Counter(5) +- expression 14 operands: lhs = Counter(1), rhs = Counter(8) +- expression 15 operands: lhs = Expression(25, Add), rhs = Expression(30, Add) +- expression 16 operands: lhs = Expression(29, Add), rhs = Counter(6) +- expression 17 operands: lhs = Counter(0), rhs = Counter(5) +- expression 18 operands: lhs = Counter(1), rhs = Counter(8) +- expression 19 operands: lhs = Expression(25, Add), rhs = Expression(22, Add) +- expression 20 operands: lhs = Expression(29, Add), rhs = Counter(6) +- expression 21 operands: lhs = Counter(0), rhs = Counter(5) +- expression 22 operands: lhs = Expression(30, Add), rhs = Zero +- expression 23 operands: lhs = Counter(1), rhs = Counter(8) +- expression 24 operands: lhs = Expression(25, Add), rhs = Expression(30, Add) +- expression 25 operands: lhs = Expression(29, Add), rhs = Counter(6) +- expression 26 operands: lhs = Counter(0), rhs = Counter(5) +- expression 27 operands: lhs = Counter(1), rhs = Counter(8) +- expression 28 operands: lhs = Expression(29, Add), rhs = Expression(30, Add) +- expression 29 operands: lhs = Counter(0), rhs = Counter(5) +- expression 30 operands: lhs = Counter(1), rhs = Counter(8) +- expression 31 operands: lhs = Expression(32, Add), rhs = Counter(1) +- expression 32 operands: lhs = Expression(33, Add), rhs = Counter(5) +- expression 33 operands: lhs = Counter(0), rhs = Counter(4) Number of file 0 mappings: 20 - Code(Counter(0)) at (prev + 9, 5) to (start + 1, 16) - Code(Counter(1)) at (prev + 2, 16) to (start + 0, 21) @@ -53,78 +45,59 @@ Number of file 0 mappings: 20 - Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 14) = (c1 - Zero) - Code(Counter(1)) at (prev + 1, 13) to (start + 0, 30) -- Code(Counter(9)) at (prev + 0, 30) to (start + 0, 31) +- Code(Counter(4)) at (prev + 0, 30) to (start + 0, 31) - Code(Zero) at (prev + 1, 16) to (start + 1, 10) -- Code(Expression(38, Sub)) at (prev + 3, 13) to (start + 0, 14) - = (((c3 + Zero) + (c4 + Zero)) - c6) -- Code(Expression(39, Add)) at (prev + 0, 18) to (start + 0, 23) - = ((c3 + Zero) + (c4 + Zero)) -- Code(Expression(38, Sub)) at (prev + 1, 16) to (start + 0, 20) - = (((c3 + Zero) + (c4 + Zero)) - c6) -- Code(Expression(37, Sub)) at (prev + 1, 20) to (start + 0, 25) - = ((((c3 + Zero) + (c4 + Zero)) - c6) - Zero) +- Code(Expression(10, Sub)) at (prev + 3, 13) to (start + 0, 14) + = ((((c0 + c5) + c6) + Zero) - (c1 + c8)) +- Code(Expression(6, Sub)) at (prev + 0, 18) to (start + 0, 23) + = ((((c0 + c5) + c6) + Zero) - c1) +- Code(Expression(10, Sub)) at (prev + 1, 16) to (start + 0, 20) + = ((((c0 + c5) + c6) + Zero) - (c1 + c8)) +- Code(Expression(24, Sub)) at (prev + 1, 20) to (start + 0, 25) + = (((c0 + c5) + c6) - (c1 + c8)) - Code(Zero) at (prev + 1, 27) to (start + 0, 31) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) -- Code(Expression(17, Sub)) at (prev + 1, 17) to (start + 0, 18) - = (((((c3 + Zero) + (c4 + Zero)) - c6) - Zero) - Zero) -- Code(Expression(37, Sub)) at (prev + 1, 17) to (start + 0, 34) - = ((((c3 + Zero) + (c4 + Zero)) - c6) - Zero) -- Code(Expression(36, Sub)) at (prev + 0, 34) to (start + 0, 35) - = (((((c3 + Zero) + (c4 + Zero)) - c6) - Zero) - c4) +- Code(Expression(19, Sub)) at (prev + 1, 17) to (start + 0, 18) + = (((c0 + c5) + c6) - ((c1 + c8) + Zero)) +- Code(Expression(24, Sub)) at (prev + 1, 17) to (start + 0, 34) + = (((c0 + c5) + c6) - (c1 + c8)) +- Code(Expression(28, Sub)) at (prev + 0, 34) to (start + 0, 35) + = ((c0 + c5) - (c1 + c8)) - Code(Zero) at (prev + 1, 20) to (start + 1, 14) -- Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15) -- Code(Expression(34, Add)) at (prev + 1, 5) to (start + 0, 6) - = ((c9 + (((((c3 + Zero) + (c4 + Zero)) - c6) - Zero) - c4)) + c6) -Highest counter ID seen: c9 +- Code(Counter(8)) at (prev + 3, 9) to (start + 0, 15) +- Code(Expression(31, Sub)) at (prev + 1, 5) to (start + 0, 6) + = (((c0 + c4) + c5) - c1) +Highest counter ID seen: c8 Function name: <loops_branches::DisplayTest as core::fmt::Display>::fmt -Raw bytes (230): 0x[01, 01, 2b, 01, 00, 02, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, a7, 01, ab, 01, 00, 0d, 00, 15, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9a, 01, 00, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9a, 01, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 93, 01, 25, 96, 01, 19, 9a, 01, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 06, 01, 0d, 00, 0e, 02, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 9e, 01, 02, 0d, 00, 0e, a3, 01, 00, 12, 00, 17, 9e, 01, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 9a, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 4a, 01, 11, 00, 12, 9a, 01, 01, 11, 00, 22, 96, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, 8f, 01, 01, 05, 00, 06] +Raw bytes (152): 0x[01, 01, 18, 01, 00, 01, 00, 23, 15, 27, 11, 00, 0d, 27, 11, 00, 0d, 23, 15, 27, 11, 00, 0d, 4b, 15, 4f, 11, 00, 0d, 4b, 43, 4f, 11, 00, 0d, 15, 00, 4b, 15, 4f, 11, 00, 0d, 5f, 15, 00, 11, 5f, 21, 00, 11, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 06, 01, 0d, 00, 0e, 02, 01, 0d, 00, 1e, 21, 00, 1e, 00, 1f, 1e, 02, 0d, 00, 0e, 23, 00, 12, 00, 17, 1e, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 46, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 36, 01, 11, 00, 12, 46, 01, 11, 00, 22, 52, 00, 22, 00, 23, 15, 03, 09, 00, 0f, 5b, 01, 05, 00, 06] Number of files: 1 - file 0 => global file 1 -Number of expressions: 43 +Number of expressions: 24 - expression 0 operands: lhs = Counter(0), rhs = Zero -- expression 1 operands: lhs = Expression(0, Sub), rhs = Zero -- expression 2 operands: lhs = Expression(40, Add), rhs = Counter(6) -- expression 3 operands: lhs = Expression(41, Add), rhs = Expression(42, Add) +- expression 1 operands: lhs = Counter(0), rhs = Zero +- expression 2 operands: lhs = Expression(8, Add), rhs = Counter(5) +- expression 3 operands: lhs = Expression(9, Add), rhs = Counter(4) - expression 4 operands: lhs = Zero, rhs = Counter(3) -- expression 5 operands: lhs = Zero, rhs = Counter(5) -- expression 6 operands: lhs = Expression(41, Add), rhs = Expression(42, Add) -- expression 7 operands: lhs = Zero, rhs = Counter(3) -- expression 8 operands: lhs = Zero, rhs = Counter(5) -- expression 9 operands: lhs = Expression(40, Add), rhs = Counter(6) -- expression 10 operands: lhs = Expression(41, Add), rhs = Expression(42, Add) -- expression 11 operands: lhs = Zero, rhs = Counter(3) -- expression 12 operands: lhs = Zero, rhs = Counter(5) -- expression 13 operands: lhs = Expression(39, Sub), rhs = Zero -- expression 14 operands: lhs = Expression(40, Add), rhs = Counter(6) -- expression 15 operands: lhs = Expression(41, Add), rhs = Expression(42, Add) -- expression 16 operands: lhs = Zero, rhs = Counter(3) -- expression 17 operands: lhs = Zero, rhs = Counter(5) -- expression 18 operands: lhs = Expression(38, Sub), rhs = Zero -- expression 19 operands: lhs = Expression(39, Sub), rhs = Zero -- expression 20 operands: lhs = Expression(40, Add), rhs = Counter(6) -- expression 21 operands: lhs = Expression(41, Add), rhs = Expression(42, Add) -- expression 22 operands: lhs = Zero, rhs = Counter(3) -- expression 23 operands: lhs = Zero, rhs = Counter(5) -- expression 24 operands: lhs = Expression(39, Sub), rhs = Zero -- expression 25 operands: lhs = Expression(40, Add), rhs = Counter(6) -- expression 26 operands: lhs = Expression(41, Add), rhs = Expression(42, Add) -- expression 27 operands: lhs = Zero, rhs = Counter(3) -- expression 28 operands: lhs = Zero, rhs = Counter(5) -- expression 29 operands: lhs = Expression(38, Sub), rhs = Counter(5) -- expression 30 operands: lhs = Expression(39, Sub), rhs = Zero -- expression 31 operands: lhs = Expression(40, Add), rhs = Counter(6) -- expression 32 operands: lhs = Expression(41, Add), rhs = Expression(42, Add) -- expression 33 operands: lhs = Zero, rhs = Counter(3) -- expression 34 operands: lhs = Zero, rhs = Counter(5) -- expression 35 operands: lhs = Expression(36, Add), rhs = Counter(9) -- expression 36 operands: lhs = Expression(37, Sub), rhs = Counter(6) -- expression 37 operands: lhs = Expression(38, Sub), rhs = Counter(5) -- expression 38 operands: lhs = Expression(39, Sub), rhs = Zero -- expression 39 operands: lhs = Expression(40, Add), rhs = Counter(6) -- expression 40 operands: lhs = Expression(41, Add), rhs = Expression(42, Add) -- expression 41 operands: lhs = Zero, rhs = Counter(3) -- expression 42 operands: lhs = Zero, rhs = Counter(5) +- expression 5 operands: lhs = Expression(9, Add), rhs = Counter(4) +- expression 6 operands: lhs = Zero, rhs = Counter(3) +- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(5) +- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(4) +- expression 9 operands: lhs = Zero, rhs = Counter(3) +- expression 10 operands: lhs = Expression(18, Add), rhs = Counter(5) +- expression 11 operands: lhs = Expression(19, Add), rhs = Counter(4) +- expression 12 operands: lhs = Zero, rhs = Counter(3) +- expression 13 operands: lhs = Expression(18, Add), rhs = Expression(16, Add) +- expression 14 operands: lhs = Expression(19, Add), rhs = Counter(4) +- expression 15 operands: lhs = Zero, rhs = Counter(3) +- expression 16 operands: lhs = Counter(5), rhs = Zero +- expression 17 operands: lhs = Expression(18, Add), rhs = Counter(5) +- expression 18 operands: lhs = Expression(19, Add), rhs = Counter(4) +- expression 19 operands: lhs = Zero, rhs = Counter(3) +- expression 20 operands: lhs = Expression(23, Add), rhs = Counter(5) +- expression 21 operands: lhs = Zero, rhs = Counter(4) +- expression 22 operands: lhs = Expression(23, Add), rhs = Counter(8) +- expression 23 operands: lhs = Zero, rhs = Counter(4) Number of file 0 mappings: 20 - Code(Counter(0)) at (prev + 34, 5) to (start + 1, 17) - Code(Zero) at (prev + 1, 18) to (start + 1, 10) @@ -133,31 +106,31 @@ Number of file 0 mappings: 20 - Code(Zero) at (prev + 1, 23) to (start + 0, 27) - Code(Zero) at (prev + 0, 28) to (start + 0, 30) - Code(Expression(1, Sub)) at (prev + 1, 13) to (start + 0, 14) - = ((c0 - Zero) - Zero) + = (c0 - Zero) - Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 30) = (c0 - Zero) -- Code(Counter(9)) at (prev + 0, 30) to (start + 0, 31) -- Code(Expression(39, Sub)) at (prev + 2, 13) to (start + 0, 14) - = (((Zero + c3) + (Zero + c5)) - c6) -- Code(Expression(40, Add)) at (prev + 0, 18) to (start + 0, 23) - = ((Zero + c3) + (Zero + c5)) -- Code(Expression(39, Sub)) at (prev + 1, 16) to (start + 0, 21) - = (((Zero + c3) + (Zero + c5)) - c6) +- Code(Counter(8)) at (prev + 0, 30) to (start + 0, 31) +- Code(Expression(7, Sub)) at (prev + 2, 13) to (start + 0, 14) + = (((Zero + c3) + c4) - c5) +- Code(Expression(8, Add)) at (prev + 0, 18) to (start + 0, 23) + = ((Zero + c3) + c4) +- Code(Expression(7, Sub)) at (prev + 1, 16) to (start + 0, 21) + = (((Zero + c3) + c4) - c5) - Code(Zero) at (prev + 0, 22) to (start + 1, 14) -- Code(Expression(38, Sub)) at (prev + 2, 20) to (start + 0, 25) - = ((((Zero + c3) + (Zero + c5)) - c6) - Zero) +- Code(Expression(17, Sub)) at (prev + 2, 20) to (start + 0, 25) + = (((Zero + c3) + c4) - c5) - Code(Zero) at (prev + 1, 27) to (start + 0, 31) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) -- Code(Expression(18, Sub)) at (prev + 1, 17) to (start + 0, 18) - = (((((Zero + c3) + (Zero + c5)) - c6) - Zero) - Zero) -- Code(Expression(38, Sub)) at (prev + 1, 17) to (start + 0, 34) - = ((((Zero + c3) + (Zero + c5)) - c6) - Zero) -- Code(Expression(37, Sub)) at (prev + 0, 34) to (start + 0, 35) - = (((((Zero + c3) + (Zero + c5)) - c6) - Zero) - c5) -- Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15) -- Code(Expression(35, Add)) at (prev + 1, 5) to (start + 0, 6) - = (((((((Zero + c3) + (Zero + c5)) - c6) - Zero) - c5) + c6) + c9) -Highest counter ID seen: c9 +- Code(Expression(13, Sub)) at (prev + 1, 17) to (start + 0, 18) + = (((Zero + c3) + c4) - (c5 + Zero)) +- Code(Expression(17, Sub)) at (prev + 1, 17) to (start + 0, 34) + = (((Zero + c3) + c4) - c5) +- Code(Expression(20, Sub)) at (prev + 0, 34) to (start + 0, 35) + = ((Zero + c4) - c5) +- Code(Counter(5)) at (prev + 3, 9) to (start + 0, 15) +- Code(Expression(22, Add)) at (prev + 1, 5) to (start + 0, 6) + = ((Zero + c4) + c8) +Highest counter ID seen: c8 Function name: loops_branches::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 37, 01, 05, 02] diff --git a/tests/coverage/mcdc/condition-limit.cov-map b/tests/coverage/mcdc/condition-limit.cov-map index e3f5b49d363..19716878600 100644 --- a/tests/coverage/mcdc/condition-limit.cov-map +++ b/tests/coverage/mcdc/condition-limit.cov-map @@ -1,52 +1,54 @@ Function name: condition_limit::accept_7_conditions -Raw bytes (232): 0x[01, 01, 2c, 01, 05, 05, 1d, 05, 1d, 7a, 19, 05, 1d, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 21, 9b, 01, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 12, 01, 07, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 7a, 1d, 07, 06, 00, 00, 0d, 00, 0e, 7a, 00, 12, 00, 13, 30, 76, 19, 06, 05, 00, 00, 12, 00, 13, 76, 00, 17, 00, 18, 30, 72, 15, 05, 04, 00, 00, 17, 00, 18, 72, 00, 1c, 00, 1d, 30, 6e, 11, 04, 03, 00, 00, 1c, 00, 1d, 6e, 00, 21, 00, 22, 30, 6a, 0d, 03, 02, 00, 00, 21, 00, 22, 6a, 00, 26, 00, 27, 30, 21, 09, 02, 00, 00, 00, 26, 00, 27, 21, 00, 28, 02, 06, 9b, 01, 02, 05, 00, 06, 97, 01, 01, 01, 00, 02] +Raw bytes (237): 0x[01, 01, 2e, 01, 05, 05, 09, 05, 09, 05, 7b, 09, 0d, 05, 7b, 09, 0d, 05, 77, 7b, 11, 09, 0d, 05, 77, 7b, 11, 09, 0d, 05, 73, 77, 15, 7b, 11, 09, 0d, 05, 73, 77, 15, 7b, 11, 09, 0d, 05, 6f, 73, 19, 77, 15, 7b, 11, 09, 0d, 05, 6f, 73, 19, 77, 15, 7b, 11, 09, 0d, 83, 01, 05, a7, 01, 21, ab, 01, 19, af, 01, 15, b3, 01, 11, b7, 01, 0d, 01, 09, 9f, 01, 05, a3, 01, 21, a7, 01, 1d, ab, 01, 19, af, 01, 15, b3, 01, 11, b7, 01, 0d, 01, 09, 12, 01, 07, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0a, 09, 07, 06, 00, 00, 0d, 00, 0e, 0a, 00, 12, 00, 13, 30, 16, 0d, 06, 05, 00, 00, 12, 00, 13, 16, 00, 17, 00, 18, 30, 2a, 11, 05, 04, 00, 00, 17, 00, 18, 2a, 00, 1c, 00, 1d, 30, 46, 15, 04, 03, 00, 00, 1c, 00, 1d, 46, 00, 21, 00, 22, 30, 6a, 19, 03, 02, 00, 00, 21, 00, 22, 6a, 00, 26, 00, 27, 30, 1d, 21, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 7e, 02, 05, 00, 06, 9a, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 44 +Number of expressions: 46 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(7) -- expression 2 operands: lhs = Counter(1), rhs = Counter(7) -- expression 3 operands: lhs = Expression(30, Sub), rhs = Counter(6) -- expression 4 operands: lhs = Counter(1), rhs = Counter(7) -- expression 5 operands: lhs = Expression(30, Sub), rhs = Counter(6) -- expression 6 operands: lhs = Counter(1), rhs = Counter(7) -- expression 7 operands: lhs = Expression(29, Sub), rhs = Counter(5) -- expression 8 operands: lhs = Expression(30, Sub), rhs = Counter(6) -- expression 9 operands: lhs = Counter(1), rhs = Counter(7) -- expression 10 operands: lhs = Expression(29, Sub), rhs = Counter(5) -- expression 11 operands: lhs = Expression(30, Sub), rhs = Counter(6) -- expression 12 operands: lhs = Counter(1), rhs = Counter(7) -- expression 13 operands: lhs = Expression(28, Sub), rhs = Counter(4) -- expression 14 operands: lhs = Expression(29, Sub), rhs = Counter(5) -- expression 15 operands: lhs = Expression(30, Sub), rhs = Counter(6) -- expression 16 operands: lhs = Counter(1), rhs = Counter(7) -- expression 17 operands: lhs = Expression(28, Sub), rhs = Counter(4) -- expression 18 operands: lhs = Expression(29, Sub), rhs = Counter(5) -- expression 19 operands: lhs = Expression(30, Sub), rhs = Counter(6) -- expression 20 operands: lhs = Counter(1), rhs = Counter(7) -- expression 21 operands: lhs = Expression(27, Sub), rhs = Counter(3) -- expression 22 operands: lhs = Expression(28, Sub), rhs = Counter(4) -- expression 23 operands: lhs = Expression(29, Sub), rhs = Counter(5) -- expression 24 operands: lhs = Expression(30, Sub), rhs = Counter(6) -- expression 25 operands: lhs = Counter(1), rhs = Counter(7) -- expression 26 operands: lhs = Expression(27, Sub), rhs = Counter(3) -- expression 27 operands: lhs = Expression(28, Sub), rhs = Counter(4) -- expression 28 operands: lhs = Expression(29, Sub), rhs = Counter(5) -- expression 29 operands: lhs = Expression(30, Sub), rhs = Counter(6) -- expression 30 operands: lhs = Counter(1), rhs = Counter(7) -- expression 31 operands: lhs = Expression(39, Add), rhs = Expression(0, Sub) -- expression 32 operands: lhs = Expression(40, Add), rhs = Counter(7) -- expression 33 operands: lhs = Expression(41, Add), rhs = Counter(6) -- expression 34 operands: lhs = Expression(42, Add), rhs = Counter(5) -- expression 35 operands: lhs = Expression(43, Add), rhs = Counter(4) -- expression 36 operands: lhs = Counter(2), rhs = Counter(3) -- expression 37 operands: lhs = Counter(8), rhs = Expression(38, Add) -- expression 38 operands: lhs = Expression(39, Add), rhs = Expression(0, Sub) -- expression 39 operands: lhs = Expression(40, Add), rhs = Counter(7) -- expression 40 operands: lhs = Expression(41, Add), rhs = Counter(6) -- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(5) -- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(4) -- expression 43 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 2 operands: lhs = Counter(1), rhs = Counter(2) +- expression 3 operands: lhs = Counter(1), rhs = Expression(30, Add) +- expression 4 operands: lhs = Counter(2), rhs = Counter(3) +- expression 5 operands: lhs = Counter(1), rhs = Expression(30, Add) +- expression 6 operands: lhs = Counter(2), rhs = Counter(3) +- expression 7 operands: lhs = Counter(1), rhs = Expression(29, Add) +- expression 8 operands: lhs = Expression(30, Add), rhs = Counter(4) +- expression 9 operands: lhs = Counter(2), rhs = Counter(3) +- expression 10 operands: lhs = Counter(1), rhs = Expression(29, Add) +- expression 11 operands: lhs = Expression(30, Add), rhs = Counter(4) +- expression 12 operands: lhs = Counter(2), rhs = Counter(3) +- expression 13 operands: lhs = Counter(1), rhs = Expression(28, Add) +- expression 14 operands: lhs = Expression(29, Add), rhs = Counter(5) +- expression 15 operands: lhs = Expression(30, Add), rhs = Counter(4) +- expression 16 operands: lhs = Counter(2), rhs = Counter(3) +- expression 17 operands: lhs = Counter(1), rhs = Expression(28, Add) +- expression 18 operands: lhs = Expression(29, Add), rhs = Counter(5) +- expression 19 operands: lhs = Expression(30, Add), rhs = Counter(4) +- expression 20 operands: lhs = Counter(2), rhs = Counter(3) +- expression 21 operands: lhs = Counter(1), rhs = Expression(27, Add) +- expression 22 operands: lhs = Expression(28, Add), rhs = Counter(6) +- expression 23 operands: lhs = Expression(29, Add), rhs = Counter(5) +- expression 24 operands: lhs = Expression(30, Add), rhs = Counter(4) +- expression 25 operands: lhs = Counter(2), rhs = Counter(3) +- expression 26 operands: lhs = Counter(1), rhs = Expression(27, Add) +- expression 27 operands: lhs = Expression(28, Add), rhs = Counter(6) +- expression 28 operands: lhs = Expression(29, Add), rhs = Counter(5) +- expression 29 operands: lhs = Expression(30, Add), rhs = Counter(4) +- expression 30 operands: lhs = Counter(2), rhs = Counter(3) +- expression 31 operands: lhs = Expression(32, Add), rhs = Counter(1) +- expression 32 operands: lhs = Expression(41, Add), rhs = Counter(8) +- expression 33 operands: lhs = Expression(42, Add), rhs = Counter(6) +- expression 34 operands: lhs = Expression(43, Add), rhs = Counter(5) +- expression 35 operands: lhs = Expression(44, Add), rhs = Counter(4) +- expression 36 operands: lhs = Expression(45, Add), rhs = Counter(3) +- expression 37 operands: lhs = Counter(0), rhs = Counter(2) +- expression 38 operands: lhs = Expression(39, Add), rhs = Counter(1) +- expression 39 operands: lhs = Expression(40, Add), rhs = Counter(8) +- expression 40 operands: lhs = Expression(41, Add), rhs = Counter(7) +- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(6) +- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(5) +- expression 43 operands: lhs = Expression(44, Add), rhs = Counter(4) +- expression 44 operands: lhs = Expression(45, Add), rhs = Counter(3) +- expression 45 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 18 - Code(Counter(0)) at (prev + 7, 1) to (start + 2, 9) - MCDCDecision { bitmap_idx: 8, conditions_num: 7 } at (prev + 2, 8) to (start + 0, 39) @@ -54,38 +56,38 @@ Number of file 0 mappings: 18 true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) -- MCDCBranch { true: Expression(30, Sub), false: Counter(7), condition_id: 7, true_next_id: 6, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = (c1 - c7) - false = c7 -- Code(Expression(30, Sub)) at (prev + 0, 18) to (start + 0, 19) - = (c1 - c7) -- MCDCBranch { true: Expression(29, Sub), false: Counter(6), condition_id: 6, true_next_id: 5, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) - true = ((c1 - c7) - c6) - false = c6 -- Code(Expression(29, Sub)) at (prev + 0, 23) to (start + 0, 24) - = ((c1 - c7) - c6) -- MCDCBranch { true: Expression(28, Sub), false: Counter(5), condition_id: 5, true_next_id: 4, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) - true = (((c1 - c7) - c6) - c5) - false = c5 -- Code(Expression(28, Sub)) at (prev + 0, 28) to (start + 0, 29) - = (((c1 - c7) - c6) - c5) -- MCDCBranch { true: Expression(27, Sub), false: Counter(4), condition_id: 4, true_next_id: 3, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29) - true = ((((c1 - c7) - c6) - c5) - c4) - false = c4 -- Code(Expression(27, Sub)) at (prev + 0, 33) to (start + 0, 34) - = ((((c1 - c7) - c6) - c5) - c4) -- MCDCBranch { true: Expression(26, Sub), false: Counter(3), condition_id: 3, true_next_id: 2, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34) - true = (((((c1 - c7) - c6) - c5) - c4) - c3) +- MCDCBranch { true: Expression(2, Sub), false: Counter(2), condition_id: 7, true_next_id: 6, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) + true = (c1 - c2) + false = c2 +- Code(Expression(2, Sub)) at (prev + 0, 18) to (start + 0, 19) + = (c1 - c2) +- MCDCBranch { true: Expression(5, Sub), false: Counter(3), condition_id: 6, true_next_id: 5, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) + true = (c1 - (c2 + c3)) false = c3 +- Code(Expression(5, Sub)) at (prev + 0, 23) to (start + 0, 24) + = (c1 - (c2 + c3)) +- MCDCBranch { true: Expression(10, Sub), false: Counter(4), condition_id: 5, true_next_id: 4, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) + true = (c1 - ((c2 + c3) + c4)) + false = c4 +- Code(Expression(10, Sub)) at (prev + 0, 28) to (start + 0, 29) + = (c1 - ((c2 + c3) + c4)) +- MCDCBranch { true: Expression(17, Sub), false: Counter(5), condition_id: 4, true_next_id: 3, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29) + true = (c1 - (((c2 + c3) + c4) + c5)) + false = c5 +- Code(Expression(17, Sub)) at (prev + 0, 33) to (start + 0, 34) + = (c1 - (((c2 + c3) + c4) + c5)) +- MCDCBranch { true: Expression(26, Sub), false: Counter(6), condition_id: 3, true_next_id: 2, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34) + true = (c1 - ((((c2 + c3) + c4) + c5) + c6)) + false = c6 - Code(Expression(26, Sub)) at (prev + 0, 38) to (start + 0, 39) - = (((((c1 - c7) - c6) - c5) - c4) - c3) -- MCDCBranch { true: Counter(8), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 38) to (start + 0, 39) - true = c8 - false = c2 -- Code(Counter(8)) at (prev + 0, 40) to (start + 2, 6) -- Code(Expression(38, Add)) at (prev + 2, 5) to (start + 0, 6) - = ((((((c2 + c3) + c4) + c5) + c6) + c7) + (c0 - c1)) -- Code(Expression(37, Add)) at (prev + 1, 1) to (start + 0, 2) - = (c8 + ((((((c2 + c3) + c4) + c5) + c6) + c7) + (c0 - c1))) + = (c1 - ((((c2 + c3) + c4) + c5) + c6)) +- MCDCBranch { true: Counter(7), false: Counter(8), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 38) to (start + 0, 39) + true = c7 + false = c8 +- Code(Counter(7)) at (prev + 0, 40) to (start + 2, 6) +- Code(Expression(31, Sub)) at (prev + 2, 5) to (start + 0, 6) + = (((((((c0 + c2) + c3) + c4) + c5) + c6) + c8) - c1) +- Code(Expression(38, Sub)) at (prev + 1, 1) to (start + 0, 2) + = ((((((((c0 + c2) + c3) + c4) + c5) + c6) + c7) + c8) - c1) Highest counter ID seen: c8 diff --git a/tests/coverage/mcdc/if.cov-map b/tests/coverage/mcdc/if.cov-map index c0e7d08bb02..acb8aac63de 100644 --- a/tests/coverage/mcdc/if.cov-map +++ b/tests/coverage/mcdc/if.cov-map @@ -1,12 +1,14 @@ Function name: if::mcdc_check_a -Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 0f, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] +Raw bytes (68): 0x[01, 01, 06, 01, 05, 0b, 05, 01, 0d, 13, 05, 17, 0d, 01, 09, 08, 01, 0f, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 0d, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 06, 02, 0c, 02, 06, 0e, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 4 +Number of expressions: 6 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(2), rhs = Expression(0, Sub) -- expression 2 operands: lhs = Counter(3), rhs = Expression(3, Add) -- expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(1) +- expression 2 operands: lhs = Counter(0), rhs = Counter(3) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(1) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) +- expression 5 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) @@ -14,25 +16,27 @@ Number of file 0 mappings: 8 true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) -- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c3 - false = c2 -- Code(Counter(3)) at (prev + 0, 15) to (start + 2, 6) -- Code(Expression(3, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c2 + (c0 - c1)) -- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c3 + (c2 + (c0 - c1))) +- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) + true = c2 + false = c3 +- Code(Counter(2)) at (prev + 0, 15) to (start + 2, 6) +- Code(Expression(1, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c0 + c3) - c1) +- Code(Expression(3, Sub)) at (prev + 3, 1) to (start + 0, 2) + = (((c0 + c2) + c3) - c1) Highest counter ID seen: c3 Function name: if::mcdc_check_b -Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 17, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] +Raw bytes (68): 0x[01, 01, 06, 01, 05, 0b, 05, 01, 0d, 13, 05, 17, 0d, 01, 09, 08, 01, 17, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 0d, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 06, 02, 0c, 02, 06, 0e, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 4 +Number of expressions: 6 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(2), rhs = Expression(0, Sub) -- expression 2 operands: lhs = Counter(3), rhs = Expression(3, Add) -- expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(1) +- expression 2 operands: lhs = Counter(0), rhs = Counter(3) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(1) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) +- expression 5 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 23, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) @@ -40,25 +44,27 @@ Number of file 0 mappings: 8 true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) -- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c3 - false = c2 -- Code(Counter(3)) at (prev + 0, 15) to (start + 2, 6) -- Code(Expression(3, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c2 + (c0 - c1)) -- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c3 + (c2 + (c0 - c1))) +- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) + true = c2 + false = c3 +- Code(Counter(2)) at (prev + 0, 15) to (start + 2, 6) +- Code(Expression(1, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c0 + c3) - c1) +- Code(Expression(3, Sub)) at (prev + 3, 1) to (start + 0, 2) + = (((c0 + c2) + c3) - c1) Highest counter ID seen: c3 Function name: if::mcdc_check_both -Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 1f, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] +Raw bytes (68): 0x[01, 01, 06, 01, 05, 0b, 05, 01, 0d, 13, 05, 17, 0d, 01, 09, 08, 01, 1f, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 0d, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 06, 02, 0c, 02, 06, 0e, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 4 +Number of expressions: 6 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(2), rhs = Expression(0, Sub) -- expression 2 operands: lhs = Counter(3), rhs = Expression(3, Add) -- expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(1) +- expression 2 operands: lhs = Counter(0), rhs = Counter(3) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(1) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) +- expression 5 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 31, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) @@ -66,25 +72,27 @@ Number of file 0 mappings: 8 true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) -- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c3 - false = c2 -- Code(Counter(3)) at (prev + 0, 15) to (start + 2, 6) -- Code(Expression(3, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c2 + (c0 - c1)) -- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c3 + (c2 + (c0 - c1))) +- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) + true = c2 + false = c3 +- Code(Counter(2)) at (prev + 0, 15) to (start + 2, 6) +- Code(Expression(1, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c0 + c3) - c1) +- Code(Expression(3, Sub)) at (prev + 3, 1) to (start + 0, 2) + = (((c0 + c2) + c3) - c1) Highest counter ID seen: c3 Function name: if::mcdc_check_neither -Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 07, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] +Raw bytes (68): 0x[01, 01, 06, 01, 05, 0b, 05, 01, 0d, 13, 05, 17, 0d, 01, 09, 08, 01, 07, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 0d, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 06, 02, 0c, 02, 06, 0e, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 4 +Number of expressions: 6 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(2), rhs = Expression(0, Sub) -- expression 2 operands: lhs = Counter(3), rhs = Expression(3, Add) -- expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(1) +- expression 2 operands: lhs = Counter(0), rhs = Counter(3) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(1) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) +- expression 5 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) @@ -92,29 +100,32 @@ Number of file 0 mappings: 8 true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) -- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c3 - false = c2 -- Code(Counter(3)) at (prev + 0, 15) to (start + 2, 6) -- Code(Expression(3, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c2 + (c0 - c1)) -- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c3 + (c2 + (c0 - c1))) +- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) + true = c2 + false = c3 +- Code(Counter(2)) at (prev + 0, 15) to (start + 2, 6) +- Code(Expression(1, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c0 + c3) - c1) +- Code(Expression(3, Sub)) at (prev + 3, 1) to (start + 0, 2) + = (((c0 + c2) + c3) - c1) Highest counter ID seen: c3 Function name: if::mcdc_check_not_tree_decision -Raw bytes (87): 0x[01, 01, 08, 01, 05, 02, 09, 05, 09, 0d, 1e, 02, 09, 11, 1b, 0d, 1e, 02, 09, 0a, 01, 31, 01, 03, 0a, 28, 05, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 1e, 03, 02, 00, 00, 0e, 00, 0f, 0b, 00, 14, 00, 15, 30, 11, 0d, 02, 00, 00, 00, 14, 00, 15, 11, 00, 16, 02, 06, 1b, 02, 0c, 02, 06, 17, 03, 01, 00, 02] +Raw bytes (93): 0x[01, 01, 0b, 01, 05, 01, 2b, 05, 09, 05, 09, 17, 2b, 01, 11, 05, 09, 23, 2b, 27, 11, 01, 0d, 05, 09, 0a, 01, 31, 01, 03, 0a, 28, 05, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 2b, 00, 14, 00, 15, 30, 0d, 11, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 12, 02, 0c, 02, 06, 1e, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 8 +Number of expressions: 11 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(0, Sub), rhs = Counter(2) +- expression 1 operands: lhs = Counter(0), rhs = Expression(10, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(3), rhs = Expression(7, Sub) -- expression 4 operands: lhs = Expression(0, Sub), rhs = Counter(2) -- expression 5 operands: lhs = Counter(4), rhs = Expression(6, Add) -- expression 6 operands: lhs = Counter(3), rhs = Expression(7, Sub) -- expression 7 operands: lhs = Expression(0, Sub), rhs = Counter(2) +- expression 3 operands: lhs = Counter(1), rhs = Counter(2) +- expression 4 operands: lhs = Expression(5, Add), rhs = Expression(10, Add) +- expression 5 operands: lhs = Counter(0), rhs = Counter(4) +- expression 6 operands: lhs = Counter(1), rhs = Counter(2) +- expression 7 operands: lhs = Expression(8, Add), rhs = Expression(10, Add) +- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(4) +- expression 9 operands: lhs = Counter(0), rhs = Counter(3) +- expression 10 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 10 - Code(Counter(0)) at (prev + 49, 1) to (start + 3, 10) - MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21) @@ -123,34 +134,36 @@ Number of file 0 mappings: 10 false = (c0 - c1) - Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 15) = (c0 - c1) -- MCDCBranch { true: Counter(2), false: Expression(7, Sub), condition_id: 3, true_next_id: 2, false_next_id: 0 } at (prev + 0, 14) to (start + 0, 15) +- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 3, true_next_id: 2, false_next_id: 0 } at (prev + 0, 14) to (start + 0, 15) true = c2 - false = ((c0 - c1) - c2) -- Code(Expression(2, Add)) at (prev + 0, 20) to (start + 0, 21) + false = (c0 - (c1 + c2)) +- Code(Expression(10, Add)) at (prev + 0, 20) to (start + 0, 21) = (c1 + c2) -- MCDCBranch { true: Counter(4), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 20) to (start + 0, 21) - true = c4 - false = c3 -- Code(Counter(4)) at (prev + 0, 22) to (start + 2, 6) -- Code(Expression(6, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c3 + ((c0 - c1) - c2)) -- Code(Expression(5, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c4 + (c3 + ((c0 - c1) - c2))) +- MCDCBranch { true: Counter(3), false: Counter(4), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 20) to (start + 0, 21) + true = c3 + false = c4 +- Code(Counter(3)) at (prev + 0, 22) to (start + 2, 6) +- Code(Expression(4, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c0 + c4) - (c1 + c2)) +- Code(Expression(7, Sub)) at (prev + 3, 1) to (start + 0, 2) + = (((c0 + c3) + c4) - (c1 + c2)) Highest counter ID seen: c4 Function name: if::mcdc_check_tree_decision -Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 0d, 05, 0d, 0d, 11, 09, 02, 1b, 1f, 0d, 11, 09, 02, 0a, 01, 27, 01, 03, 09, 28, 04, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 0d, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 11, 09, 03, 00, 00, 00, 13, 00, 14, 1b, 00, 16, 02, 06, 1f, 02, 0c, 02, 06, 17, 03, 01, 00, 02] +Raw bytes (91): 0x[01, 01, 0a, 01, 05, 05, 09, 05, 09, 09, 0d, 17, 05, 01, 11, 1f, 05, 23, 11, 27, 0d, 01, 09, 0a, 01, 27, 01, 03, 09, 28, 04, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 11, 03, 00, 00, 00, 13, 00, 14, 0f, 00, 16, 02, 06, 12, 02, 0c, 02, 06, 1a, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 8 +Number of expressions: 10 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(3) -- expression 2 operands: lhs = Counter(1), rhs = Counter(3) -- expression 3 operands: lhs = Counter(3), rhs = Counter(4) -- expression 4 operands: lhs = Counter(2), rhs = Expression(0, Sub) -- expression 5 operands: lhs = Expression(6, Add), rhs = Expression(7, Add) -- expression 6 operands: lhs = Counter(3), rhs = Counter(4) -- expression 7 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 2 operands: lhs = Counter(1), rhs = Counter(2) +- expression 3 operands: lhs = Counter(2), rhs = Counter(3) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(1) +- expression 5 operands: lhs = Counter(0), rhs = Counter(4) +- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(1) +- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(4) +- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(3) +- expression 9 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 10 - Code(Counter(0)) at (prev + 39, 1) to (start + 3, 9) - MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21) @@ -158,40 +171,43 @@ Number of file 0 mappings: 10 true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 14) to (start + 0, 15) -- MCDCBranch { true: Counter(3), false: Expression(2, Sub), condition_id: 2, true_next_id: 0, false_next_id: 3 } at (prev + 0, 14) to (start + 0, 15) - true = c3 - false = (c1 - c3) +- MCDCBranch { true: Counter(2), false: Expression(2, Sub), condition_id: 2, true_next_id: 0, false_next_id: 3 } at (prev + 0, 14) to (start + 0, 15) + true = c2 + false = (c1 - c2) - Code(Expression(2, Sub)) at (prev + 0, 19) to (start + 0, 20) - = (c1 - c3) -- MCDCBranch { true: Counter(4), false: Counter(2), condition_id: 3, true_next_id: 0, false_next_id: 0 } at (prev + 0, 19) to (start + 0, 20) - true = c4 - false = c2 -- Code(Expression(6, Add)) at (prev + 0, 22) to (start + 2, 6) - = (c3 + c4) -- Code(Expression(7, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c2 + (c0 - c1)) -- Code(Expression(5, Add)) at (prev + 3, 1) to (start + 0, 2) - = ((c3 + c4) + (c2 + (c0 - c1))) + = (c1 - c2) +- MCDCBranch { true: Counter(3), false: Counter(4), condition_id: 3, true_next_id: 0, false_next_id: 0 } at (prev + 0, 19) to (start + 0, 20) + true = c3 + false = c4 +- Code(Expression(3, Add)) at (prev + 0, 22) to (start + 2, 6) + = (c2 + c3) +- Code(Expression(4, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c0 + c4) - c1) +- Code(Expression(6, Sub)) at (prev + 3, 1) to (start + 0, 2) + = ((((c0 + c2) + c3) + c4) - c1) Highest counter ID seen: c4 Function name: if::mcdc_nested_if -Raw bytes (124): 0x[01, 01, 0d, 01, 05, 02, 09, 05, 09, 1b, 15, 05, 09, 1b, 15, 05, 09, 11, 15, 02, 09, 2b, 32, 0d, 2f, 11, 15, 02, 09, 0e, 01, 3b, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 32, 02, 00, 00, 00, 0d, 00, 0e, 1b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 16, 15, 01, 02, 00, 00, 0c, 00, 0d, 16, 00, 11, 00, 12, 30, 0d, 11, 02, 00, 00, 00, 11, 00, 12, 0d, 00, 13, 02, 0a, 2f, 02, 09, 00, 0a, 32, 01, 0c, 02, 06, 27, 03, 01, 00, 02] +Raw bytes (130): 0x[01, 01, 10, 01, 05, 01, 3f, 05, 09, 05, 09, 3f, 0d, 05, 09, 3f, 0d, 05, 09, 0d, 15, 01, 3f, 05, 09, 33, 3f, 37, 15, 3b, 11, 01, 0d, 05, 09, 0e, 01, 3b, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 26, 02, 00, 00, 00, 0d, 00, 0e, 3f, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 1a, 0d, 01, 02, 00, 00, 0c, 00, 0d, 1a, 00, 11, 00, 12, 30, 11, 15, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 23, 02, 09, 00, 0a, 26, 01, 0c, 02, 06, 2e, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 13 +Number of expressions: 16 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(0, Sub), rhs = Counter(2) +- expression 1 operands: lhs = Counter(0), rhs = Expression(15, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Expression(6, Add), rhs = Counter(5) -- expression 4 operands: lhs = Counter(1), rhs = Counter(2) -- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(5) -- expression 6 operands: lhs = Counter(1), rhs = Counter(2) -- expression 7 operands: lhs = Counter(4), rhs = Counter(5) -- expression 8 operands: lhs = Expression(0, Sub), rhs = Counter(2) -- expression 9 operands: lhs = Expression(10, Add), rhs = Expression(12, Sub) -- expression 10 operands: lhs = Counter(3), rhs = Expression(11, Add) -- expression 11 operands: lhs = Counter(4), rhs = Counter(5) -- expression 12 operands: lhs = Expression(0, Sub), rhs = Counter(2) +- expression 3 operands: lhs = Counter(1), rhs = Counter(2) +- expression 4 operands: lhs = Expression(15, Add), rhs = Counter(3) +- expression 5 operands: lhs = Counter(1), rhs = Counter(2) +- expression 6 operands: lhs = Expression(15, Add), rhs = Counter(3) +- expression 7 operands: lhs = Counter(1), rhs = Counter(2) +- expression 8 operands: lhs = Counter(3), rhs = Counter(5) +- expression 9 operands: lhs = Counter(0), rhs = Expression(15, Add) +- expression 10 operands: lhs = Counter(1), rhs = Counter(2) +- expression 11 operands: lhs = Expression(12, Add), rhs = Expression(15, Add) +- expression 12 operands: lhs = Expression(13, Add), rhs = Counter(5) +- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(4) +- expression 14 operands: lhs = Counter(0), rhs = Counter(3) +- expression 15 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 14 - Code(Counter(0)) at (prev + 59, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) @@ -200,26 +216,26 @@ Number of file 0 mappings: 14 false = (c0 - c1) - Code(Expression(0, Sub)) at (prev + 0, 13) to (start + 0, 14) = (c0 - c1) -- MCDCBranch { true: Counter(2), false: Expression(12, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) +- MCDCBranch { true: Counter(2), false: Expression(9, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) true = c2 - false = ((c0 - c1) - c2) -- Code(Expression(6, Add)) at (prev + 1, 9) to (start + 1, 13) + false = (c0 - (c1 + c2)) +- Code(Expression(15, Add)) at (prev + 1, 9) to (start + 1, 13) = (c1 + c2) - MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 12) to (start + 0, 18) -- MCDCBranch { true: Expression(5, Sub), false: Counter(5), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 12) to (start + 0, 13) - true = ((c1 + c2) - c5) +- MCDCBranch { true: Expression(6, Sub), false: Counter(3), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 12) to (start + 0, 13) + true = ((c1 + c2) - c3) + false = c3 +- Code(Expression(6, Sub)) at (prev + 0, 17) to (start + 0, 18) + = ((c1 + c2) - c3) +- MCDCBranch { true: Counter(4), false: Counter(5), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 17) to (start + 0, 18) + true = c4 false = c5 -- Code(Expression(5, Sub)) at (prev + 0, 17) to (start + 0, 18) - = ((c1 + c2) - c5) -- MCDCBranch { true: Counter(3), false: Counter(4), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 17) to (start + 0, 18) - true = c3 - false = c4 -- Code(Counter(3)) at (prev + 0, 19) to (start + 2, 10) -- Code(Expression(11, Add)) at (prev + 2, 9) to (start + 0, 10) - = (c4 + c5) -- Code(Expression(12, Sub)) at (prev + 1, 12) to (start + 2, 6) - = ((c0 - c1) - c2) -- Code(Expression(9, Add)) at (prev + 3, 1) to (start + 0, 2) - = ((c3 + (c4 + c5)) + ((c0 - c1) - c2)) +- Code(Counter(4)) at (prev + 0, 19) to (start + 2, 10) +- Code(Expression(8, Add)) at (prev + 2, 9) to (start + 0, 10) + = (c3 + c5) +- Code(Expression(9, Sub)) at (prev + 1, 12) to (start + 2, 6) + = (c0 - (c1 + c2)) +- Code(Expression(11, Sub)) at (prev + 3, 1) to (start + 0, 2) + = ((((c0 + c3) + c4) + c5) - (c1 + c2)) Highest counter ID seen: c5 diff --git a/tests/coverage/mcdc/inlined_expressions.cov-map b/tests/coverage/mcdc/inlined_expressions.cov-map index 4f44e0f2b85..92ec60dc23c 100644 --- a/tests/coverage/mcdc/inlined_expressions.cov-map +++ b/tests/coverage/mcdc/inlined_expressions.cov-map @@ -1,11 +1,12 @@ Function name: inlined_expressions::inlined_instance -Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 08, 01, 01, 06, 28, 03, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 0d, 02, 00, 00, 00, 0a, 00, 0b, 07, 01, 01, 00, 02] +Raw bytes (54): 0x[01, 01, 04, 01, 05, 0b, 05, 0f, 0d, 01, 09, 06, 01, 08, 01, 01, 06, 28, 03, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 0d, 02, 00, 00, 00, 0a, 00, 0b, 06, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 3 +Number of expressions: 4 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(0, Sub) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(1) +- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(3) +- expression 3 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 8, 1) to (start + 1, 6) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 5) to (start + 0, 11) @@ -16,7 +17,7 @@ Number of file 0 mappings: 6 - MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 10) to (start + 0, 11) true = c2 false = c3 -- Code(Expression(1, Add)) at (prev + 1, 1) to (start + 0, 2) - = ((c2 + c3) + (c0 - c1)) +- Code(Expression(1, Sub)) at (prev + 1, 1) to (start + 0, 2) + = (((c0 + c2) + c3) - c1) Highest counter ID seen: c3 diff --git a/tests/coverage/mcdc/nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map index 3bed49e7a12..72daecabc77 100644 --- a/tests/coverage/mcdc/nested_if.cov-map +++ b/tests/coverage/mcdc/nested_if.cov-map @@ -1,205 +1,213 @@ Function name: nested_if::doubly_nested_if_in_condition -Raw bytes (168): 0x[01, 01, 0e, 01, 05, 05, 11, 05, 11, 26, 19, 05, 11, 19, 1d, 19, 1d, 1d, 22, 26, 19, 05, 11, 11, 15, 09, 02, 0d, 37, 09, 02, 14, 01, 0f, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 11, 26, 01, 00, 02, 00, 10, 00, 11, 30, 15, 21, 02, 00, 00, 00, 15, 00, 36, 26, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 19, 22, 01, 02, 00, 00, 18, 00, 19, 19, 00, 1d, 00, 1e, 30, 1a, 1d, 02, 00, 00, 00, 1d, 00, 1e, 1a, 00, 21, 00, 25, 1f, 00, 2f, 00, 34, 2b, 00, 39, 00, 3e, 21, 00, 48, 00, 4c, 0d, 00, 4f, 02, 06, 37, 02, 0c, 02, 06, 33, 03, 01, 00, 02] +Raw bytes (172): 0x[01, 01, 10, 01, 05, 05, 09, 05, 09, 05, 27, 09, 19, 19, 1d, 19, 1d, 23, 27, 05, 1d, 09, 19, 09, 0d, 33, 05, 01, 15, 3b, 05, 3f, 15, 01, 11, 14, 01, 0f, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 15, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 21, 02, 00, 00, 00, 15, 00, 36, 0a, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 19, 0e, 01, 02, 00, 00, 18, 00, 19, 19, 00, 1d, 00, 1e, 30, 1a, 1d, 02, 00, 00, 00, 1d, 00, 1e, 1a, 00, 21, 00, 25, 1e, 00, 2f, 00, 34, 2b, 00, 39, 00, 3e, 21, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 2e, 02, 0c, 02, 06, 36, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 14 +Number of expressions: 16 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(4) -- expression 2 operands: lhs = Counter(1), rhs = Counter(4) -- expression 3 operands: lhs = Expression(9, Sub), rhs = Counter(6) -- expression 4 operands: lhs = Counter(1), rhs = Counter(4) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 2 operands: lhs = Counter(1), rhs = Counter(2) +- expression 3 operands: lhs = Counter(1), rhs = Expression(9, Add) +- expression 4 operands: lhs = Counter(2), rhs = Counter(6) - expression 5 operands: lhs = Counter(6), rhs = Counter(7) - expression 6 operands: lhs = Counter(6), rhs = Counter(7) -- expression 7 operands: lhs = Counter(7), rhs = Expression(8, Sub) -- expression 8 operands: lhs = Expression(9, Sub), rhs = Counter(6) -- expression 9 operands: lhs = Counter(1), rhs = Counter(4) -- expression 10 operands: lhs = Counter(4), rhs = Counter(5) -- expression 11 operands: lhs = Counter(2), rhs = Expression(0, Sub) -- expression 12 operands: lhs = Counter(3), rhs = Expression(13, Add) -- expression 13 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 7 operands: lhs = Expression(8, Add), rhs = Expression(9, Add) +- expression 8 operands: lhs = Counter(1), rhs = Counter(7) +- expression 9 operands: lhs = Counter(2), rhs = Counter(6) +- expression 10 operands: lhs = Counter(2), rhs = Counter(3) +- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(1) +- expression 12 operands: lhs = Counter(0), rhs = Counter(5) +- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(1) +- expression 14 operands: lhs = Expression(15, Add), rhs = Counter(5) +- expression 15 operands: lhs = Counter(0), rhs = Counter(4) Number of file 0 mappings: 20 - Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 78) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) -- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 78) - true = c3 - false = c2 +- MCDCBranch { true: Counter(4), false: Counter(5), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 78) + true = c4 + false = c5 - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) - MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 54) -- MCDCBranch { true: Counter(4), false: Expression(9, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) - true = c4 - false = (c1 - c4) -- MCDCBranch { true: Counter(5), false: Counter(8), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 54) - true = c5 +- MCDCBranch { true: Counter(2), false: Expression(2, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) + true = c2 + false = (c1 - c2) +- MCDCBranch { true: Counter(3), false: Counter(8), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 54) + true = c3 false = c8 -- Code(Expression(9, Sub)) at (prev + 0, 24) to (start + 0, 25) - = (c1 - c4) +- Code(Expression(2, Sub)) at (prev + 0, 24) to (start + 0, 25) + = (c1 - c2) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 24) to (start + 0, 30) -- MCDCBranch { true: Counter(6), false: Expression(8, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 24) to (start + 0, 25) +- MCDCBranch { true: Counter(6), false: Expression(3, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 24) to (start + 0, 25) true = c6 - false = ((c1 - c4) - c6) + false = (c1 - (c2 + c6)) - Code(Counter(6)) at (prev + 0, 29) to (start + 0, 30) - MCDCBranch { true: Expression(6, Sub), false: Counter(7), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 29) to (start + 0, 30) true = (c6 - c7) false = c7 - Code(Expression(6, Sub)) at (prev + 0, 33) to (start + 0, 37) = (c6 - c7) -- Code(Expression(7, Add)) at (prev + 0, 47) to (start + 0, 52) - = (c7 + ((c1 - c4) - c6)) +- Code(Expression(7, Sub)) at (prev + 0, 47) to (start + 0, 52) + = ((c1 + c7) - (c2 + c6)) - Code(Expression(10, Add)) at (prev + 0, 57) to (start + 0, 62) - = (c4 + c5) + = (c2 + c3) - Code(Counter(8)) at (prev + 0, 72) to (start + 0, 76) -- Code(Counter(3)) at (prev + 0, 79) to (start + 2, 6) -- Code(Expression(13, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c2 + (c0 - c1)) -- Code(Expression(12, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c3 + (c2 + (c0 - c1))) +- Code(Counter(4)) at (prev + 0, 79) to (start + 2, 6) +- Code(Expression(11, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c0 + c5) - c1) +- Code(Expression(13, Sub)) at (prev + 3, 1) to (start + 0, 2) + = (((c0 + c4) + c5) - c1) Highest counter ID seen: c8 Function name: nested_if::nested_if_in_condition -Raw bytes (120): 0x[01, 01, 0b, 01, 05, 05, 11, 05, 11, 1e, 15, 05, 11, 11, 15, 1e, 15, 05, 11, 09, 02, 0d, 2b, 09, 02, 0e, 01, 07, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 11, 1e, 01, 00, 02, 00, 10, 00, 11, 1e, 00, 15, 00, 16, 30, 15, 1a, 02, 00, 00, 00, 15, 00, 16, 17, 00, 19, 00, 1d, 1a, 00, 27, 00, 2c, 0d, 00, 2f, 02, 06, 2b, 02, 0c, 02, 06, 27, 03, 01, 00, 02] +Raw bytes (124): 0x[01, 01, 0d, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 05, 1f, 09, 0d, 27, 05, 01, 15, 2f, 05, 33, 15, 01, 11, 0e, 01, 07, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 15, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 0a, 00, 15, 00, 16, 30, 0d, 1a, 02, 00, 00, 00, 15, 00, 16, 1f, 00, 19, 00, 1d, 1a, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 22, 02, 0c, 02, 06, 2a, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 11 +Number of expressions: 13 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(4) -- expression 2 operands: lhs = Counter(1), rhs = Counter(4) -- expression 3 operands: lhs = Expression(7, Sub), rhs = Counter(5) -- expression 4 operands: lhs = Counter(1), rhs = Counter(4) -- expression 5 operands: lhs = Counter(4), rhs = Counter(5) -- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(5) -- expression 7 operands: lhs = Counter(1), rhs = Counter(4) -- expression 8 operands: lhs = Counter(2), rhs = Expression(0, Sub) -- expression 9 operands: lhs = Counter(3), rhs = Expression(10, Add) -- expression 10 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 2 operands: lhs = Counter(1), rhs = Counter(2) +- expression 3 operands: lhs = Counter(1), rhs = Expression(7, Add) +- expression 4 operands: lhs = Counter(2), rhs = Counter(3) +- expression 5 operands: lhs = Counter(2), rhs = Counter(3) +- expression 6 operands: lhs = Counter(1), rhs = Expression(7, Add) +- expression 7 operands: lhs = Counter(2), rhs = Counter(3) +- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(1) +- expression 9 operands: lhs = Counter(0), rhs = Counter(5) +- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(1) +- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(5) +- expression 12 operands: lhs = Counter(0), rhs = Counter(4) Number of file 0 mappings: 14 - Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 46) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) -- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 46) - true = c3 - false = c2 +- MCDCBranch { true: Counter(4), false: Counter(5), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 46) + true = c4 + false = c5 - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 22) -- MCDCBranch { true: Counter(4), false: Expression(7, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) - true = c4 - false = (c1 - c4) -- Code(Expression(7, Sub)) at (prev + 0, 21) to (start + 0, 22) - = (c1 - c4) -- MCDCBranch { true: Counter(5), false: Expression(6, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22) - true = c5 - false = ((c1 - c4) - c5) -- Code(Expression(5, Add)) at (prev + 0, 25) to (start + 0, 29) - = (c4 + c5) +- MCDCBranch { true: Counter(2), false: Expression(2, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) + true = c2 + false = (c1 - c2) +- Code(Expression(2, Sub)) at (prev + 0, 21) to (start + 0, 22) + = (c1 - c2) +- MCDCBranch { true: Counter(3), false: Expression(6, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22) + true = c3 + false = (c1 - (c2 + c3)) +- Code(Expression(7, Add)) at (prev + 0, 25) to (start + 0, 29) + = (c2 + c3) - Code(Expression(6, Sub)) at (prev + 0, 39) to (start + 0, 44) - = ((c1 - c4) - c5) -- Code(Counter(3)) at (prev + 0, 47) to (start + 2, 6) -- Code(Expression(10, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c2 + (c0 - c1)) -- Code(Expression(9, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c3 + (c2 + (c0 - c1))) + = (c1 - (c2 + c3)) +- Code(Counter(4)) at (prev + 0, 47) to (start + 2, 6) +- Code(Expression(8, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c0 + c5) - c1) +- Code(Expression(10, Sub)) at (prev + 3, 1) to (start + 0, 2) + = (((c0 + c4) + c5) - c1) Highest counter ID seen: c5 Function name: nested_if::nested_in_then_block_in_condition -Raw bytes (176): 0x[01, 01, 12, 01, 05, 05, 11, 05, 11, 3a, 15, 05, 11, 11, 15, 33, 19, 11, 15, 19, 1d, 19, 1d, 1d, 2e, 33, 19, 11, 15, 3a, 15, 05, 11, 09, 02, 0d, 47, 09, 02, 14, 01, 22, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 11, 3a, 01, 00, 02, 00, 10, 00, 11, 3a, 00, 15, 00, 16, 30, 15, 36, 02, 00, 00, 00, 15, 00, 16, 33, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 19, 2e, 01, 02, 00, 00, 1c, 00, 1d, 19, 00, 21, 00, 22, 30, 26, 1d, 02, 00, 00, 00, 21, 00, 22, 26, 00, 25, 00, 29, 2b, 00, 33, 00, 38, 36, 00, 44, 00, 49, 0d, 00, 4c, 02, 06, 47, 02, 0c, 02, 06, 43, 03, 01, 00, 02] +Raw bytes (180): 0x[01, 01, 14, 01, 05, 05, 09, 05, 09, 05, 3b, 09, 0d, 09, 0d, 3b, 11, 09, 0d, 11, 15, 11, 15, 2f, 11, 3b, 15, 09, 0d, 05, 3b, 09, 0d, 43, 05, 01, 1d, 4b, 05, 4f, 1d, 01, 19, 14, 01, 22, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 1d, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 0a, 00, 15, 00, 16, 30, 0d, 36, 02, 00, 00, 00, 15, 00, 16, 3b, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1a, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 26, 15, 02, 00, 00, 00, 21, 00, 22, 26, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 36, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3e, 02, 0c, 02, 06, 46, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 18 +Number of expressions: 20 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(4) -- expression 2 operands: lhs = Counter(1), rhs = Counter(4) -- expression 3 operands: lhs = Expression(14, Sub), rhs = Counter(5) -- expression 4 operands: lhs = Counter(1), rhs = Counter(4) -- expression 5 operands: lhs = Counter(4), rhs = Counter(5) -- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(6) -- expression 7 operands: lhs = Counter(4), rhs = Counter(5) -- expression 8 operands: lhs = Counter(6), rhs = Counter(7) -- expression 9 operands: lhs = Counter(6), rhs = Counter(7) -- expression 10 operands: lhs = Counter(7), rhs = Expression(11, Sub) -- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(6) -- expression 12 operands: lhs = Counter(4), rhs = Counter(5) -- expression 13 operands: lhs = Expression(14, Sub), rhs = Counter(5) -- expression 14 operands: lhs = Counter(1), rhs = Counter(4) -- expression 15 operands: lhs = Counter(2), rhs = Expression(0, Sub) -- expression 16 operands: lhs = Counter(3), rhs = Expression(17, Add) -- expression 17 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 2 operands: lhs = Counter(1), rhs = Counter(2) +- expression 3 operands: lhs = Counter(1), rhs = Expression(14, Add) +- expression 4 operands: lhs = Counter(2), rhs = Counter(3) +- expression 5 operands: lhs = Counter(2), rhs = Counter(3) +- expression 6 operands: lhs = Expression(14, Add), rhs = Counter(4) +- expression 7 operands: lhs = Counter(2), rhs = Counter(3) +- expression 8 operands: lhs = Counter(4), rhs = Counter(5) +- expression 9 operands: lhs = Counter(4), rhs = Counter(5) +- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(4) +- expression 11 operands: lhs = Expression(14, Add), rhs = Counter(5) +- expression 12 operands: lhs = Counter(2), rhs = Counter(3) +- expression 13 operands: lhs = Counter(1), rhs = Expression(14, Add) +- expression 14 operands: lhs = Counter(2), rhs = Counter(3) +- expression 15 operands: lhs = Expression(16, Add), rhs = Counter(1) +- expression 16 operands: lhs = Counter(0), rhs = Counter(7) +- expression 17 operands: lhs = Expression(18, Add), rhs = Counter(1) +- expression 18 operands: lhs = Expression(19, Add), rhs = Counter(7) +- expression 19 operands: lhs = Counter(0), rhs = Counter(6) Number of file 0 mappings: 20 - Code(Counter(0)) at (prev + 34, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 75) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) -- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 75) - true = c3 - false = c2 +- MCDCBranch { true: Counter(6), false: Counter(7), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 75) + true = c6 + false = c7 - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 22) -- MCDCBranch { true: Counter(4), false: Expression(14, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) - true = c4 - false = (c1 - c4) -- Code(Expression(14, Sub)) at (prev + 0, 21) to (start + 0, 22) - = (c1 - c4) -- MCDCBranch { true: Counter(5), false: Expression(13, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22) - true = c5 - false = ((c1 - c4) - c5) -- Code(Expression(12, Add)) at (prev + 0, 28) to (start + 0, 29) - = (c4 + c5) +- MCDCBranch { true: Counter(2), false: Expression(2, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) + true = c2 + false = (c1 - c2) +- Code(Expression(2, Sub)) at (prev + 0, 21) to (start + 0, 22) + = (c1 - c2) +- MCDCBranch { true: Counter(3), false: Expression(13, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22) + true = c3 + false = (c1 - (c2 + c3)) +- Code(Expression(14, Add)) at (prev + 0, 28) to (start + 0, 29) + = (c2 + c3) - MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 28) to (start + 0, 34) -- MCDCBranch { true: Counter(6), false: Expression(11, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29) - true = c6 - false = ((c4 + c5) - c6) -- Code(Counter(6)) at (prev + 0, 33) to (start + 0, 34) -- MCDCBranch { true: Expression(9, Sub), false: Counter(7), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34) - true = (c6 - c7) - false = c7 +- MCDCBranch { true: Counter(4), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29) + true = c4 + false = ((c2 + c3) - c4) +- Code(Counter(4)) at (prev + 0, 33) to (start + 0, 34) +- MCDCBranch { true: Expression(9, Sub), false: Counter(5), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34) + true = (c4 - c5) + false = c5 - Code(Expression(9, Sub)) at (prev + 0, 37) to (start + 0, 41) - = (c6 - c7) -- Code(Expression(10, Add)) at (prev + 0, 51) to (start + 0, 56) - = (c7 + ((c4 + c5) - c6)) + = (c4 - c5) +- Code(Expression(10, Sub)) at (prev + 0, 51) to (start + 0, 56) + = (((c2 + c3) + c5) - c4) - Code(Expression(13, Sub)) at (prev + 0, 68) to (start + 0, 73) - = ((c1 - c4) - c5) -- Code(Counter(3)) at (prev + 0, 76) to (start + 2, 6) -- Code(Expression(17, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c2 + (c0 - c1)) -- Code(Expression(16, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c3 + (c2 + (c0 - c1))) + = (c1 - (c2 + c3)) +- Code(Counter(6)) at (prev + 0, 76) to (start + 2, 6) +- Code(Expression(15, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c0 + c7) - c1) +- Code(Expression(17, Sub)) at (prev + 3, 1) to (start + 0, 2) + = (((c0 + c6) + c7) - c1) Highest counter ID seen: c7 Function name: nested_if::nested_single_condition_decision -Raw bytes (85): 0x[01, 01, 06, 01, 05, 05, 11, 05, 11, 09, 02, 0d, 17, 09, 02, 0b, 01, 17, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 11, 0a, 00, 10, 00, 11, 11, 00, 14, 00, 19, 0a, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 17, 02, 0c, 02, 06, 13, 03, 01, 00, 02] +Raw bytes (89): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 13, 05, 01, 11, 1b, 05, 1f, 11, 01, 0d, 0b, 01, 17, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 11, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0a, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0a, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 0e, 02, 0c, 02, 06, 16, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 6 +Number of expressions: 8 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(4) -- expression 2 operands: lhs = Counter(1), rhs = Counter(4) -- expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub) -- expression 4 operands: lhs = Counter(3), rhs = Expression(5, Add) -- expression 5 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 2 operands: lhs = Counter(1), rhs = Counter(2) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(1) +- expression 4 operands: lhs = Counter(0), rhs = Counter(4) +- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(1) +- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4) +- expression 7 operands: lhs = Counter(0), rhs = Counter(3) Number of file 0 mappings: 11 - Code(Counter(0)) at (prev + 23, 1) to (start + 4, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 4, 8) to (start + 0, 41) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 false = (c0 - c1) -- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 41) +- MCDCBranch { true: Counter(3), false: Counter(4), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 41) true = c3 - false = c2 + false = c4 - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) -- Branch { true: Counter(4), false: Expression(2, Sub) } at (prev + 0, 16) to (start + 0, 17) - true = c4 - false = (c1 - c4) -- Code(Counter(4)) at (prev + 0, 20) to (start + 0, 25) +- Branch { true: Counter(2), false: Expression(2, Sub) } at (prev + 0, 16) to (start + 0, 17) + true = c2 + false = (c1 - c2) +- Code(Counter(2)) at (prev + 0, 20) to (start + 0, 25) - Code(Expression(2, Sub)) at (prev + 0, 35) to (start + 0, 39) - = (c1 - c4) + = (c1 - c2) - Code(Counter(3)) at (prev + 0, 42) to (start + 2, 6) -- Code(Expression(5, Add)) at (prev + 2, 12) to (start + 2, 6) - = (c2 + (c0 - c1)) -- Code(Expression(4, Add)) at (prev + 3, 1) to (start + 0, 2) - = (c3 + (c2 + (c0 - c1))) +- Code(Expression(3, Sub)) at (prev + 2, 12) to (start + 2, 6) + = ((c0 + c4) - c1) +- Code(Expression(5, Sub)) at (prev + 3, 1) to (start + 0, 2) + = (((c0 + c3) + c4) - c1) Highest counter ID seen: c4 diff --git a/tests/coverage/mcdc/non_control_flow.cov-map b/tests/coverage/mcdc/non_control_flow.cov-map index 677e31e404e..0edeff9a586 100644 --- a/tests/coverage/mcdc/non_control_flow.cov-map +++ b/tests/coverage/mcdc/non_control_flow.cov-map @@ -1,67 +1,65 @@ Function name: non_control_flow::assign_3 -Raw bytes (89): 0x[01, 01, 09, 05, 07, 0b, 11, 09, 0d, 01, 05, 01, 05, 22, 11, 01, 05, 22, 11, 01, 05, 0a, 01, 16, 01, 00, 28, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 22, 01, 00, 02, 00, 0d, 00, 0e, 22, 00, 12, 00, 13, 30, 1e, 11, 02, 03, 00, 00, 12, 00, 13, 1e, 00, 17, 00, 18, 30, 09, 0d, 03, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02] +Raw bytes (89): 0x[01, 01, 09, 07, 11, 0b, 0d, 05, 09, 01, 05, 01, 05, 01, 23, 05, 11, 01, 23, 05, 11, 0a, 01, 16, 01, 00, 28, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 12, 01, 00, 02, 00, 0d, 00, 0e, 12, 00, 12, 00, 13, 30, 1e, 11, 02, 03, 00, 00, 12, 00, 13, 1e, 00, 17, 00, 18, 30, 09, 0d, 03, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 9 -- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add) -- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(4) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3) +- expression 2 operands: lhs = Counter(1), rhs = Counter(2) - expression 3 operands: lhs = Counter(0), rhs = Counter(1) - expression 4 operands: lhs = Counter(0), rhs = Counter(1) -- expression 5 operands: lhs = Expression(8, Sub), rhs = Counter(4) -- expression 6 operands: lhs = Counter(0), rhs = Counter(1) -- expression 7 operands: lhs = Expression(8, Sub), rhs = Counter(4) -- expression 8 operands: lhs = Counter(0), rhs = Counter(1) +- expression 5 operands: lhs = Counter(0), rhs = Expression(8, Add) +- expression 6 operands: lhs = Counter(1), rhs = Counter(4) +- expression 7 operands: lhs = Counter(0), rhs = Expression(8, Add) +- expression 8 operands: lhs = Counter(1), rhs = Counter(4) Number of file 0 mappings: 10 - Code(Counter(0)) at (prev + 22, 1) to (start + 0, 40) - Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) - = (c1 + ((c2 + c3) + c4)) + = (((c1 + c2) + c3) + c4) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24) -- MCDCBranch { true: Counter(1), false: Expression(8, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14) +- MCDCBranch { true: Counter(1), false: Expression(4, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14) true = c1 false = (c0 - c1) -- Code(Expression(8, Sub)) at (prev + 0, 18) to (start + 0, 19) +- Code(Expression(4, Sub)) at (prev + 0, 18) to (start + 0, 19) = (c0 - c1) - MCDCBranch { true: Expression(7, Sub), false: Counter(4), condition_id: 2, true_next_id: 3, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) - true = ((c0 - c1) - c4) + true = (c0 - (c1 + c4)) false = c4 - Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 24) - = ((c0 - c1) - c4) + = (c0 - (c1 + c4)) - MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 3, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) true = c2 false = c3 - Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) - = (c1 + ((c2 + c3) + c4)) + = (((c1 + c2) + c3) + c4) Highest counter ID seen: c4 Function name: non_control_flow::assign_3_bis -Raw bytes (85): 0x[01, 01, 07, 07, 11, 09, 0d, 01, 05, 05, 09, 16, 1a, 05, 09, 01, 05, 0a, 01, 1b, 01, 00, 2c, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 1a, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 16, 03, 00, 02, 00, 12, 00, 13, 13, 00, 17, 00, 18, 30, 0d, 11, 02, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02] +Raw bytes (81): 0x[01, 01, 05, 07, 11, 09, 0d, 01, 05, 05, 09, 01, 09, 0a, 01, 1b, 01, 00, 2c, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 0a, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 0e, 03, 00, 02, 00, 12, 00, 13, 12, 00, 17, 00, 18, 30, 0d, 11, 02, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 7 +Number of expressions: 5 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(4) - expression 1 operands: lhs = Counter(2), rhs = Counter(3) - expression 2 operands: lhs = Counter(0), rhs = Counter(1) - expression 3 operands: lhs = Counter(1), rhs = Counter(2) -- expression 4 operands: lhs = Expression(5, Sub), rhs = Expression(6, Sub) -- expression 5 operands: lhs = Counter(1), rhs = Counter(2) -- expression 6 operands: lhs = Counter(0), rhs = Counter(1) +- expression 4 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 10 - Code(Counter(0)) at (prev + 27, 1) to (start + 0, 44) - Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) = ((c2 + c3) + c4) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24) -- MCDCBranch { true: Counter(1), false: Expression(6, Sub), condition_id: 1, true_next_id: 3, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14) +- MCDCBranch { true: Counter(1), false: Expression(2, Sub), condition_id: 1, true_next_id: 3, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14) true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) -- MCDCBranch { true: Counter(2), false: Expression(5, Sub), condition_id: 3, true_next_id: 0, false_next_id: 2 } at (prev + 0, 18) to (start + 0, 19) +- MCDCBranch { true: Counter(2), false: Expression(3, Sub), condition_id: 3, true_next_id: 0, false_next_id: 2 } at (prev + 0, 18) to (start + 0, 19) true = c2 false = (c1 - c2) -- Code(Expression(4, Add)) at (prev + 0, 23) to (start + 0, 24) - = ((c1 - c2) + (c0 - c1)) +- Code(Expression(4, Sub)) at (prev + 0, 23) to (start + 0, 24) + = (c0 - c2) - MCDCBranch { true: Counter(3), false: Counter(4), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) true = c3 false = c4 @@ -70,18 +68,18 @@ Number of file 0 mappings: 10 Highest counter ID seen: c4 Function name: non_control_flow::assign_and -Raw bytes (64): 0x[01, 01, 04, 07, 0e, 09, 0d, 01, 05, 01, 05, 08, 01, 0c, 01, 00, 21, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02] +Raw bytes (64): 0x[01, 01, 04, 07, 05, 0b, 0d, 01, 09, 01, 05, 08, 01, 0c, 01, 00, 21, 02, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 02, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 -- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(3, Sub) -- expression 1 operands: lhs = Counter(2), rhs = Counter(3) -- expression 2 operands: lhs = Counter(0), rhs = Counter(1) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(1) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3) +- expression 2 operands: lhs = Counter(0), rhs = Counter(2) - expression 3 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 12, 1) to (start + 0, 33) -- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) - = ((c2 + c3) + (c0 - c1)) +- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10) + = (((c0 + c2) + c3) - c1) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19) - MCDCBranch { true: Counter(1), false: Expression(3, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) @@ -91,8 +89,8 @@ Number of file 0 mappings: 8 - MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) true = c2 false = c3 -- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) - = ((c2 + c3) + (c0 - c1)) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 1, 2) + = (((c0 + c2) + c3) - c1) Highest counter ID seen: c3 Function name: non_control_flow::assign_or @@ -132,13 +130,14 @@ Number of file 0 mappings: 1 Highest counter ID seen: c0 Function name: non_control_flow::func_call -Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 29, 01, 01, 0a, 28, 03, 02, 01, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 0d, 02, 00, 00, 00, 0e, 00, 0f, 07, 01, 01, 00, 02] +Raw bytes (54): 0x[01, 01, 04, 01, 05, 0b, 05, 0f, 0d, 01, 09, 06, 01, 29, 01, 01, 0a, 28, 03, 02, 01, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 0d, 02, 00, 00, 00, 0e, 00, 0f, 06, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 3 +Number of expressions: 4 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(0, Sub) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(1) +- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(3) +- expression 3 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 41, 1) to (start + 1, 10) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 9) to (start + 0, 15) @@ -149,63 +148,63 @@ Number of file 0 mappings: 6 - MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 14) to (start + 0, 15) true = c2 false = c3 -- Code(Expression(1, Add)) at (prev + 1, 1) to (start + 0, 2) - = ((c2 + c3) + (c0 - c1)) +- Code(Expression(1, Sub)) at (prev + 1, 1) to (start + 0, 2) + = (((c0 + c2) + c3) - c1) Highest counter ID seen: c3 Function name: non_control_flow::right_comb_tree -Raw bytes (139): 0x[01, 01, 13, 07, 1a, 0b, 19, 0f, 15, 13, 11, 09, 0d, 01, 05, 01, 05, 05, 19, 05, 19, 4a, 15, 05, 19, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 0e, 01, 20, 01, 00, 41, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 1a, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 4a, 19, 02, 03, 00, 00, 13, 00, 14, 4a, 00, 19, 00, 1a, 30, 46, 15, 03, 04, 00, 00, 19, 00, 1a, 46, 00, 1f, 00, 20, 30, 42, 11, 04, 05, 00, 00, 1f, 00, 20, 42, 00, 24, 00, 27, 30, 09, 0d, 05, 00, 00, 00, 24, 00, 27, 03, 01, 05, 01, 02] +Raw bytes (139): 0x[01, 01, 13, 07, 05, 0b, 19, 0f, 15, 13, 11, 17, 0d, 01, 09, 01, 05, 05, 09, 05, 09, 05, 4b, 09, 0d, 05, 4b, 09, 0d, 05, 47, 4b, 11, 09, 0d, 05, 47, 4b, 11, 09, 0d, 0e, 01, 20, 01, 00, 41, 02, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 1a, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 22, 09, 02, 03, 00, 00, 13, 00, 14, 22, 00, 19, 00, 1a, 30, 2e, 0d, 03, 04, 00, 00, 19, 00, 1a, 2e, 00, 1f, 00, 20, 30, 42, 11, 04, 05, 00, 00, 1f, 00, 20, 42, 00, 24, 00, 27, 30, 15, 19, 05, 00, 00, 00, 24, 00, 27, 02, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 19 -- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(6, Sub) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(1) - expression 1 operands: lhs = Expression(2, Add), rhs = Counter(6) - expression 2 operands: lhs = Expression(3, Add), rhs = Counter(5) - expression 3 operands: lhs = Expression(4, Add), rhs = Counter(4) -- expression 4 operands: lhs = Counter(2), rhs = Counter(3) -- expression 5 operands: lhs = Counter(0), rhs = Counter(1) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) +- expression 5 operands: lhs = Counter(0), rhs = Counter(2) - expression 6 operands: lhs = Counter(0), rhs = Counter(1) -- expression 7 operands: lhs = Counter(1), rhs = Counter(6) -- expression 8 operands: lhs = Counter(1), rhs = Counter(6) -- expression 9 operands: lhs = Expression(18, Sub), rhs = Counter(5) -- expression 10 operands: lhs = Counter(1), rhs = Counter(6) -- expression 11 operands: lhs = Expression(18, Sub), rhs = Counter(5) -- expression 12 operands: lhs = Counter(1), rhs = Counter(6) -- expression 13 operands: lhs = Expression(17, Sub), rhs = Counter(4) -- expression 14 operands: lhs = Expression(18, Sub), rhs = Counter(5) -- expression 15 operands: lhs = Counter(1), rhs = Counter(6) -- expression 16 operands: lhs = Expression(17, Sub), rhs = Counter(4) -- expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(5) -- expression 18 operands: lhs = Counter(1), rhs = Counter(6) +- expression 7 operands: lhs = Counter(1), rhs = Counter(2) +- expression 8 operands: lhs = Counter(1), rhs = Counter(2) +- expression 9 operands: lhs = Counter(1), rhs = Expression(18, Add) +- expression 10 operands: lhs = Counter(2), rhs = Counter(3) +- expression 11 operands: lhs = Counter(1), rhs = Expression(18, Add) +- expression 12 operands: lhs = Counter(2), rhs = Counter(3) +- expression 13 operands: lhs = Counter(1), rhs = Expression(17, Add) +- expression 14 operands: lhs = Expression(18, Add), rhs = Counter(4) +- expression 15 operands: lhs = Counter(2), rhs = Counter(3) +- expression 16 operands: lhs = Counter(1), rhs = Expression(17, Add) +- expression 17 operands: lhs = Expression(18, Add), rhs = Counter(4) +- expression 18 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 14 - Code(Counter(0)) at (prev + 32, 1) to (start + 0, 65) -- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) - = (((((c2 + c3) + c4) + c5) + c6) + (c0 - c1)) +- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10) + = ((((((c0 + c2) + c3) + c4) + c5) + c6) - c1) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 6, conditions_num: 5 } at (prev + 0, 13) to (start + 0, 42) - MCDCBranch { true: Counter(1), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) true = c1 false = (c0 - c1) - Code(Counter(1)) at (prev + 0, 19) to (start + 0, 20) -- MCDCBranch { true: Expression(18, Sub), false: Counter(6), condition_id: 2, true_next_id: 3, false_next_id: 0 } at (prev + 0, 19) to (start + 0, 20) - true = (c1 - c6) - false = c6 -- Code(Expression(18, Sub)) at (prev + 0, 25) to (start + 0, 26) - = (c1 - c6) -- MCDCBranch { true: Expression(17, Sub), false: Counter(5), condition_id: 3, true_next_id: 4, false_next_id: 0 } at (prev + 0, 25) to (start + 0, 26) - true = ((c1 - c6) - c5) - false = c5 -- Code(Expression(17, Sub)) at (prev + 0, 31) to (start + 0, 32) - = ((c1 - c6) - c5) +- MCDCBranch { true: Expression(8, Sub), false: Counter(2), condition_id: 2, true_next_id: 3, false_next_id: 0 } at (prev + 0, 19) to (start + 0, 20) + true = (c1 - c2) + false = c2 +- Code(Expression(8, Sub)) at (prev + 0, 25) to (start + 0, 26) + = (c1 - c2) +- MCDCBranch { true: Expression(11, Sub), false: Counter(3), condition_id: 3, true_next_id: 4, false_next_id: 0 } at (prev + 0, 25) to (start + 0, 26) + true = (c1 - (c2 + c3)) + false = c3 +- Code(Expression(11, Sub)) at (prev + 0, 31) to (start + 0, 32) + = (c1 - (c2 + c3)) - MCDCBranch { true: Expression(16, Sub), false: Counter(4), condition_id: 4, true_next_id: 5, false_next_id: 0 } at (prev + 0, 31) to (start + 0, 32) - true = (((c1 - c6) - c5) - c4) + true = (c1 - ((c2 + c3) + c4)) false = c4 - Code(Expression(16, Sub)) at (prev + 0, 36) to (start + 0, 39) - = (((c1 - c6) - c5) - c4) -- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 5, true_next_id: 0, false_next_id: 0 } at (prev + 0, 36) to (start + 0, 39) - true = c2 - false = c3 -- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) - = (((((c2 + c3) + c4) + c5) + c6) + (c0 - c1)) + = (c1 - ((c2 + c3) + c4)) +- MCDCBranch { true: Counter(5), false: Counter(6), condition_id: 5, true_next_id: 0, false_next_id: 0 } at (prev + 0, 36) to (start + 0, 39) + true = c5 + false = c6 +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 1, 2) + = ((((((c0 + c2) + c3) + c4) + c5) + c6) - c1) Highest counter ID seen: c6 diff --git a/tests/coverage/nested_loops.cov-map b/tests/coverage/nested_loops.cov-map index 21871ef3206..6ba5887d243 100644 --- a/tests/coverage/nested_loops.cov-map +++ b/tests/coverage/nested_loops.cov-map @@ -1,52 +1,46 @@ Function name: nested_loops::main -Raw bytes (115): 0x[01, 01, 17, 01, 57, 05, 09, 03, 0d, 4e, 53, 03, 0d, 15, 19, 4b, 09, 4e, 53, 03, 0d, 15, 19, 46, 05, 4b, 09, 4e, 53, 03, 0d, 15, 19, 42, 19, 46, 05, 4b, 09, 4e, 53, 03, 0d, 15, 19, 05, 09, 11, 0d, 0d, 01, 01, 01, 02, 1b, 03, 04, 13, 00, 20, 4e, 01, 0d, 01, 18, 4b, 02, 12, 00, 17, 46, 01, 10, 00, 16, 05, 01, 11, 00, 16, 42, 01, 0e, 03, 16, 3e, 04, 11, 01, 1b, 11, 02, 15, 00, 21, 15, 01, 18, 02, 12, 19, 03, 0d, 00, 0e, 57, 02, 09, 00, 17, 5b, 02, 01, 00, 02] +Raw bytes (103): 0x[01, 01, 11, 27, 09, 01, 05, 03, 0d, 13, 0d, 17, 15, 03, 11, 1f, 0d, 23, 15, 27, 11, 01, 05, 2f, 0d, 3b, 15, 01, 11, 3b, 0d, 01, 11, 05, 09, 0d, 19, 0d, 01, 01, 01, 02, 1b, 03, 04, 13, 00, 20, 0a, 01, 0d, 01, 18, 0e, 02, 12, 00, 17, 1a, 01, 10, 00, 16, 05, 01, 11, 00, 16, 2a, 01, 0e, 03, 16, 36, 04, 11, 01, 1b, 19, 02, 15, 00, 21, 11, 01, 18, 02, 12, 15, 03, 0d, 00, 0e, 3f, 02, 09, 00, 17, 43, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 23 -- expression 0 operands: lhs = Counter(0), rhs = Expression(21, Add) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +Number of expressions: 17 +- expression 0 operands: lhs = Expression(9, Add), rhs = Counter(2) +- expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 3 operands: lhs = Expression(19, Sub), rhs = Expression(20, Add) -- expression 4 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 5 operands: lhs = Counter(5), rhs = Counter(6) -- expression 6 operands: lhs = Expression(18, Add), rhs = Counter(2) -- expression 7 operands: lhs = Expression(19, Sub), rhs = Expression(20, Add) -- expression 8 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 9 operands: lhs = Counter(5), rhs = Counter(6) -- expression 10 operands: lhs = Expression(17, Sub), rhs = Counter(1) -- expression 11 operands: lhs = Expression(18, Add), rhs = Counter(2) -- expression 12 operands: lhs = Expression(19, Sub), rhs = Expression(20, Add) -- expression 13 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 14 operands: lhs = Counter(5), rhs = Counter(6) -- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(6) -- expression 16 operands: lhs = Expression(17, Sub), rhs = Counter(1) -- expression 17 operands: lhs = Expression(18, Add), rhs = Counter(2) -- expression 18 operands: lhs = Expression(19, Sub), rhs = Expression(20, Add) -- expression 19 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 20 operands: lhs = Counter(5), rhs = Counter(6) -- expression 21 operands: lhs = Counter(1), rhs = Counter(2) -- expression 22 operands: lhs = Counter(4), rhs = Counter(3) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(3) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(5) +- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(4) +- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(3) +- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(5) +- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(4) +- expression 9 operands: lhs = Counter(0), rhs = Counter(1) +- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(3) +- expression 11 operands: lhs = Expression(14, Add), rhs = Counter(5) +- expression 12 operands: lhs = Counter(0), rhs = Counter(4) +- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(3) +- expression 14 operands: lhs = Counter(0), rhs = Counter(4) +- expression 15 operands: lhs = Counter(1), rhs = Counter(2) +- expression 16 operands: lhs = Counter(3), rhs = Counter(6) Number of file 0 mappings: 13 - Code(Counter(0)) at (prev + 1, 1) to (start + 2, 27) - Code(Expression(0, Add)) at (prev + 4, 19) to (start + 0, 32) - = (c0 + (c1 + c2)) -- Code(Expression(19, Sub)) at (prev + 1, 13) to (start + 1, 24) - = ((c0 + (c1 + c2)) - c3) -- Code(Expression(18, Add)) at (prev + 2, 18) to (start + 0, 23) - = (((c0 + (c1 + c2)) - c3) + (c5 + c6)) -- Code(Expression(17, Sub)) at (prev + 1, 16) to (start + 0, 22) - = ((((c0 + (c1 + c2)) - c3) + (c5 + c6)) - c2) + = ((c0 + c1) + c2) +- Code(Expression(2, Sub)) at (prev + 1, 13) to (start + 1, 24) + = (((c0 + c1) + c2) - c3) +- Code(Expression(3, Sub)) at (prev + 2, 18) to (start + 0, 23) + = (((((c0 + c1) + c2) + c4) + c5) - c3) +- Code(Expression(6, Sub)) at (prev + 1, 16) to (start + 0, 22) + = ((((c0 + c1) + c4) + c5) - c3) - Code(Counter(1)) at (prev + 1, 17) to (start + 0, 22) -- Code(Expression(16, Sub)) at (prev + 1, 14) to (start + 3, 22) - = (((((c0 + (c1 + c2)) - c3) + (c5 + c6)) - c2) - c1) -- Code(Expression(15, Sub)) at (prev + 4, 17) to (start + 1, 27) - = ((((((c0 + (c1 + c2)) - c3) + (c5 + c6)) - c2) - c1) - c6) -- Code(Counter(4)) at (prev + 2, 21) to (start + 0, 33) -- Code(Counter(5)) at (prev + 1, 24) to (start + 2, 18) -- Code(Counter(6)) at (prev + 3, 13) to (start + 0, 14) -- Code(Expression(21, Add)) at (prev + 2, 9) to (start + 0, 23) +- Code(Expression(10, Sub)) at (prev + 1, 14) to (start + 3, 22) + = (((c0 + c4) + c5) - c3) +- Code(Expression(13, Sub)) at (prev + 4, 17) to (start + 1, 27) + = ((c0 + c4) - c3) +- Code(Counter(6)) at (prev + 2, 21) to (start + 0, 33) +- Code(Counter(4)) at (prev + 1, 24) to (start + 2, 18) +- Code(Counter(5)) at (prev + 3, 13) to (start + 0, 14) +- Code(Expression(15, Add)) at (prev + 2, 9) to (start + 0, 23) = (c1 + c2) -- Code(Expression(22, Add)) at (prev + 2, 1) to (start + 0, 2) - = (c4 + c3) +- Code(Expression(16, Add)) at (prev + 2, 1) to (start + 0, 2) + = (c3 + c6) Highest counter ID seen: c6 diff --git a/tests/coverage/overflow.cov-map b/tests/coverage/overflow.cov-map index f6bfb465bf9..01abcc15003 100644 --- a/tests/coverage/overflow.cov-map +++ b/tests/coverage/overflow.cov-map @@ -1,29 +1,30 @@ Function name: overflow::main -Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 10, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 03, 0a, 12, 03, 13, 00, 20, 09, 00, 21, 03, 0a, 0d, 03, 09, 00, 0a, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02] +Raw bytes (67): 0x[01, 01, 09, 07, 0d, 0b, 09, 01, 05, 03, 11, 17, 11, 1b, 0d, 01, 09, 23, 0d, 05, 09, 09, 01, 10, 01, 01, 1b, 03, 02, 0b, 00, 18, 0e, 01, 0c, 00, 1a, 05, 00, 1b, 03, 0a, 12, 03, 13, 00, 20, 09, 00, 21, 03, 0a, 0d, 03, 09, 00, 0a, 1f, 01, 09, 00, 17, 11, 02, 05, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 8 -- expression 0 operands: lhs = Counter(0), rhs = Expression(6, Add) -- expression 1 operands: lhs = Counter(1), rhs = Expression(7, Add) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +Number of expressions: 9 +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(2) +- expression 2 operands: lhs = Counter(0), rhs = Counter(1) - expression 3 operands: lhs = Expression(0, Add), rhs = Counter(4) -- expression 4 operands: lhs = Expression(5, Sub), rhs = Counter(1) -- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(4) -- expression 6 operands: lhs = Counter(1), rhs = Expression(7, Add) -- expression 7 operands: lhs = Counter(2), rhs = Counter(3) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(4) +- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(3) +- expression 6 operands: lhs = Counter(0), rhs = Counter(2) +- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(3) +- expression 8 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 16, 1) to (start + 1, 27) - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24) - = (c0 + (c1 + (c2 + c3))) -- Code(Expression(5, Sub)) at (prev + 1, 12) to (start + 0, 26) - = ((c0 + (c1 + (c2 + c3))) - c4) + = (((c0 + c1) + c2) + c3) +- Code(Expression(3, Sub)) at (prev + 1, 12) to (start + 0, 26) + = ((((c0 + c1) + c2) + c3) - c4) - Code(Counter(1)) at (prev + 0, 27) to (start + 3, 10) - Code(Expression(4, Sub)) at (prev + 3, 19) to (start + 0, 32) - = (((c0 + (c1 + (c2 + c3))) - c4) - c1) + = (((c0 + c2) + c3) - c4) - Code(Counter(2)) at (prev + 0, 33) to (start + 3, 10) - Code(Counter(3)) at (prev + 3, 9) to (start + 0, 10) -- Code(Expression(6, Add)) at (prev + 1, 9) to (start + 0, 23) - = (c1 + (c2 + c3)) +- Code(Expression(7, Add)) at (prev + 1, 9) to (start + 0, 23) + = ((c1 + c2) + c3) - Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2) Highest counter ID seen: c4 diff --git a/tests/coverage/panic_unwind.cov-map b/tests/coverage/panic_unwind.cov-map index 58a796ff3a2..005c4babbea 100644 --- a/tests/coverage/panic_unwind.cov-map +++ b/tests/coverage/panic_unwind.cov-map @@ -1,29 +1,30 @@ Function name: panic_unwind::main -Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 09, 00, 0a, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02] +Raw bytes (67): 0x[01, 01, 09, 07, 0d, 0b, 09, 01, 05, 03, 11, 17, 11, 1b, 0d, 01, 09, 23, 0d, 05, 09, 09, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 0e, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 09, 00, 0a, 1f, 01, 09, 00, 17, 11, 02, 05, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 8 -- expression 0 operands: lhs = Counter(0), rhs = Expression(6, Add) -- expression 1 operands: lhs = Counter(1), rhs = Expression(7, Add) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +Number of expressions: 9 +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(2) +- expression 2 operands: lhs = Counter(0), rhs = Counter(1) - expression 3 operands: lhs = Expression(0, Add), rhs = Counter(4) -- expression 4 operands: lhs = Expression(5, Sub), rhs = Counter(1) -- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(4) -- expression 6 operands: lhs = Counter(1), rhs = Expression(7, Add) -- expression 7 operands: lhs = Counter(2), rhs = Counter(3) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(4) +- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(3) +- expression 6 operands: lhs = Counter(0), rhs = Counter(2) +- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(3) +- expression 8 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27) - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24) - = (c0 + (c1 + (c2 + c3))) -- Code(Expression(5, Sub)) at (prev + 1, 12) to (start + 0, 26) - = ((c0 + (c1 + (c2 + c3))) - c4) + = (((c0 + c1) + c2) + c3) +- Code(Expression(3, Sub)) at (prev + 1, 12) to (start + 0, 26) + = ((((c0 + c1) + c2) + c3) - c4) - Code(Counter(1)) at (prev + 0, 27) to (start + 2, 10) - Code(Expression(4, Sub)) at (prev + 2, 19) to (start + 0, 32) - = (((c0 + (c1 + (c2 + c3))) - c4) - c1) + = (((c0 + c2) + c3) - c4) - Code(Counter(2)) at (prev + 0, 33) to (start + 2, 10) - Code(Counter(3)) at (prev + 2, 9) to (start + 0, 10) -- Code(Expression(6, Add)) at (prev + 1, 9) to (start + 0, 23) - = (c1 + (c2 + c3)) +- Code(Expression(7, Add)) at (prev + 1, 9) to (start + 0, 23) + = ((c1 + c2) + c3) - Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2) Highest counter ID seen: c4 diff --git a/tests/coverage/simple_match.cov-map b/tests/coverage/simple_match.cov-map index d8bf9eae4bc..8f973742959 100644 --- a/tests/coverage/simple_match.cov-map +++ b/tests/coverage/simple_match.cov-map @@ -1,29 +1,29 @@ Function name: simple_match::main -Raw bytes (72): 0x[01, 01, 09, 01, 05, 01, 23, 09, 0d, 1f, 11, 01, 23, 09, 0d, 1f, 11, 01, 23, 09, 0d, 0a, 01, 04, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 1f, 05, 09, 00, 0d, 1a, 05, 0d, 00, 16, 09, 02, 0d, 00, 0e, 1a, 02, 11, 02, 12, 09, 04, 0d, 07, 0e, 0d, 0a, 0d, 00, 0f, 11, 03, 01, 00, 02] +Raw bytes (72): 0x[01, 01, 09, 01, 05, 23, 0d, 01, 09, 1f, 11, 23, 0d, 01, 09, 1f, 11, 23, 0d, 01, 09, 0a, 01, 04, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 1f, 05, 09, 00, 0d, 1a, 05, 0d, 00, 16, 09, 02, 0d, 00, 0e, 1a, 02, 11, 02, 12, 09, 04, 0d, 07, 0e, 0d, 0a, 0d, 00, 0f, 11, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 9 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Expression(8, Add) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Expression(8, Add), rhs = Counter(3) +- expression 2 operands: lhs = Counter(0), rhs = Counter(2) - expression 3 operands: lhs = Expression(7, Add), rhs = Counter(4) -- expression 4 operands: lhs = Counter(0), rhs = Expression(8, Add) -- expression 5 operands: lhs = Counter(2), rhs = Counter(3) +- expression 4 operands: lhs = Expression(8, Add), rhs = Counter(3) +- expression 5 operands: lhs = Counter(0), rhs = Counter(2) - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4) -- expression 7 operands: lhs = Counter(0), rhs = Expression(8, Add) -- expression 8 operands: lhs = Counter(2), rhs = Counter(3) +- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(3) +- expression 8 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 10 - Code(Counter(0)) at (prev + 4, 1) to (start + 7, 15) - Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c1) - Code(Expression(7, Add)) at (prev + 5, 9) to (start + 0, 13) - = (c0 + (c2 + c3)) + = ((c0 + c2) + c3) - Code(Expression(6, Sub)) at (prev + 5, 13) to (start + 0, 22) - = ((c0 + (c2 + c3)) - c4) + = (((c0 + c2) + c3) - c4) - Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14) - Code(Expression(6, Sub)) at (prev + 2, 17) to (start + 2, 18) - = ((c0 + (c2 + c3)) - c4) + = (((c0 + c2) + c3) - c4) - Code(Counter(2)) at (prev + 4, 13) to (start + 7, 14) - Code(Counter(3)) at (prev + 10, 13) to (start + 0, 15) - Code(Counter(4)) at (prev + 3, 1) to (start + 0, 2) diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map index 246a1ba738b..7fbd2cc642e 100644 --- a/tests/coverage/try_error_result.cov-map +++ b/tests/coverage/try_error_result.cov-map @@ -55,162 +55,162 @@ Number of file 0 mappings: 4 Highest counter ID seen: c1 Function name: try_error_result::test1 -Raw bytes (75): 0x[01, 01, 08, 01, 07, 00, 09, 03, 0d, 12, 1d, 03, 0d, 1b, 0d, 1f, 00, 11, 00, 0b, 01, 0d, 01, 02, 17, 03, 07, 09, 00, 0e, 12, 02, 09, 04, 1a, 1d, 06, 0d, 00, 29, 11, 00, 29, 00, 2a, 00, 01, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0e, 04, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0d, 03, 05, 00, 0b, 17, 01, 01, 00, 02] +Raw bytes (75): 0x[01, 01, 08, 07, 09, 01, 00, 03, 0d, 03, 13, 0d, 11, 1b, 00, 1f, 00, 0d, 15, 0b, 01, 0d, 01, 02, 17, 03, 07, 09, 00, 0e, 0a, 02, 09, 04, 1a, 11, 06, 0d, 00, 29, 15, 00, 29, 00, 2a, 00, 01, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0e, 04, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0d, 03, 05, 00, 0b, 17, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 8 -- expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) -- expression 1 operands: lhs = Zero, rhs = Counter(2) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2) +- expression 1 operands: lhs = Counter(0), rhs = Zero - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 3 operands: lhs = Expression(4, Sub), rhs = Counter(7) -- expression 4 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(3) +- expression 3 operands: lhs = Expression(0, Add), rhs = Expression(4, Add) +- expression 4 operands: lhs = Counter(3), rhs = Counter(4) +- expression 5 operands: lhs = Expression(6, Add), rhs = Zero - expression 6 operands: lhs = Expression(7, Add), rhs = Zero -- expression 7 operands: lhs = Counter(4), rhs = Zero +- expression 7 operands: lhs = Counter(3), rhs = Counter(5) Number of file 0 mappings: 11 - Code(Counter(0)) at (prev + 13, 1) to (start + 2, 23) - Code(Expression(0, Add)) at (prev + 7, 9) to (start + 0, 14) - = (c0 + (Zero + c2)) -- Code(Expression(4, Sub)) at (prev + 2, 9) to (start + 4, 26) - = ((c0 + (Zero + c2)) - c3) -- Code(Counter(7)) at (prev + 6, 13) to (start + 0, 41) -- Code(Counter(4)) at (prev + 0, 41) to (start + 0, 42) + = ((c0 + Zero) + c2) +- Code(Expression(2, Sub)) at (prev + 2, 9) to (start + 4, 26) + = (((c0 + Zero) + c2) - c3) +- Code(Counter(4)) at (prev + 6, 13) to (start + 0, 41) +- Code(Counter(5)) at (prev + 0, 41) to (start + 0, 42) - Code(Zero) at (prev + 1, 13) to (start + 0, 42) - Code(Zero) at (prev + 0, 42) to (start + 0, 43) - Code(Expression(3, Sub)) at (prev + 4, 13) to (start + 0, 42) - = (((c0 + (Zero + c2)) - c3) - c7) + = (((c0 + Zero) + c2) - (c3 + c4)) - Code(Zero) at (prev + 0, 42) to (start + 0, 43) - Code(Counter(3)) at (prev + 3, 5) to (start + 0, 11) - Code(Expression(5, Add)) at (prev + 1, 1) to (start + 0, 2) - = (((c4 + Zero) + Zero) + c3) -Highest counter ID seen: c7 + = (((c3 + c5) + Zero) + Zero) +Highest counter ID seen: c5 Function name: try_error_result::test2 -Raw bytes (358): 0x[01, 01, 3b, 01, 07, 05, 09, 03, 0d, 41, 11, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 4a, 15, 41, 11, 46, 19, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 5e, 25, 49, 21, 49, 21, 5e, 25, 49, 21, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, 92, 01, 41, 03, 0d, 8e, 01, 29, 92, 01, 41, 03, 0d, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, a6, 01, 35, 45, 31, 45, 31, a6, 01, 35, 45, 31, ba, 01, 3d, 4d, 39, 4d, 39, ba, 01, 3d, 4d, 39, c3, 01, 0d, c7, 01, db, 01, cb, 01, cf, 01, 11, 15, d3, 01, d7, 01, 19, 1d, 21, 25, df, 01, e3, 01, 29, 2d, e7, 01, eb, 01, 31, 35, 39, 3d, 28, 01, 3d, 01, 03, 17, 03, 08, 09, 00, 0e, 92, 01, 02, 09, 04, 1a, 41, 06, 0d, 00, 2f, 11, 00, 2f, 00, 30, 4a, 00, 31, 03, 35, 15, 04, 11, 00, 12, 46, 02, 11, 04, 12, 3e, 05, 11, 00, 14, 46, 00, 17, 00, 41, 19, 00, 41, 00, 42, 42, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 3e, 01, 0d, 00, 20, 5a, 01, 11, 00, 14, 49, 00, 17, 00, 41, 21, 00, 41, 00, 42, 5e, 00, 43, 00, 60, 25, 00, 60, 00, 61, 5a, 01, 0d, 00, 20, 86, 01, 04, 11, 00, 14, 8e, 01, 00, 17, 00, 42, 29, 00, 42, 00, 43, 8a, 01, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 86, 01, 01, 0d, 00, 20, a2, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, a6, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 20, b6, 01, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 39, 02, 11, 00, 12, ba, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, bf, 01, 01, 01, 00, 02] +Raw bytes (355): 0x[01, 01, 3b, 07, 09, 01, 05, 03, 0d, 11, 15, 11, 4b, 15, 19, 11, 43, 47, 21, 4b, 1d, 15, 19, 11, 4b, 15, 19, 11, 47, 4b, 1d, 15, 19, 11, 43, 47, 21, 4b, 1d, 15, 19, 45, 5f, 25, 29, 45, 25, 45, 5f, 25, 29, 03, 8b, 01, 8f, 01, 31, 93, 01, 2d, 0d, 11, 03, 93, 01, 0d, 11, 03, 8f, 01, 93, 01, 2d, 0d, 11, 03, 8b, 01, 8f, 01, 31, 93, 01, 2d, 0d, 11, 49, a7, 01, 35, 39, 49, 35, 49, a7, 01, 35, 39, 4d, bb, 01, 3d, 41, 4d, 3d, 4d, bb, 01, 3d, 41, c3, 01, 41, c7, 01, 3d, cb, 01, 39, cf, 01, 35, d3, 01, 31, d7, 01, 2d, db, 01, 29, df, 01, 25, e3, 01, 21, e7, 01, 1d, eb, 01, 19, 0d, 15, 28, 01, 3d, 01, 03, 17, 03, 08, 09, 00, 0e, 0a, 02, 09, 04, 1a, 11, 06, 0d, 00, 2f, 15, 00, 2f, 00, 30, 0e, 00, 31, 03, 35, 19, 04, 11, 00, 12, 2a, 02, 11, 04, 12, 3e, 05, 11, 00, 14, 2a, 00, 17, 00, 41, 1d, 00, 41, 00, 42, 32, 00, 43, 00, 5f, 21, 00, 5f, 00, 60, 3e, 01, 0d, 00, 20, 5a, 01, 11, 00, 14, 45, 00, 17, 00, 41, 25, 00, 41, 00, 42, 56, 00, 43, 00, 60, 29, 00, 60, 00, 61, 5a, 01, 0d, 00, 20, 86, 01, 04, 11, 00, 14, 72, 00, 17, 00, 42, 2d, 00, 42, 00, 43, 7a, 00, 44, 00, 61, 31, 00, 61, 00, 62, 86, 01, 01, 0d, 00, 20, a2, 01, 01, 11, 00, 14, 49, 00, 17, 01, 36, 35, 01, 36, 00, 37, 9e, 01, 01, 12, 00, 2f, 39, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 20, b6, 01, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 3d, 02, 11, 00, 12, b2, 01, 01, 12, 00, 2f, 41, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, bf, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 59 -- expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2) +- expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 3 operands: lhs = Counter(16), rhs = Counter(4) -- expression 4 operands: lhs = Expression(18, Sub), rhs = Counter(5) -- expression 5 operands: lhs = Counter(16), rhs = Counter(4) -- expression 6 operands: lhs = Expression(16, Sub), rhs = Counter(7) -- expression 7 operands: lhs = Expression(17, Sub), rhs = Counter(6) -- expression 8 operands: lhs = Expression(18, Sub), rhs = Counter(5) -- expression 9 operands: lhs = Counter(16), rhs = Counter(4) -- expression 10 operands: lhs = Expression(18, Sub), rhs = Counter(5) -- expression 11 operands: lhs = Counter(16), rhs = Counter(4) -- expression 12 operands: lhs = Expression(17, Sub), rhs = Counter(6) -- expression 13 operands: lhs = Expression(18, Sub), rhs = Counter(5) -- expression 14 operands: lhs = Counter(16), rhs = Counter(4) -- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(7) -- expression 16 operands: lhs = Expression(17, Sub), rhs = Counter(6) -- expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(5) -- expression 18 operands: lhs = Counter(16), rhs = Counter(4) -- expression 19 operands: lhs = Expression(23, Sub), rhs = Counter(9) -- expression 20 operands: lhs = Counter(18), rhs = Counter(8) -- expression 21 operands: lhs = Counter(18), rhs = Counter(8) -- expression 22 operands: lhs = Expression(23, Sub), rhs = Counter(9) -- expression 23 operands: lhs = Counter(18), rhs = Counter(8) -- expression 24 operands: lhs = Expression(34, Sub), rhs = Counter(11) -- expression 25 operands: lhs = Expression(35, Sub), rhs = Counter(10) -- expression 26 operands: lhs = Expression(36, Sub), rhs = Counter(16) -- expression 27 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 28 operands: lhs = Expression(36, Sub), rhs = Counter(16) -- expression 29 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 30 operands: lhs = Expression(35, Sub), rhs = Counter(10) -- expression 31 operands: lhs = Expression(36, Sub), rhs = Counter(16) -- expression 32 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 33 operands: lhs = Expression(34, Sub), rhs = Counter(11) -- expression 34 operands: lhs = Expression(35, Sub), rhs = Counter(10) -- expression 35 operands: lhs = Expression(36, Sub), rhs = Counter(16) -- expression 36 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 37 operands: lhs = Expression(41, Sub), rhs = Counter(13) -- expression 38 operands: lhs = Counter(17), rhs = Counter(12) -- expression 39 operands: lhs = Counter(17), rhs = Counter(12) -- expression 40 operands: lhs = Expression(41, Sub), rhs = Counter(13) -- expression 41 operands: lhs = Counter(17), rhs = Counter(12) -- expression 42 operands: lhs = Expression(46, Sub), rhs = Counter(15) -- expression 43 operands: lhs = Counter(19), rhs = Counter(14) -- expression 44 operands: lhs = Counter(19), rhs = Counter(14) -- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(15) -- expression 46 operands: lhs = Counter(19), rhs = Counter(14) -- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(3) -- expression 48 operands: lhs = Expression(49, Add), rhs = Expression(54, Add) -- expression 49 operands: lhs = Expression(50, Add), rhs = Expression(51, Add) -- expression 50 operands: lhs = Counter(4), rhs = Counter(5) -- expression 51 operands: lhs = Expression(52, Add), rhs = Expression(53, Add) -- expression 52 operands: lhs = Counter(6), rhs = Counter(7) -- expression 53 operands: lhs = Counter(8), rhs = Counter(9) -- expression 54 operands: lhs = Expression(55, Add), rhs = Expression(56, Add) -- expression 55 operands: lhs = Counter(10), rhs = Counter(11) -- expression 56 operands: lhs = Expression(57, Add), rhs = Expression(58, Add) -- expression 57 operands: lhs = Counter(12), rhs = Counter(13) -- expression 58 operands: lhs = Counter(14), rhs = Counter(15) +- expression 3 operands: lhs = Counter(4), rhs = Counter(5) +- expression 4 operands: lhs = Counter(4), rhs = Expression(18, Add) +- expression 5 operands: lhs = Counter(5), rhs = Counter(6) +- expression 6 operands: lhs = Counter(4), rhs = Expression(16, Add) +- expression 7 operands: lhs = Expression(17, Add), rhs = Counter(8) +- expression 8 operands: lhs = Expression(18, Add), rhs = Counter(7) +- expression 9 operands: lhs = Counter(5), rhs = Counter(6) +- expression 10 operands: lhs = Counter(4), rhs = Expression(18, Add) +- expression 11 operands: lhs = Counter(5), rhs = Counter(6) +- expression 12 operands: lhs = Counter(4), rhs = Expression(17, Add) +- expression 13 operands: lhs = Expression(18, Add), rhs = Counter(7) +- expression 14 operands: lhs = Counter(5), rhs = Counter(6) +- expression 15 operands: lhs = Counter(4), rhs = Expression(16, Add) +- expression 16 operands: lhs = Expression(17, Add), rhs = Counter(8) +- expression 17 operands: lhs = Expression(18, Add), rhs = Counter(7) +- expression 18 operands: lhs = Counter(5), rhs = Counter(6) +- expression 19 operands: lhs = Counter(17), rhs = Expression(23, Add) +- expression 20 operands: lhs = Counter(9), rhs = Counter(10) +- expression 21 operands: lhs = Counter(17), rhs = Counter(9) +- expression 22 operands: lhs = Counter(17), rhs = Expression(23, Add) +- expression 23 operands: lhs = Counter(9), rhs = Counter(10) +- expression 24 operands: lhs = Expression(0, Add), rhs = Expression(34, Add) +- expression 25 operands: lhs = Expression(35, Add), rhs = Counter(12) +- expression 26 operands: lhs = Expression(36, Add), rhs = Counter(11) +- expression 27 operands: lhs = Counter(3), rhs = Counter(4) +- expression 28 operands: lhs = Expression(0, Add), rhs = Expression(36, Add) +- expression 29 operands: lhs = Counter(3), rhs = Counter(4) +- expression 30 operands: lhs = Expression(0, Add), rhs = Expression(35, Add) +- expression 31 operands: lhs = Expression(36, Add), rhs = Counter(11) +- expression 32 operands: lhs = Counter(3), rhs = Counter(4) +- expression 33 operands: lhs = Expression(0, Add), rhs = Expression(34, Add) +- expression 34 operands: lhs = Expression(35, Add), rhs = Counter(12) +- expression 35 operands: lhs = Expression(36, Add), rhs = Counter(11) +- expression 36 operands: lhs = Counter(3), rhs = Counter(4) +- expression 37 operands: lhs = Counter(18), rhs = Expression(41, Add) +- expression 38 operands: lhs = Counter(13), rhs = Counter(14) +- expression 39 operands: lhs = Counter(18), rhs = Counter(13) +- expression 40 operands: lhs = Counter(18), rhs = Expression(41, Add) +- expression 41 operands: lhs = Counter(13), rhs = Counter(14) +- expression 42 operands: lhs = Counter(19), rhs = Expression(46, Add) +- expression 43 operands: lhs = Counter(15), rhs = Counter(16) +- expression 44 operands: lhs = Counter(19), rhs = Counter(15) +- expression 45 operands: lhs = Counter(19), rhs = Expression(46, Add) +- expression 46 operands: lhs = Counter(15), rhs = Counter(16) +- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(16) +- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(15) +- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(14) +- expression 50 operands: lhs = Expression(51, Add), rhs = Counter(13) +- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(12) +- expression 52 operands: lhs = Expression(53, Add), rhs = Counter(11) +- expression 53 operands: lhs = Expression(54, Add), rhs = Counter(10) +- expression 54 operands: lhs = Expression(55, Add), rhs = Counter(9) +- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(8) +- expression 56 operands: lhs = Expression(57, Add), rhs = Counter(7) +- expression 57 operands: lhs = Expression(58, Add), rhs = Counter(6) +- expression 58 operands: lhs = Counter(3), rhs = Counter(5) Number of file 0 mappings: 40 - Code(Counter(0)) at (prev + 61, 1) to (start + 3, 23) - Code(Expression(0, Add)) at (prev + 8, 9) to (start + 0, 14) - = (c0 + (c1 + c2)) -- Code(Expression(36, Sub)) at (prev + 2, 9) to (start + 4, 26) - = ((c0 + (c1 + c2)) - c3) -- Code(Counter(16)) at (prev + 6, 13) to (start + 0, 47) -- Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48) -- Code(Expression(18, Sub)) at (prev + 0, 49) to (start + 3, 53) - = (c16 - c4) -- Code(Counter(5)) at (prev + 4, 17) to (start + 0, 18) -- Code(Expression(17, Sub)) at (prev + 2, 17) to (start + 4, 18) - = ((c16 - c4) - c5) + = ((c0 + c1) + c2) +- Code(Expression(2, Sub)) at (prev + 2, 9) to (start + 4, 26) + = (((c0 + c1) + c2) - c3) +- Code(Counter(4)) at (prev + 6, 13) to (start + 0, 47) +- Code(Counter(5)) at (prev + 0, 47) to (start + 0, 48) +- Code(Expression(3, Sub)) at (prev + 0, 49) to (start + 3, 53) + = (c4 - c5) +- Code(Counter(6)) at (prev + 4, 17) to (start + 0, 18) +- Code(Expression(10, Sub)) at (prev + 2, 17) to (start + 4, 18) + = (c4 - (c5 + c6)) - Code(Expression(15, Sub)) at (prev + 5, 17) to (start + 0, 20) - = ((((c16 - c4) - c5) - c6) - c7) -- Code(Expression(17, Sub)) at (prev + 0, 23) to (start + 0, 65) - = ((c16 - c4) - c5) -- Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66) -- Code(Expression(16, Sub)) at (prev + 0, 67) to (start + 0, 95) - = (((c16 - c4) - c5) - c6) -- Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96) + = (c4 - (((c5 + c6) + c7) + c8)) +- Code(Expression(10, Sub)) at (prev + 0, 23) to (start + 0, 65) + = (c4 - (c5 + c6)) +- Code(Counter(7)) at (prev + 0, 65) to (start + 0, 66) +- Code(Expression(12, Sub)) at (prev + 0, 67) to (start + 0, 95) + = (c4 - ((c5 + c6) + c7)) +- Code(Counter(8)) at (prev + 0, 95) to (start + 0, 96) - Code(Expression(15, Sub)) at (prev + 1, 13) to (start + 0, 32) - = ((((c16 - c4) - c5) - c6) - c7) + = (c4 - (((c5 + c6) + c7) + c8)) - Code(Expression(22, Sub)) at (prev + 1, 17) to (start + 0, 20) - = ((c18 - c8) - c9) -- Code(Counter(18)) at (prev + 0, 23) to (start + 0, 65) -- Code(Counter(8)) at (prev + 0, 65) to (start + 0, 66) -- Code(Expression(23, Sub)) at (prev + 0, 67) to (start + 0, 96) - = (c18 - c8) -- Code(Counter(9)) at (prev + 0, 96) to (start + 0, 97) + = (c17 - (c9 + c10)) +- Code(Counter(17)) at (prev + 0, 23) to (start + 0, 65) +- Code(Counter(9)) at (prev + 0, 65) to (start + 0, 66) +- Code(Expression(21, Sub)) at (prev + 0, 67) to (start + 0, 96) + = (c17 - c9) +- Code(Counter(10)) at (prev + 0, 96) to (start + 0, 97) - Code(Expression(22, Sub)) at (prev + 1, 13) to (start + 0, 32) - = ((c18 - c8) - c9) + = (c17 - (c9 + c10)) - Code(Expression(33, Sub)) at (prev + 4, 17) to (start + 0, 20) - = (((((c0 + (c1 + c2)) - c3) - c16) - c10) - c11) -- Code(Expression(35, Sub)) at (prev + 0, 23) to (start + 0, 66) - = (((c0 + (c1 + c2)) - c3) - c16) -- Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67) -- Code(Expression(34, Sub)) at (prev + 0, 68) to (start + 0, 97) - = ((((c0 + (c1 + c2)) - c3) - c16) - c10) -- Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98) + = (((c0 + c1) + c2) - (((c3 + c4) + c11) + c12)) +- Code(Expression(28, Sub)) at (prev + 0, 23) to (start + 0, 66) + = (((c0 + c1) + c2) - (c3 + c4)) +- Code(Counter(11)) at (prev + 0, 66) to (start + 0, 67) +- Code(Expression(30, Sub)) at (prev + 0, 68) to (start + 0, 97) + = (((c0 + c1) + c2) - ((c3 + c4) + c11)) +- Code(Counter(12)) at (prev + 0, 97) to (start + 0, 98) - Code(Expression(33, Sub)) at (prev + 1, 13) to (start + 0, 32) - = (((((c0 + (c1 + c2)) - c3) - c16) - c10) - c11) + = (((c0 + c1) + c2) - (((c3 + c4) + c11) + c12)) - Code(Expression(40, Sub)) at (prev + 1, 17) to (start + 0, 20) - = ((c17 - c12) - c13) -- Code(Counter(17)) at (prev + 0, 23) to (start + 1, 54) -- Code(Counter(12)) at (prev + 1, 54) to (start + 0, 55) -- Code(Expression(41, Sub)) at (prev + 1, 18) to (start + 0, 47) - = (c17 - c12) -- Code(Counter(13)) at (prev + 0, 47) to (start + 0, 48) + = (c18 - (c13 + c14)) +- Code(Counter(18)) at (prev + 0, 23) to (start + 1, 54) +- Code(Counter(13)) at (prev + 1, 54) to (start + 0, 55) +- Code(Expression(39, Sub)) at (prev + 1, 18) to (start + 0, 47) + = (c18 - c13) +- Code(Counter(14)) at (prev + 0, 47) to (start + 0, 48) - Code(Expression(40, Sub)) at (prev + 1, 13) to (start + 0, 32) - = ((c17 - c12) - c13) + = (c18 - (c13 + c14)) - Code(Expression(45, Sub)) at (prev + 1, 17) to (start + 0, 20) - = ((c19 - c14) - c15) + = (c19 - (c15 + c16)) - Code(Counter(19)) at (prev + 0, 23) to (start + 1, 54) -- Code(Counter(14)) at (prev + 2, 17) to (start + 0, 18) -- Code(Expression(46, Sub)) at (prev + 1, 18) to (start + 0, 47) - = (c19 - c14) -- Code(Counter(15)) at (prev + 1, 17) to (start + 0, 18) +- Code(Counter(15)) at (prev + 2, 17) to (start + 0, 18) +- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 47) + = (c19 - c15) +- Code(Counter(16)) at (prev + 1, 17) to (start + 0, 18) - Code(Expression(45, Sub)) at (prev + 2, 13) to (start + 0, 32) - = ((c19 - c14) - c15) + = (c19 - (c15 + c16)) - Code(Counter(3)) at (prev + 3, 5) to (start + 0, 11) - Code(Expression(47, Add)) at (prev + 1, 1) to (start + 0, 2) - = ((((c4 + c5) + ((c6 + c7) + (c8 + c9))) + ((c10 + c11) + ((c12 + c13) + (c14 + c15)))) + c3) + = ((((((((((((c3 + c5) + c6) + c7) + c8) + c9) + c10) + c11) + c12) + c13) + c14) + c15) + c16) Highest counter ID seen: c19 diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map index 769930110d6..630ab4ce47e 100644 --- a/tests/coverage/unicode.cov-map +++ b/tests/coverage/unicode.cov-map @@ -1,14 +1,14 @@ Function name: unicode::main -Raw bytes (61): 0x[01, 01, 06, 01, 05, 16, 0d, 01, 09, 11, 13, 16, 0d, 01, 09, 09, 01, 0e, 01, 00, 0b, 05, 01, 09, 00, 0c, 03, 00, 10, 00, 1b, 05, 00, 1c, 00, 28, 01, 02, 08, 00, 25, 09, 00, 29, 00, 46, 11, 00, 47, 02, 06, 13, 02, 05, 00, 06, 0f, 02, 05, 01, 02] +Raw bytes (61): 0x[01, 01, 06, 01, 05, 0b, 09, 01, 11, 13, 09, 17, 11, 01, 0d, 09, 01, 0e, 01, 00, 0b, 05, 01, 09, 00, 0c, 03, 00, 10, 00, 1b, 05, 00, 1c, 00, 28, 01, 02, 08, 00, 25, 09, 00, 29, 00, 46, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 0e, 02, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 6 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(5, Sub), rhs = Counter(3) -- expression 2 operands: lhs = Counter(0), rhs = Counter(2) -- expression 3 operands: lhs = Counter(4), rhs = Expression(4, Add) -- expression 4 operands: lhs = Expression(5, Sub), rhs = Counter(3) -- expression 5 operands: lhs = Counter(0), rhs = Counter(2) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(2) +- expression 2 operands: lhs = Counter(0), rhs = Counter(4) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(2) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(4) +- expression 5 operands: lhs = Counter(0), rhs = Counter(3) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 14, 1) to (start + 0, 11) - Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12) @@ -17,12 +17,12 @@ Number of file 0 mappings: 9 - Code(Counter(1)) at (prev + 0, 28) to (start + 0, 40) - Code(Counter(0)) at (prev + 2, 8) to (start + 0, 37) - Code(Counter(2)) at (prev + 0, 41) to (start + 0, 70) -- Code(Counter(4)) at (prev + 0, 71) to (start + 2, 6) -- Code(Expression(4, Add)) at (prev + 2, 5) to (start + 0, 6) - = ((c0 - c2) + c3) -- Code(Expression(3, Add)) at (prev + 2, 5) to (start + 1, 2) - = (c4 + ((c0 - c2) + c3)) -Highest counter ID seen: c4 +- Code(Counter(3)) at (prev + 0, 71) to (start + 2, 6) +- Code(Expression(1, Sub)) at (prev + 2, 5) to (start + 0, 6) + = ((c0 + c4) - c2) +- Code(Expression(3, Sub)) at (prev + 2, 5) to (start + 1, 2) + = (((c0 + c3) + c4) - c2) +Highest counter ID seen: c3 Function name: unicode::ä»– (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 1e, 19, 00, 25] diff --git a/tests/coverage/unused.cov-map b/tests/coverage/unused.cov-map index e865ac3ee62..4eae63f380c 100644 --- a/tests/coverage/unused.cov-map +++ b/tests/coverage/unused.cov-map @@ -1,18 +1,18 @@ Function name: unused::foo::<f32> -Raw bytes (42): 0x[01, 01, 04, 01, 0f, 05, 09, 03, 0d, 05, 09, 06, 01, 03, 01, 01, 12, 03, 02, 0b, 00, 11, 0a, 01, 09, 00, 0f, 09, 00, 13, 00, 19, 0f, 01, 09, 00, 0f, 0d, 02, 01, 00, 02] +Raw bytes (42): 0x[01, 01, 04, 07, 09, 01, 05, 03, 0d, 05, 09, 06, 01, 03, 01, 01, 12, 03, 02, 0b, 00, 11, 0a, 01, 09, 00, 0f, 09, 00, 13, 00, 19, 0f, 01, 09, 00, 0f, 0d, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 -- expression 0 operands: lhs = Counter(0), rhs = Expression(3, Add) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2) +- expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) - expression 3 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 3, 1) to (start + 1, 18) - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 17) - = (c0 + (c1 + c2)) + = ((c0 + c1) + c2) - Code(Expression(2, Sub)) at (prev + 1, 9) to (start + 0, 15) - = ((c0 + (c1 + c2)) - c3) + = (((c0 + c1) + c2) - c3) - Code(Counter(2)) at (prev + 0, 19) to (start + 0, 25) - Code(Expression(3, Add)) at (prev + 1, 9) to (start + 0, 15) = (c1 + c2) @@ -20,20 +20,20 @@ Number of file 0 mappings: 6 Highest counter ID seen: c3 Function name: unused::foo::<u32> -Raw bytes (42): 0x[01, 01, 04, 01, 0f, 05, 09, 03, 0d, 05, 09, 06, 01, 03, 01, 01, 12, 03, 02, 0b, 00, 11, 0a, 01, 09, 00, 0f, 09, 00, 13, 00, 19, 0f, 01, 09, 00, 0f, 0d, 02, 01, 00, 02] +Raw bytes (42): 0x[01, 01, 04, 07, 09, 01, 05, 03, 0d, 05, 09, 06, 01, 03, 01, 01, 12, 03, 02, 0b, 00, 11, 0a, 01, 09, 00, 0f, 09, 00, 13, 00, 19, 0f, 01, 09, 00, 0f, 0d, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 -- expression 0 operands: lhs = Counter(0), rhs = Expression(3, Add) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2) +- expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) - expression 3 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 3, 1) to (start + 1, 18) - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 17) - = (c0 + (c1 + c2)) + = ((c0 + c1) + c2) - Code(Expression(2, Sub)) at (prev + 1, 9) to (start + 0, 15) - = ((c0 + (c1 + c2)) - c3) + = (((c0 + c1) + c2) - c3) - Code(Counter(2)) at (prev + 0, 19) to (start + 0, 25) - Code(Expression(3, Add)) at (prev + 1, 9) to (start + 0, 15) = (c1 + c2) diff --git a/tests/coverage/while_early_ret.cov-map b/tests/coverage/while_early_ret.cov-map index 6254dfbcf01..ade770597e2 100644 --- a/tests/coverage/while_early_ret.cov-map +++ b/tests/coverage/while_early_ret.cov-map @@ -1,27 +1,26 @@ Function name: while_early_ret::main -Raw bytes (61): 0x[01, 01, 06, 01, 05, 03, 09, 0e, 05, 03, 09, 17, 09, 0d, 11, 09, 01, 05, 01, 01, 1b, 03, 03, 09, 02, 0a, 0e, 05, 0d, 02, 0e, 0a, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 11, 04, 15, 00, 1b, 05, 03, 0a, 03, 0a, 09, 06, 05, 00, 0b, 13, 01, 01, 00, 02] +Raw bytes (59): 0x[01, 01, 05, 01, 05, 03, 09, 01, 09, 13, 11, 09, 0d, 09, 01, 05, 01, 01, 1b, 03, 03, 09, 02, 0a, 06, 05, 0d, 02, 0e, 0a, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 11, 04, 15, 00, 1b, 05, 03, 0a, 03, 0a, 09, 06, 05, 00, 0b, 0f, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 6 +Number of expressions: 5 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Expression(0, Add), rhs = Counter(2) -- expression 2 operands: lhs = Expression(3, Sub), rhs = Counter(1) -- expression 3 operands: lhs = Expression(0, Add), rhs = Counter(2) -- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(2) -- expression 5 operands: lhs = Counter(3), rhs = Counter(4) +- expression 2 operands: lhs = Counter(0), rhs = Counter(2) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(4) +- expression 4 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 5, 1) to (start + 1, 27) - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 2, 10) = (c0 + c1) -- Code(Expression(3, Sub)) at (prev + 5, 13) to (start + 2, 14) +- Code(Expression(1, Sub)) at (prev + 5, 13) to (start + 2, 14) = ((c0 + c1) - c2) - Code(Expression(2, Sub)) at (prev + 6, 21) to (start + 2, 22) - = (((c0 + c1) - c2) - c1) + = (c0 - c2) - Code(Counter(3)) at (prev + 4, 21) to (start + 0, 27) - Code(Counter(4)) at (prev + 4, 21) to (start + 0, 27) - Code(Counter(1)) at (prev + 3, 10) to (start + 3, 10) - Code(Counter(2)) at (prev + 6, 5) to (start + 0, 11) -- Code(Expression(4, Add)) at (prev + 1, 1) to (start + 0, 2) - = ((c3 + c4) + c2) +- Code(Expression(3, Add)) at (prev + 1, 1) to (start + 0, 2) + = ((c2 + c3) + c4) Highest counter ID seen: c4 diff --git a/tests/coverage/yield.cov-map b/tests/coverage/yield.cov-map index 578994a4530..e01ec8f9edb 100644 --- a/tests/coverage/yield.cov-map +++ b/tests/coverage/yield.cov-map @@ -1,17 +1,17 @@ Function name: yield::main -Raw bytes (106): 0x[01, 01, 0b, 05, 00, 0d, 11, 22, 15, 0d, 11, 11, 15, 22, 15, 0d, 11, 22, 15, 0d, 11, 19, 1d, 25, 29, 10, 01, 07, 01, 01, 16, 01, 07, 0b, 00, 2e, 0d, 01, 27, 00, 29, 03, 01, 0e, 00, 34, 0d, 02, 0b, 00, 2e, 22, 01, 22, 00, 27, 1e, 00, 2c, 00, 2e, 13, 01, 0e, 00, 34, 1e, 03, 09, 00, 16, 1e, 08, 0b, 00, 2e, 21, 01, 27, 00, 29, 27, 01, 0e, 00, 34, 21, 02, 0b, 00, 2e, 2d, 01, 27, 00, 29, 2b, 01, 0e, 00, 34, 2d, 02, 01, 00, 02] +Raw bytes (106): 0x[01, 01, 0b, 05, 00, 0d, 11, 0d, 23, 11, 15, 11, 15, 0d, 23, 11, 15, 0d, 23, 11, 15, 19, 1d, 25, 29, 10, 01, 07, 01, 01, 16, 01, 07, 0b, 00, 2e, 0d, 01, 27, 00, 29, 03, 01, 0e, 00, 34, 0d, 02, 0b, 00, 2e, 06, 01, 22, 00, 27, 1e, 00, 2c, 00, 2e, 23, 01, 0e, 00, 34, 1e, 03, 09, 00, 16, 1e, 08, 0b, 00, 2e, 21, 01, 27, 00, 29, 27, 01, 0e, 00, 34, 21, 02, 0b, 00, 2e, 2d, 01, 27, 00, 29, 2b, 01, 0e, 00, 34, 2d, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 11 - expression 0 operands: lhs = Counter(1), rhs = Zero - expression 1 operands: lhs = Counter(3), rhs = Counter(4) -- expression 2 operands: lhs = Expression(8, Sub), rhs = Counter(5) -- expression 3 operands: lhs = Counter(3), rhs = Counter(4) +- expression 2 operands: lhs = Counter(3), rhs = Expression(8, Add) +- expression 3 operands: lhs = Counter(4), rhs = Counter(5) - expression 4 operands: lhs = Counter(4), rhs = Counter(5) -- expression 5 operands: lhs = Expression(8, Sub), rhs = Counter(5) -- expression 6 operands: lhs = Counter(3), rhs = Counter(4) -- expression 7 operands: lhs = Expression(8, Sub), rhs = Counter(5) -- expression 8 operands: lhs = Counter(3), rhs = Counter(4) +- expression 5 operands: lhs = Counter(3), rhs = Expression(8, Add) +- expression 6 operands: lhs = Counter(4), rhs = Counter(5) +- expression 7 operands: lhs = Counter(3), rhs = Expression(8, Add) +- expression 8 operands: lhs = Counter(4), rhs = Counter(5) - expression 9 operands: lhs = Counter(6), rhs = Counter(7) - expression 10 operands: lhs = Counter(9), rhs = Counter(10) Number of file 0 mappings: 16 @@ -21,16 +21,16 @@ Number of file 0 mappings: 16 - Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 52) = (c1 + Zero) - Code(Counter(3)) at (prev + 2, 11) to (start + 0, 46) -- Code(Expression(8, Sub)) at (prev + 1, 34) to (start + 0, 39) +- Code(Expression(1, Sub)) at (prev + 1, 34) to (start + 0, 39) = (c3 - c4) - Code(Expression(7, Sub)) at (prev + 0, 44) to (start + 0, 46) - = ((c3 - c4) - c5) -- Code(Expression(4, Add)) at (prev + 1, 14) to (start + 0, 52) + = (c3 - (c4 + c5)) +- Code(Expression(8, Add)) at (prev + 1, 14) to (start + 0, 52) = (c4 + c5) - Code(Expression(7, Sub)) at (prev + 3, 9) to (start + 0, 22) - = ((c3 - c4) - c5) + = (c3 - (c4 + c5)) - Code(Expression(7, Sub)) at (prev + 8, 11) to (start + 0, 46) - = ((c3 - c4) - c5) + = (c3 - (c4 + c5)) - Code(Counter(8)) at (prev + 1, 39) to (start + 0, 41) - Code(Expression(9, Add)) at (prev + 1, 14) to (start + 0, 52) = (c6 + c7) diff --git a/tests/crashes/121429.rs b/tests/crashes/121429.rs index 09bd343e0ba..e407754db5c 100644 --- a/tests/crashes/121429.rs +++ b/tests/crashes/121429.rs @@ -1,14 +1,11 @@ //@ known-bug: #121429 -#![feature(generic_const_exprs)] - -pub trait True {} -impl<const N: usize = { const { 3 } }> PartialEq<FixedI8<FRAC_RHS>> for FixedI8<FRAC_LHS> where - If<{}>: True -{ -} #![feature(generic_const_exprs)] +struct FixedI8<const X: usize>; +const FRAC_LHS: usize = 0; +const FRAC_RHS: usize = 1; + pub trait True {} impl<const N: usize = { const { 3 } }> PartialEq<FixedI8<FRAC_RHS>> for FixedI8<FRAC_LHS> where diff --git a/tests/crashes/124020.rs b/tests/crashes/124020.rs index f461f32f59d..1b875497465 100644 --- a/tests/crashes/124020.rs +++ b/tests/crashes/124020.rs @@ -1,7 +1,7 @@ //@ known-bug: #124020 //@ compile-flags: -Zpolymorphize=on --edition=2018 --crate-type=lib -#![feature(async_closure, noop_waker, async_fn_traits)] +#![feature(async_closure, noop_waker, async_trait_bounds)] use std::future::Future; use std::pin::pin; @@ -19,7 +19,7 @@ pub fn block_on<T>(fut: impl Future<Output = T>) -> T { } } -async fn call_once(f: impl async FnOnce(DropMe)) { +async fn call_once(f: impl AsyncFnOnce(DropMe)) { f(DropMe("world")).await; } diff --git a/tests/crashes/125476.rs b/tests/crashes/125476.rs deleted file mode 100644 index ad739639b72..00000000000 --- a/tests/crashes/125476.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: rust-lang/rust#125476 -//@ only-x86_64 -pub struct Data([u8; usize::MAX >> 2]); -const _: &'static [Data] = &[]; diff --git a/tests/crashes/126267.rs b/tests/crashes/126267.rs deleted file mode 100644 index 728578179ed..00000000000 --- a/tests/crashes/126267.rs +++ /dev/null @@ -1,30 +0,0 @@ -//@ known-bug: rust-lang/rust#126267 - -#![feature(transmutability)] -#![crate_type = "lib"] - -pub enum ApiError {} -pub struct TokioError { - b: bool, -} -pub enum Error { - Api { source: ApiError }, - Ethereum, - Tokio { source: TokioError }, -} - -mod assert { - use std::mem::TransmuteFrom; - - pub fn is_transmutable<Src, Dst>() - where - Dst: TransmuteFrom<Src>, // safety is NOT assumed - { - } -} - -fn test() { - struct Src; - type Dst = Error; - assert::is_transmutable::<Src, Dst>(); -} diff --git a/tests/crashes/128176.rs b/tests/crashes/128176.rs deleted file mode 100644 index 970ad9ff2cd..00000000000 --- a/tests/crashes/128176.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: rust-lang/rust#128176 - -#![feature(generic_const_exprs)] -#![feature(dyn_compatible_for_dispatch)] -trait X { - type Y<const N: i16>; -} - -const _: () = { - fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {} -}; - -fn main() {} diff --git a/tests/crashes/131538.rs b/tests/crashes/131538.rs deleted file mode 100644 index f971d8b7791..00000000000 --- a/tests/crashes/131538.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #131538 -#![feature(generic_associated_types_extended)] -#![feature(trivial_bounds)] - -trait HealthCheck { - async fn check<const N: usize>(); -} - -fn do_health_check_par() -where - HealthCheck: HealthCheck, -{ -} diff --git a/tests/crashes/132320.rs b/tests/crashes/132320.rs deleted file mode 100644 index 79181c3a2c5..00000000000 --- a/tests/crashes/132320.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #132320 -//@ compile-flags: -Znext-solver=globally - -trait Foo { - type Item; - fn foo(&mut self); -} - -impl Foo for () { - type Item = Option<()>; - - fn foo(&mut self) { - let _ = Self::Item::None; - } -} diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff index cbb11d50f79..8dd23e4d6a3 100644 --- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff @@ -30,15 +30,12 @@ + coverage ExpressionId(0) => Expression { lhs: Counter(1), op: Add, rhs: Counter(2) }; + coverage ExpressionId(1) => Expression { lhs: Expression(0), op: Add, rhs: Counter(3) }; + coverage ExpressionId(2) => Expression { lhs: Counter(0), op: Subtract, rhs: Expression(1) }; -+ coverage ExpressionId(3) => Expression { lhs: Counter(3), op: Add, rhs: Counter(2) }; -+ coverage ExpressionId(4) => Expression { lhs: Expression(3), op: Add, rhs: Counter(1) }; -+ coverage ExpressionId(5) => Expression { lhs: Expression(4), op: Add, rhs: Expression(2) }; + coverage Code(Counter(0)) => 14:1 - 15:21; -+ coverage Code(Counter(3)) => 16:17 - 16:33; ++ coverage Code(Counter(1)) => 16:17 - 16:33; + coverage Code(Counter(2)) => 17:17 - 17:33; -+ coverage Code(Counter(1)) => 18:17 - 18:33; ++ coverage Code(Counter(3)) => 18:17 - 18:33; + coverage Code(Expression(2)) => 19:17 - 19:33; -+ coverage Code(Expression(5)) => 21:1 - 21:2; ++ coverage Code(Counter(0)) => 21:1 - 21:2; + bb0: { + Coverage::CounterIncrement(0); @@ -55,7 +52,7 @@ } bb2: { -+ Coverage::CounterIncrement(3); ++ Coverage::CounterIncrement(1); falseEdge -> [real: bb8, imaginary: bb3]; } @@ -65,7 +62,7 @@ } bb4: { -+ Coverage::CounterIncrement(1); ++ Coverage::CounterIncrement(3); falseEdge -> [real: bb6, imaginary: bb5]; } @@ -127,7 +124,6 @@ } bb13: { -+ Coverage::ExpressionUsed(5); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow.main.maybe_init.borrowck.dot b/tests/mir-opt/dataflow.main.maybe_init.borrowck.dot new file mode 100644 index 00000000000..7c7d8921fb3 --- /dev/null +++ b/tests/mir-opt/dataflow.main.maybe_init.borrowck.dot @@ -0,0 +1,6 @@ +digraph graph_for_def_id_0_3 { + graph[fontname="Courier, monospace"]; + node[fontname="Courier, monospace"]; + edge[fontname="Courier, monospace"]; + bb_0[label=<<table border="1" cellborder="1" cellspacing="0" cellpadding="3" sides="rb"><tr><td colspan="3" sides="tl">bb0</td></tr><tr><td colspan="2" bgcolor="#a0a0a0" sides="tl">MIR</td><td bgcolor="#a0a0a0" sides="tl">STATE</td></tr><tr><td valign="bottom" sides="tl" align="right"></td><td valign="bottom" sides="tl" align="left">(on start)</td><td colspan="1" valign="bottom" sides="tl" align="left">{}</td></tr><tr><td valign="top" sides="tl" bgcolor="#f0f0f0" align="right">0</td><td valign="top" sides="tl" bgcolor="#f0f0f0" align="left">_0 = const ()</td><td valign="top" sides="tl" bgcolor="#f0f0f0" align="left"><font color="darkgreen">+_0</font></td></tr><tr><td valign="top" sides="tl" align="right">T</td><td valign="top" sides="tl" align="left">return</td><td valign="top" sides="tl" align="left"></td></tr><tr><td valign="bottom" sides="tl" bgcolor="#f0f0f0" align="right"></td><td valign="bottom" sides="tl" bgcolor="#f0f0f0" align="left">(on end)</td><td colspan="1" valign="bottom" sides="tl" bgcolor="#f0f0f0" align="left">{_0}</td></tr></table>>][shape="none"]; +} diff --git a/tests/mir-opt/dataflow.rs b/tests/mir-opt/dataflow.rs new file mode 100644 index 00000000000..3a28f5d47b9 --- /dev/null +++ b/tests/mir-opt/dataflow.rs @@ -0,0 +1,6 @@ +// skip-filecheck +// Test graphviz dataflow output +//@ compile-flags: -Z dump-mir=main -Z dump-mir-dataflow + +// EMIT_MIR dataflow.main.maybe_init.borrowck.dot +fn main() {} diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff index 87fbcca9177..027c71dfaae 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff @@ -31,7 +31,6 @@ } } scope 9 (inlined NonNull::<[u8]>::as_ptr) { - let mut _17: *const [u8]; } } scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) { @@ -102,16 +101,9 @@ StorageDead(_16); StorageDead(_12); StorageDead(_6); -- StorageLive(_17); -+ nop; - _17 = copy (_5.0: *const [u8]); -- _4 = move _17 as *mut [u8] (PtrToPtr); -- StorageDead(_17); -+ _4 = copy _17 as *mut [u8] (PtrToPtr); -+ nop; + _4 = copy _5 as *mut [u8] (Transmute); StorageDead(_5); -- _3 = move _4 as *mut u8 (PtrToPtr); -+ _3 = copy _17 as *mut u8 (PtrToPtr); + _3 = move _4 as *mut u8 (PtrToPtr); StorageDead(_4); StorageDead(_3); - StorageDead(_1); diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff index 5fcece2280d..88bd4628c29 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff @@ -20,7 +20,6 @@ scope 5 (inlined <std::alloc::Global as Allocator>::allocate) { } scope 6 (inlined NonNull::<[u8]>::as_ptr) { - let mut _12: *const [u8]; } } scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) { @@ -45,16 +44,9 @@ bb1: { StorageDead(_6); -- StorageLive(_12); -+ nop; - _12 = copy (_5.0: *const [u8]); -- _4 = move _12 as *mut [u8] (PtrToPtr); -- StorageDead(_12); -+ _4 = copy _12 as *mut [u8] (PtrToPtr); -+ nop; + _4 = copy _5 as *mut [u8] (Transmute); StorageDead(_5); -- _3 = move _4 as *mut u8 (PtrToPtr); -+ _3 = copy _12 as *mut u8 (PtrToPtr); + _3 = move _4 as *mut u8 (PtrToPtr); StorageDead(_4); StorageDead(_3); - StorageDead(_1); diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff index 13258c17160..ebf305a6f1b 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff @@ -31,7 +31,6 @@ } } scope 9 (inlined NonNull::<[u8]>::as_ptr) { - let mut _17: *const [u8]; } } scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) { @@ -102,16 +101,9 @@ StorageDead(_16); StorageDead(_12); StorageDead(_6); -- StorageLive(_17); -+ nop; - _17 = copy (_5.0: *const [u8]); -- _4 = move _17 as *mut [u8] (PtrToPtr); -- StorageDead(_17); -+ _4 = copy _17 as *mut [u8] (PtrToPtr); -+ nop; + _4 = copy _5 as *mut [u8] (Transmute); StorageDead(_5); -- _3 = move _4 as *mut u8 (PtrToPtr); -+ _3 = copy _17 as *mut u8 (PtrToPtr); + _3 = move _4 as *mut u8 (PtrToPtr); StorageDead(_4); StorageDead(_3); - StorageDead(_1); diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff index 0821ea272bf..0c52f1e0583 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff @@ -20,7 +20,6 @@ scope 5 (inlined <std::alloc::Global as Allocator>::allocate) { } scope 6 (inlined NonNull::<[u8]>::as_ptr) { - let mut _12: *const [u8]; } } scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) { @@ -45,16 +44,9 @@ bb1: { StorageDead(_6); -- StorageLive(_12); -+ nop; - _12 = copy (_5.0: *const [u8]); -- _4 = move _12 as *mut [u8] (PtrToPtr); -- StorageDead(_12); -+ _4 = copy _12 as *mut [u8] (PtrToPtr); -+ nop; + _4 = copy _5 as *mut [u8] (Transmute); StorageDead(_5); -- _3 = move _4 as *mut u8 (PtrToPtr); -+ _3 = copy _12 as *mut u8 (PtrToPtr); + _3 = move _4 as *mut u8 (PtrToPtr); StorageDead(_4); StorageDead(_3); - StorageDead(_1); diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index bd56ab67e00..a3308cc5df1 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -4,28 +4,28 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>; - let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>; - let mut _21: std::option::Option<(usize, &T)>; - let mut _24: &impl Fn(usize, &T); - let mut _25: (usize, &T); - let _26: (); + let mut _13: std::slice::Iter<'_, T>; + let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>; + let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>; + let mut _23: std::option::Option<(usize, &T)>; + let mut _26: &impl Fn(usize, &T); + let mut _27: (usize, &T); + let _28: (); scope 1 { - debug iter => _13; - let _22: usize; - let _23: &T; + debug iter => _15; + let _24: usize; + let _25: &T; scope 2 { - debug i => _22; - debug x => _23; + debug i => _24; + debug x => _25; } scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; - let mut _15: std::option::Option<&T>; - let mut _19: (usize, bool); - let mut _20: (usize, &T); + let mut _16: &mut std::slice::Iter<'_, T>; + let mut _17: std::option::Option<&T>; + let mut _21: (usize, bool); + let mut _22: (usize, &T); scope 19 { - let _18: usize; + let _20: usize; scope 24 { } } @@ -40,8 +40,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 25 (inlined <Option<&T> as Try>::branch) { - let mut _16: isize; - let _17: &T; + let mut _18: isize; + let _19: &T; scope 26 { } } @@ -50,13 +50,14 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { scope 3 (inlined core::slice::<impl [T]>::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _5: std::ptr::NonNull<[T]>; + let mut _9: *mut T; + let mut _10: *mut T; + let mut _12: *const T; scope 5 { - let _6: std::ptr::NonNull<T>; + let _8: std::ptr::NonNull<T>; scope 6 { - let _9: *const T; + let _11: *const T; scope 7 { } scope 12 (inlined without_provenance::<T>) { @@ -72,7 +73,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::<T>) { - let mut _5: *const T; + let mut _6: *mut [T]; + let mut _7: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -87,76 +89,82 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_13); StorageLive(_3); - StorageLive(_6); - StorageLive(_4); - StorageLive(_5); + StorageLive(_8); _3 = PtrMetadata(copy _1); + StorageLive(_5); + StorageLive(_4); _4 = &raw const (*_1); - _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull::<T> { pointer: copy _5 }; - StorageLive(_9); + _5 = NonNull::<[T]> { pointer: move _4 }; + StorageDead(_4); + StorageLive(_6); + StorageLive(_7); + _6 = copy _5 as *mut [T] (Transmute); + _7 = copy _6 as *const T (PtrToPtr); + _8 = NonNull::<T> { pointer: move _7 }; + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + StorageLive(_10); + StorageLive(_9); + _9 = copy _8 as *mut T (Transmute); + _10 = Offset(copy _9, copy _3); + StorageDead(_9); + _11 = move _10 as *const T (PtrToPtr); + StorageDead(_10); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _11 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); - StorageDead(_5); - StorageDead(_4); - StorageDead(_6); - StorageDead(_3); - _12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize }; + StorageLive(_12); + _12 = copy _11; + _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_12); StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + StorageDead(_8); + StorageDead(_3); + _14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize }; + StorageDead(_13); + StorageLive(_15); + _15 = copy _14; goto -> bb4; } bb4: { + StorageLive(_23); + StorageLive(_20); StorageLive(_21); - StorageLive(_18); - StorageLive(_19); - StorageLive(_15); - StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = <std::slice::Iter<'_, T> as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; + StorageLive(_17); + StorageLive(_16); + _16 = &mut (_15.0: std::slice::Iter<'_, T>); + _17 = <std::slice::Iter<'_, T> as Iterator>::next(move _16) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_14); - StorageLive(_16); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11]; + StorageDead(_16); + StorageLive(_18); + _18 = discriminant(_17); + switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb11]; } bb6: { - StorageDead(_16); - StorageDead(_15); - StorageDead(_19); StorageDead(_18); + StorageDead(_17); StorageDead(_21); - StorageDead(_13); + StorageDead(_20); + StorageDead(_23); + StorageDead(_15); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -165,35 +173,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _17 = move ((_15 as Some).0: &T); - StorageDead(_16); - StorageDead(_15); - _18 = copy (_13.1: usize); - _19 = AddWithOverflow(copy (_13.1: usize), const 1_usize); - assert(!move (_19.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_13.1: usize), const 1_usize) -> [success: bb9, unwind unreachable]; + _19 = move ((_17 as Some).0: &T); + StorageDead(_18); + StorageDead(_17); + _20 = copy (_15.1: usize); + _21 = AddWithOverflow(copy (_15.1: usize), const 1_usize); + assert(!move (_21.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_15.1: usize), const 1_usize) -> [success: bb9, unwind unreachable]; } bb9: { - (_13.1: usize) = move (_19.0: usize); - StorageLive(_20); - _20 = (copy _18, copy _17); - _21 = Option::<(usize, &T)>::Some(move _20); + (_15.1: usize) = move (_21.0: usize); + StorageLive(_22); + _22 = (copy _20, copy _19); + _23 = Option::<(usize, &T)>::Some(move _22); + StorageDead(_22); + StorageDead(_21); StorageDead(_20); - StorageDead(_19); - StorageDead(_18); - _22 = copy (((_21 as Some).0: (usize, &T)).0: usize); - _23 = copy (((_21 as Some).0: (usize, &T)).1: &T); - StorageLive(_24); - _24 = &_2; - StorageLive(_25); - _25 = (copy _22, copy _23); - _26 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _24, move _25) -> [return: bb10, unwind unreachable]; + _24 = copy (((_23 as Some).0: (usize, &T)).0: usize); + _25 = copy (((_23 as Some).0: (usize, &T)).1: &T); + StorageLive(_26); + _26 = &_2; + StorageLive(_27); + _27 = (copy _24, copy _25); + _28 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _26, move _27) -> [return: bb10, unwind unreachable]; } bb10: { - StorageDead(_25); - StorageDead(_24); - StorageDead(_21); + StorageDead(_27); + StorageDead(_26); + StorageDead(_23); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 57f09a4631b..2a837fabd4c 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -4,34 +4,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>; - let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>; - let mut _14: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>; - let mut _15: std::option::Option<(usize, &T)>; - let mut _16: isize; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _13: std::slice::Iter<'_, T>; + let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>; + let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>; + let mut _16: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>; + let mut _17: std::option::Option<(usize, &T)>; + let mut _18: isize; + let mut _21: &impl Fn(usize, &T); + let mut _22: (usize, &T); + let _23: (); scope 1 { - debug iter => _13; - let _17: usize; - let _18: &T; + debug iter => _15; + let _19: usize; + let _20: &T; scope 2 { - debug i => _17; - debug x => _18; + debug i => _19; + debug x => _20; } } scope 3 (inlined core::slice::<impl [T]>::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _5: std::ptr::NonNull<[T]>; + let mut _9: *mut T; + let mut _10: *mut T; + let mut _12: *const T; scope 5 { - let _6: std::ptr::NonNull<T>; + let _8: std::ptr::NonNull<T>; scope 6 { - let _9: *const T; + let _11: *const T; scope 7 { } scope 12 (inlined without_provenance::<T>) { @@ -47,7 +48,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::<T>) { - let mut _5: *const T; + let mut _6: *mut [T]; + let mut _7: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -62,66 +64,72 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_13); StorageLive(_3); - StorageLive(_6); - StorageLive(_4); - StorageLive(_5); + StorageLive(_8); _3 = PtrMetadata(copy _1); + StorageLive(_5); + StorageLive(_4); _4 = &raw const (*_1); - _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull::<T> { pointer: copy _5 }; - StorageLive(_9); + _5 = NonNull::<[T]> { pointer: move _4 }; + StorageDead(_4); + StorageLive(_6); + StorageLive(_7); + _6 = copy _5 as *mut [T] (Transmute); + _7 = copy _6 as *const T (PtrToPtr); + _8 = NonNull::<T> { pointer: move _7 }; + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + StorageLive(_10); + StorageLive(_9); + _9 = copy _8 as *mut T (Transmute); + _10 = Offset(copy _9, copy _3); + StorageDead(_9); + _11 = move _10 as *const T (PtrToPtr); + StorageDead(_10); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _11 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); - StorageDead(_5); - StorageDead(_4); - StorageDead(_6); - StorageDead(_3); - _12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize }; + StorageLive(_12); + _12 = copy _11; + _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_12); StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + StorageDead(_8); + StorageDead(_3); + _14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize }; + StorageDead(_13); + StorageLive(_15); + _15 = copy _14; goto -> bb4; } bb4: { - StorageLive(_15); - _14 = &mut _13; - _15 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; + StorageLive(_17); + _16 = &mut _15; + _17 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _16) -> [return: bb5, unwind: bb11]; } bb5: { - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + _18 = discriminant(_17); + switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { + StorageDead(_17); StorageDead(_15); - StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -130,19 +138,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _17 = copy (((_15 as Some).0: (usize, &T)).0: usize); - _18 = copy (((_15 as Some).0: (usize, &T)).1: &T); - StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (copy _17, copy _18); - _21 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11]; + _19 = copy (((_17 as Some).0: (usize, &T)).0: usize); + _20 = copy (((_17 as Some).0: (usize, &T)).1: &T); + StorageLive(_21); + _21 = &_2; + StorageLive(_22); + _22 = (copy _19, copy _20); + _23 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_20); - StorageDead(_19); - StorageDead(_15); + StorageDead(_22); + StorageDead(_21); + StorageDead(_17); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 4050304f469..063045caebb 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -4,31 +4,32 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::slice::Iter<'_, T>; - let mut _13: &mut std::slice::Iter<'_, T>; - let mut _14: std::option::Option<&T>; - let mut _15: isize; - let mut _17: &impl Fn(&T); - let mut _18: (&T,); - let _19: (); + let mut _13: std::slice::Iter<'_, T>; + let mut _14: std::slice::Iter<'_, T>; + let mut _15: &mut std::slice::Iter<'_, T>; + let mut _16: std::option::Option<&T>; + let mut _17: isize; + let mut _19: &impl Fn(&T); + let mut _20: (&T,); + let _21: (); scope 1 { - debug iter => _12; - let _16: &T; + debug iter => _14; + let _18: &T; scope 2 { - debug x => _16; + debug x => _18; } } scope 3 (inlined core::slice::<impl [T]>::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _5: std::ptr::NonNull<[T]>; + let mut _9: *mut T; + let mut _10: *mut T; + let mut _12: *const T; scope 5 { - let _6: std::ptr::NonNull<T>; + let _8: std::ptr::NonNull<T>; scope 6 { - let _9: *const T; + let _11: *const T; scope 7 { } scope 12 (inlined without_provenance::<T>) { @@ -44,7 +45,8 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::<T>) { - let mut _5: *const T; + let mut _6: *mut [T]; + let mut _7: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -56,62 +58,68 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb0: { StorageLive(_3); - StorageLive(_6); - StorageLive(_4); - StorageLive(_5); + StorageLive(_8); _3 = PtrMetadata(copy _1); + StorageLive(_5); + StorageLive(_4); _4 = &raw const (*_1); - _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull::<T> { pointer: copy _5 }; - StorageLive(_9); + _5 = NonNull::<[T]> { pointer: move _4 }; + StorageDead(_4); + StorageLive(_6); + StorageLive(_7); + _6 = copy _5 as *mut [T] (Transmute); + _7 = copy _6 as *const T (PtrToPtr); + _8 = NonNull::<T> { pointer: move _7 }; + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + StorageLive(_10); + StorageLive(_9); + _9 = copy _8 as *mut T (Transmute); + _10 = Offset(copy _9, copy _3); + StorageDead(_9); + _11 = move _10 as *const T (PtrToPtr); + StorageDead(_10); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _11 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); - StorageDead(_5); - StorageDead(_4); - StorageDead(_6); - StorageDead(_3); StorageLive(_12); _12 = copy _11; + _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_12); + StorageDead(_11); + StorageDead(_8); + StorageDead(_3); + StorageLive(_14); + _14 = copy _13; goto -> bb4; } bb4: { - StorageLive(_14); - _13 = &mut _12; - _14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind unreachable]; + StorageLive(_16); + _15 = &mut _14; + _16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind unreachable]; } bb5: { - _15 = discriminant(_14); - switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + _17 = discriminant(_16); + switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { + StorageDead(_16); StorageDead(_14); - StorageDead(_12); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -120,18 +128,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _16 = copy ((_14 as Some).0: &T); - StorageLive(_17); - _17 = &_2; - StorageLive(_18); - _18 = (copy _16,); - _19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind unreachable]; + _18 = copy ((_16 as Some).0: &T); + StorageLive(_19); + _19 = &_2; + StorageLive(_20); + _20 = (copy _18,); + _21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_18); - StorageDead(_17); - StorageDead(_14); + StorageDead(_20); + StorageDead(_19); + StorageDead(_16); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 2c3d7ab1e4a..d401ed8fcf3 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -4,31 +4,32 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::slice::Iter<'_, T>; - let mut _13: &mut std::slice::Iter<'_, T>; - let mut _14: std::option::Option<&T>; - let mut _15: isize; - let mut _17: &impl Fn(&T); - let mut _18: (&T,); - let _19: (); + let mut _13: std::slice::Iter<'_, T>; + let mut _14: std::slice::Iter<'_, T>; + let mut _15: &mut std::slice::Iter<'_, T>; + let mut _16: std::option::Option<&T>; + let mut _17: isize; + let mut _19: &impl Fn(&T); + let mut _20: (&T,); + let _21: (); scope 1 { - debug iter => _12; - let _16: &T; + debug iter => _14; + let _18: &T; scope 2 { - debug x => _16; + debug x => _18; } } scope 3 (inlined core::slice::<impl [T]>::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _5: std::ptr::NonNull<[T]>; + let mut _9: *mut T; + let mut _10: *mut T; + let mut _12: *const T; scope 5 { - let _6: std::ptr::NonNull<T>; + let _8: std::ptr::NonNull<T>; scope 6 { - let _9: *const T; + let _11: *const T; scope 7 { } scope 12 (inlined without_provenance::<T>) { @@ -44,7 +45,8 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::<T>) { - let mut _5: *const T; + let mut _6: *mut [T]; + let mut _7: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -56,62 +58,68 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb0: { StorageLive(_3); - StorageLive(_6); - StorageLive(_4); - StorageLive(_5); + StorageLive(_8); _3 = PtrMetadata(copy _1); + StorageLive(_5); + StorageLive(_4); _4 = &raw const (*_1); - _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull::<T> { pointer: copy _5 }; - StorageLive(_9); + _5 = NonNull::<[T]> { pointer: move _4 }; + StorageDead(_4); + StorageLive(_6); + StorageLive(_7); + _6 = copy _5 as *mut [T] (Transmute); + _7 = copy _6 as *const T (PtrToPtr); + _8 = NonNull::<T> { pointer: move _7 }; + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + StorageLive(_10); + StorageLive(_9); + _9 = copy _8 as *mut T (Transmute); + _10 = Offset(copy _9, copy _3); + StorageDead(_9); + _11 = move _10 as *const T (PtrToPtr); + StorageDead(_10); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _11 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); - StorageDead(_5); - StorageDead(_4); - StorageDead(_6); - StorageDead(_3); StorageLive(_12); _12 = copy _11; + _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_12); + StorageDead(_11); + StorageDead(_8); + StorageDead(_3); + StorageLive(_14); + _14 = copy _13; goto -> bb4; } bb4: { - StorageLive(_14); - _13 = &mut _12; - _14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; + StorageLive(_16); + _15 = &mut _14; + _16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind: bb11]; } bb5: { - _15 = discriminant(_14); - switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + _17 = discriminant(_16); + switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { + StorageDead(_16); StorageDead(_14); - StorageDead(_12); drop(_2) -> [return: bb7, unwind continue]; } @@ -120,18 +128,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _16 = copy ((_14 as Some).0: &T); - StorageLive(_17); - _17 = &_2; - StorageLive(_18); - _18 = (copy _16,); - _19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind: bb11]; + _18 = copy ((_16 as Some).0: &T); + StorageLive(_19); + _19 = &_2; + StorageLive(_20); + _20 = (copy _18,); + _21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_18); - StorageDead(_17); - StorageDead(_14); + StorageDead(_20); + StorageDead(_19); + StorageDead(_16); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index a6ccd435c40..deb12c4f1c2 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -4,34 +4,35 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>; - let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _13: std::slice::Iter<'_, T>; + let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>; + let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>; + let mut _17: std::option::Option<&T>; + let mut _18: isize; + let mut _20: &impl Fn(&T); + let mut _21: (&T,); + let _22: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _15; + let _19: &T; scope 2 { - debug x => _17; + debug x => _19; } scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + let mut _16: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::<impl [T]>::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _5: std::ptr::NonNull<[T]>; + let mut _9: *mut T; + let mut _10: *mut T; + let mut _12: *const T; scope 5 { - let _6: std::ptr::NonNull<T>; + let _8: std::ptr::NonNull<T>; scope 6 { - let _9: *const T; + let _11: *const T; scope 7 { } scope 12 (inlined without_provenance::<T>) { @@ -47,7 +48,8 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::<T>) { - let mut _5: *const T; + let mut _6: *mut [T]; + let mut _7: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -62,68 +64,74 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_13); StorageLive(_3); - StorageLive(_6); - StorageLive(_4); - StorageLive(_5); + StorageLive(_8); _3 = PtrMetadata(copy _1); + StorageLive(_5); + StorageLive(_4); _4 = &raw const (*_1); - _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull::<T> { pointer: copy _5 }; - StorageLive(_9); + _5 = NonNull::<[T]> { pointer: move _4 }; + StorageDead(_4); + StorageLive(_6); + StorageLive(_7); + _6 = copy _5 as *mut [T] (Transmute); + _7 = copy _6 as *const T (PtrToPtr); + _8 = NonNull::<T> { pointer: move _7 }; + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + StorageLive(_10); + StorageLive(_9); + _9 = copy _8 as *mut T (Transmute); + _10 = Offset(copy _9, copy _3); + StorageDead(_9); + _11 = move _10 as *const T (PtrToPtr); + StorageDead(_10); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _11 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); - StorageDead(_5); - StorageDead(_4); - StorageDead(_6); - StorageDead(_3); - _12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 }; + StorageLive(_12); + _12 = copy _11; + _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_12); StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + StorageDead(_8); + StorageDead(_3); + _14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 }; + StorageDead(_13); + StorageLive(_15); + _15 = copy _14; goto -> bb4; } bb4: { - StorageLive(_15); - StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; + StorageLive(_17); + StorageLive(_16); + _16 = &mut (_15.0: std::slice::Iter<'_, T>); + _17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_16); + _18 = discriminant(_17); + switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { + StorageDead(_17); StorageDead(_15); - StorageDead(_13); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -132,18 +140,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = copy ((_15 as Some).0: &T); - StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (copy _17,); - _20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind unreachable]; + _19 = copy ((_17 as Some).0: &T); + StorageLive(_20); + _20 = &_2; + StorageLive(_21); + _21 = (copy _19,); + _22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_19); - StorageDead(_18); - StorageDead(_15); + StorageDead(_21); + StorageDead(_20); + StorageDead(_17); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index df11c8e3b49..acd5323eb7a 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -4,34 +4,35 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>; - let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _13: std::slice::Iter<'_, T>; + let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>; + let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>; + let mut _17: std::option::Option<&T>; + let mut _18: isize; + let mut _20: &impl Fn(&T); + let mut _21: (&T,); + let _22: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _15; + let _19: &T; scope 2 { - debug x => _17; + debug x => _19; } scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + let mut _16: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::<impl [T]>::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _5: std::ptr::NonNull<[T]>; + let mut _9: *mut T; + let mut _10: *mut T; + let mut _12: *const T; scope 5 { - let _6: std::ptr::NonNull<T>; + let _8: std::ptr::NonNull<T>; scope 6 { - let _9: *const T; + let _11: *const T; scope 7 { } scope 12 (inlined without_provenance::<T>) { @@ -47,7 +48,8 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::<T>) { - let mut _5: *const T; + let mut _6: *mut [T]; + let mut _7: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -62,68 +64,74 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_13); StorageLive(_3); - StorageLive(_6); - StorageLive(_4); - StorageLive(_5); + StorageLive(_8); _3 = PtrMetadata(copy _1); + StorageLive(_5); + StorageLive(_4); _4 = &raw const (*_1); - _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull::<T> { pointer: copy _5 }; - StorageLive(_9); + _5 = NonNull::<[T]> { pointer: move _4 }; + StorageDead(_4); + StorageLive(_6); + StorageLive(_7); + _6 = copy _5 as *mut [T] (Transmute); + _7 = copy _6 as *const T (PtrToPtr); + _8 = NonNull::<T> { pointer: move _7 }; + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + StorageLive(_10); + StorageLive(_9); + _9 = copy _8 as *mut T (Transmute); + _10 = Offset(copy _9, copy _3); + StorageDead(_9); + _11 = move _10 as *const T (PtrToPtr); + StorageDead(_10); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _11 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); - StorageDead(_5); - StorageDead(_4); - StorageDead(_6); - StorageDead(_3); - _12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 }; + StorageLive(_12); + _12 = copy _11; + _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_12); StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + StorageDead(_8); + StorageDead(_3); + _14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 }; + StorageDead(_13); + StorageLive(_15); + _15 = copy _14; goto -> bb4; } bb4: { - StorageLive(_15); - StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; + StorageLive(_17); + StorageLive(_16); + _16 = &mut (_15.0: std::slice::Iter<'_, T>); + _17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_16); + _18 = discriminant(_17); + switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { + StorageDead(_17); StorageDead(_15); - StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -132,18 +140,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = copy ((_15 as Some).0: &T); - StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (copy _17,); - _20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind: bb11]; + _19 = copy ((_17 as Some).0: &T); + StorageLive(_20); + _20 = &_2; + StorageLive(_21); + _21 = (copy _19,); + _22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_19); - StorageDead(_18); - StorageDead(_15); + StorageDead(_21); + StorageDead(_20); + StorageDead(_17); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir index f8b0e749bfc..22be48c47b2 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir @@ -15,11 +15,11 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool { scope 4 { scope 8 (inlined <NonNull<T> as PartialEq>::eq) { let mut _5: std::ptr::NonNull<T>; + let mut _6: *mut T; + let mut _7: *mut T; scope 9 (inlined NonNull::<T>::as_ptr) { - let mut _6: *const T; } scope 10 (inlined NonNull::<T>::as_ptr) { - let mut _7: *const T; } } } @@ -48,13 +48,13 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool { _4 = copy (*_3); StorageDead(_3); StorageLive(_6); - StorageLive(_7); StorageLive(_5); _5 = copy ((*_1).0: std::ptr::NonNull<T>); - _6 = copy (_5.0: *const T); + _6 = copy _5 as *mut T (Transmute); StorageDead(_5); - _7 = copy (_4.0: *const T); - _0 = Eq(copy _6, copy _7); + StorageLive(_7); + _7 = copy _4 as *mut T (Transmute); + _0 = Eq(move _6, move _7); StorageDead(_7); StorageDead(_6); goto -> bb3; diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir index f8b0e749bfc..22be48c47b2 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir @@ -15,11 +15,11 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool { scope 4 { scope 8 (inlined <NonNull<T> as PartialEq>::eq) { let mut _5: std::ptr::NonNull<T>; + let mut _6: *mut T; + let mut _7: *mut T; scope 9 (inlined NonNull::<T>::as_ptr) { - let mut _6: *const T; } scope 10 (inlined NonNull::<T>::as_ptr) { - let mut _7: *const T; } } } @@ -48,13 +48,13 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool { _4 = copy (*_3); StorageDead(_3); StorageLive(_6); - StorageLive(_7); StorageLive(_5); _5 = copy ((*_1).0: std::ptr::NonNull<T>); - _6 = copy (_5.0: *const T); + _6 = copy _5 as *mut T (Transmute); StorageDead(_5); - _7 = copy (_4.0: *const T); - _0 = Eq(copy _6, copy _7); + StorageLive(_7); + _7 = copy _4 as *mut T (Transmute); + _0 = Eq(move _6, move _7); StorageDead(_7); StorageDead(_6); goto -> bb3; diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir index c3091bd4395..2efbb6d9904 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir @@ -7,16 +7,18 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { debug self => _1; scope 2 (inlined Vec::<u8>::as_slice) { debug self => _1; - let mut _7: usize; + let mut _9: *const u8; + let mut _10: usize; scope 3 (inlined Vec::<u8>::as_ptr) { debug self => _1; let mut _2: &alloc::raw_vec::RawVec<u8>; + let mut _8: *mut u8; scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) { debug self => _2; let mut _3: &alloc::raw_vec::RawVecInner; scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) { debug self => _3; - let mut _6: std::ptr::NonNull<u8>; + let mut _7: std::ptr::NonNull<u8>; scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) { debug self => _3; let mut _4: std::ptr::NonNull<u8>; @@ -25,27 +27,28 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>; scope 8 (inlined NonNull::<u8>::cast::<u8>) { debug self => _4; + let mut _5: *mut u8; + let mut _6: *const u8; scope 9 (inlined NonNull::<u8>::as_ptr) { debug self => _4; - let mut _5: *const u8; } } } scope 10 (inlined Unique::<u8>::as_non_null_ptr) { - debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6; + debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7; debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>; } } scope 11 (inlined NonNull::<u8>::as_ptr) { - debug self => _6; + debug self => _7; } } } } scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) { - debug data => _5; - debug len => _7; - let _8: *const [u8]; + debug data => _9; + debug len => _10; + let _11: *const [u8]; scope 13 (inlined core::ub_checks::check_language_ub) { scope 14 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -55,11 +58,11 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { scope 16 (inlined align_of::<u8>) { } scope 17 (inlined slice_from_raw_parts::<u8>) { - debug data => _5; - debug len => _7; + debug data => _9; + debug len => _10; scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { - debug data_pointer => _5; - debug metadata => _7; + debug data_pointer => _9; + debug metadata => _10; } } } @@ -67,26 +70,37 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { } bb0: { + StorageLive(_8); + StorageLive(_9); StorageLive(_2); _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>); StorageLive(_3); _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner); - StorageLive(_6); + StorageLive(_7); StorageLive(_4); _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>); - _5 = copy (_4.0: *const u8); - _6 = NonNull::<u8> { pointer: copy _5 }; - StorageDead(_4); + StorageLive(_5); + StorageLive(_6); + _5 = copy _4 as *mut u8 (Transmute); + _6 = copy _5 as *const u8 (PtrToPtr); + _7 = NonNull::<u8> { pointer: move _6 }; StorageDead(_6); + StorageDead(_5); + StorageDead(_4); + _8 = copy _7 as *mut u8 (Transmute); + StorageDead(_7); StorageDead(_3); + _9 = copy _8 as *const u8 (PtrToPtr); StorageDead(_2); - StorageLive(_7); - _7 = copy ((*_1).1: usize); - StorageLive(_8); - _8 = *const [u8] from (copy _5, copy _7); - _0 = &(*_8); + StorageLive(_10); + _10 = copy ((*_1).1: usize); + StorageLive(_11); + _11 = *const [u8] from (copy _9, copy _10); + _0 = &(*_11); + StorageDead(_11); + StorageDead(_10); + StorageDead(_9); StorageDead(_8); - StorageDead(_7); return; } } diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir index c3091bd4395..2efbb6d9904 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir @@ -7,16 +7,18 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { debug self => _1; scope 2 (inlined Vec::<u8>::as_slice) { debug self => _1; - let mut _7: usize; + let mut _9: *const u8; + let mut _10: usize; scope 3 (inlined Vec::<u8>::as_ptr) { debug self => _1; let mut _2: &alloc::raw_vec::RawVec<u8>; + let mut _8: *mut u8; scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) { debug self => _2; let mut _3: &alloc::raw_vec::RawVecInner; scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) { debug self => _3; - let mut _6: std::ptr::NonNull<u8>; + let mut _7: std::ptr::NonNull<u8>; scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) { debug self => _3; let mut _4: std::ptr::NonNull<u8>; @@ -25,27 +27,28 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>; scope 8 (inlined NonNull::<u8>::cast::<u8>) { debug self => _4; + let mut _5: *mut u8; + let mut _6: *const u8; scope 9 (inlined NonNull::<u8>::as_ptr) { debug self => _4; - let mut _5: *const u8; } } } scope 10 (inlined Unique::<u8>::as_non_null_ptr) { - debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6; + debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7; debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>; } } scope 11 (inlined NonNull::<u8>::as_ptr) { - debug self => _6; + debug self => _7; } } } } scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) { - debug data => _5; - debug len => _7; - let _8: *const [u8]; + debug data => _9; + debug len => _10; + let _11: *const [u8]; scope 13 (inlined core::ub_checks::check_language_ub) { scope 14 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -55,11 +58,11 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { scope 16 (inlined align_of::<u8>) { } scope 17 (inlined slice_from_raw_parts::<u8>) { - debug data => _5; - debug len => _7; + debug data => _9; + debug len => _10; scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { - debug data_pointer => _5; - debug metadata => _7; + debug data_pointer => _9; + debug metadata => _10; } } } @@ -67,26 +70,37 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { } bb0: { + StorageLive(_8); + StorageLive(_9); StorageLive(_2); _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>); StorageLive(_3); _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner); - StorageLive(_6); + StorageLive(_7); StorageLive(_4); _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>); - _5 = copy (_4.0: *const u8); - _6 = NonNull::<u8> { pointer: copy _5 }; - StorageDead(_4); + StorageLive(_5); + StorageLive(_6); + _5 = copy _4 as *mut u8 (Transmute); + _6 = copy _5 as *const u8 (PtrToPtr); + _7 = NonNull::<u8> { pointer: move _6 }; StorageDead(_6); + StorageDead(_5); + StorageDead(_4); + _8 = copy _7 as *mut u8 (Transmute); + StorageDead(_7); StorageDead(_3); + _9 = copy _8 as *const u8 (PtrToPtr); StorageDead(_2); - StorageLive(_7); - _7 = copy ((*_1).1: usize); - StorageLive(_8); - _8 = *const [u8] from (copy _5, copy _7); - _0 = &(*_8); + StorageLive(_10); + _10 = copy ((*_1).1: usize); + StorageLive(_11); + _11 = *const [u8] from (copy _9, copy _10); + _0 = &(*_11); + StorageDead(_11); + StorageDead(_10); + StorageDead(_9); StorageDead(_8); - StorageDead(_7); return; } } diff --git a/tests/run-make/apple-deployment-target/rmake.rs b/tests/run-make/apple-deployment-target/rmake.rs index fed6d310770..0ae95cb1f4b 100644 --- a/tests/run-make/apple-deployment-target/rmake.rs +++ b/tests/run-make/apple-deployment-target/rmake.rs @@ -24,21 +24,31 @@ fn minos(file: &str, version: &str) { fn main() { // These versions should generally be higher than the default versions - let (env_var, example_version, higher_example_version) = match apple_os() { - "macos" => ("MACOSX_DEPLOYMENT_TARGET", "12.0", "13.0"), + let (example_version, higher_example_version) = match apple_os() { + "macos" => ("12.0", "13.0"), // armv7s-apple-ios and i386-apple-ios only supports iOS 10.0 - "ios" if target() == "armv7s-apple-ios" || target() == "i386-apple-ios" => { - ("IPHONEOS_DEPLOYMENT_TARGET", "10.0", "10.0") - } - "ios" => ("IPHONEOS_DEPLOYMENT_TARGET", "15.0", "16.0"), - "watchos" => ("WATCHOS_DEPLOYMENT_TARGET", "7.0", "9.0"), - "tvos" => ("TVOS_DEPLOYMENT_TARGET", "14.0", "15.0"), - "visionos" => ("XROS_DEPLOYMENT_TARGET", "1.1", "1.2"), + "ios" if target() == "armv7s-apple-ios" || target() == "i386-apple-ios" => ("10.0", "10.0"), + "ios" => ("15.0", "16.0"), + "watchos" => ("7.0", "9.0"), + "tvos" => ("14.0", "15.0"), + "visionos" => ("1.1", "1.2"), _ => unreachable!(), }; - let default_version = - rustc().target(target()).env_remove(env_var).print("deployment-target").run().stdout_utf8(); - let default_version = default_version.strip_prefix("deployment_target=").unwrap().trim(); + + // Remove env vars to get `rustc`'s default + let output = rustc() + .target(target()) + .env_remove("MACOSX_DEPLOYMENT_TARGET") + .env_remove("IPHONEOS_DEPLOYMENT_TARGET") + .env_remove("WATCHOS_DEPLOYMENT_TARGET") + .env_remove("TVOS_DEPLOYMENT_TARGET") + .env_remove("XROS_DEPLOYMENT_TARGET") + .print("deployment-target") + .run() + .stdout_utf8(); + let (env_var, default_version) = output.split_once('=').unwrap(); + let env_var = env_var.trim(); + let default_version = default_version.trim(); // Test that version makes it to the object file. run_in_tmpdir(|| { diff --git a/tests/run-make/apple-sdk-version/rmake.rs b/tests/run-make/apple-sdk-version/rmake.rs index 6463ec00403..43e80577204 100644 --- a/tests/run-make/apple-sdk-version/rmake.rs +++ b/tests/run-make/apple-sdk-version/rmake.rs @@ -26,8 +26,7 @@ fn main() { // Fetch rustc's inferred deployment target. let current_deployment_target = rustc().target(target()).print("deployment-target").run().stdout_utf8(); - let current_deployment_target = - current_deployment_target.strip_prefix("deployment_target=").unwrap().trim(); + let current_deployment_target = current_deployment_target.split('=').last().unwrap().trim(); // Fetch current SDK version via. xcrun. // diff --git a/tests/run-make/libtest-thread-limit/rmake.rs b/tests/run-make/libtest-thread-limit/rmake.rs index 5decd802b34..fe14d2c046c 100644 --- a/tests/run-make/libtest-thread-limit/rmake.rs +++ b/tests/run-make/libtest-thread-limit/rmake.rs @@ -38,7 +38,7 @@ fn main() { // If the process ID is 0, this is the child process responsible for running the test // program. if pid == 0 { - let test = CString::new("test").unwrap(); + let test = c"test"; // The argv array should be terminated with a NULL pointer. let argv = [test.as_ptr(), std::ptr::null()]; // rlim_cur is soft limit, rlim_max is hard limit. diff --git a/tests/rustdoc-json/impls/trait-for-dyn-trait.rs b/tests/rustdoc-json/impls/trait-for-dyn-trait.rs new file mode 100644 index 00000000000..0fbb4df0028 --- /dev/null +++ b/tests/rustdoc-json/impls/trait-for-dyn-trait.rs @@ -0,0 +1,15 @@ +//@ set t1 = '$.index[*][?(@.name=="T1")].id' +pub trait T1 {} + +//@ set t2 = '$.index[*][?(@.name=="T2")].id' +pub trait T2 {} + +/// Fun impl +impl T1 for dyn T2 {} + +//@ set impl = '$.index[*][?(@.docs=="Fun impl")].id' +//@ is '$.index[*][?(@.name=="T1")].inner.trait.implementations[*]' $impl +//@ is '$.index[*][?(@.name=="T2")].inner.trait.implementations' [] + +//@ is '$.index[*][?(@.docs=="Fun impl")].inner.impl.trait.id' $t1 +//@ is '$.index[*][?(@.docs=="Fun impl")].inner.impl.for.dyn_trait.traits[*].trait.id' $t2 diff --git a/tests/rustdoc-json/statics/extern.rs b/tests/rustdoc-json/statics/extern.rs new file mode 100644 index 00000000000..d38fdf1cd1c --- /dev/null +++ b/tests/rustdoc-json/statics/extern.rs @@ -0,0 +1,39 @@ +// ignore-tidy-linelength +//@ edition: 2021 + +extern "C" { + //@ is '$.index[*][?(@.name=="A")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="A")].inner.static.is_mutable' false + pub static A: i32; + //@ is '$.index[*][?(@.name=="B")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="B")].inner.static.is_mutable' true + pub static mut B: i32; + + // items in unadorned `extern` blocks cannot have safety qualifiers +} + +unsafe extern "C" { + //@ is '$.index[*][?(@.name=="C")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="C")].inner.static.is_mutable' false + pub static C: i32; + //@ is '$.index[*][?(@.name=="D")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="D")].inner.static.is_mutable' true + pub static mut D: i32; + + //@ is '$.index[*][?(@.name=="E")].inner.static.is_unsafe' false + //@ is '$.index[*][?(@.name=="E")].inner.static.is_mutable' false + pub safe static E: i32; + //@ is '$.index[*][?(@.name=="F")].inner.static.is_unsafe' false + //@ is '$.index[*][?(@.name=="F")].inner.static.is_mutable' true + pub safe static mut F: i32; + + //@ is '$.index[*][?(@.name=="G")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="G")].inner.static.is_mutable' false + pub unsafe static G: i32; + //@ is '$.index[*][?(@.name=="H")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="H")].inner.static.is_mutable' true + pub unsafe static mut H: i32; +} + +//@ ismany '$.index[*][?(@.inner.static)].inner.static.expr' '""' '""' '""' '""' '""' '""' '""' '""' +//@ ismany '$.index[*][?(@.inner.static)].inner.static.type.primitive' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' diff --git a/tests/rustdoc-json/statics/statics.rs b/tests/rustdoc-json/statics/statics.rs new file mode 100644 index 00000000000..a8af23cc87d --- /dev/null +++ b/tests/rustdoc-json/statics/statics.rs @@ -0,0 +1,12 @@ +//@ is '$.index[*][?(@.name=="A")].inner.static.type.primitive' '"i32"' +//@ is '$.index[*][?(@.name=="A")].inner.static.is_mutable' false +//@ is '$.index[*][?(@.name=="A")].inner.static.expr' '"5"' +//@ is '$.index[*][?(@.name=="A")].inner.static.is_unsafe' false +pub static A: i32 = 5; + +//@ is '$.index[*][?(@.name=="B")].inner.static.type.primitive' '"u32"' +//@ is '$.index[*][?(@.name=="B")].inner.static.is_mutable' true +// Expr value isn't gaurenteed, it'd be fine to change it. +//@ is '$.index[*][?(@.name=="B")].inner.static.expr' '"_"' +//@ is '$.index[*][?(@.name=="B")].inner.static.is_unsafe' false +pub static mut B: u32 = 2 + 3; diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs new file mode 100644 index 00000000000..b83e576076d --- /dev/null +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -0,0 +1,228 @@ +//@ run-pass +//@ ignore-cross-compile + +// This test covers the AST pretty-printer's automatic insertion of parentheses +// into unparenthesized syntax trees according to precedence and various grammar +// restrictions and edge cases. +// +// For example if the following syntax tree represents the expression a*(b+c), +// in which the parenthesis is necessary for precedence: +// +// Binary('*', Path("a"), Paren(Binary('+', Path("b"), Path("c")))) +// +// then the pretty-printer needs to be able to print the following +// unparenthesized syntax tree with an automatically inserted parenthesization. +// +// Binary('*', Path("a"), Binary('+', Path("b"), Path("c"))) +// +// Handling this correctly is relevant in real-world code when pretty-printing +// macro-generated syntax trees, in which expressions can get interpolated into +// one another without any parenthesization being visible in the syntax tree. +// +// macro_rules! repro { +// ($rhs:expr) => { +// a * $rhs +// }; +// } +// +// let _ = repro!(b + c); + +#![feature(rustc_private)] + +extern crate rustc_ast; +extern crate rustc_ast_pretty; +extern crate rustc_driver; +extern crate rustc_errors; +extern crate rustc_parse; +extern crate rustc_session; +extern crate rustc_span; + +use std::mem; +use std::process::ExitCode; + +use rustc_ast::ast::{DUMMY_NODE_ID, Expr, ExprKind}; +use rustc_ast::mut_visit::{self, DummyAstNode as _, MutVisitor}; +use rustc_ast::node_id::NodeId; +use rustc_ast::ptr::P; +use rustc_ast_pretty::pprust; +use rustc_errors::Diag; +use rustc_parse::parser::Recovery; +use rustc_session::parse::ParseSess; +use rustc_span::{DUMMY_SP, FileName, Span}; + +// Every parenthesis in the following expressions is re-inserted by the +// pretty-printer. +// +// FIXME: Some of them shouldn't be. +static EXPRS: &[&str] = &[ + // Straightforward binary operator precedence. + "2 * 2 + 2", + "2 + 2 * 2", + "(2 + 2) * 2", + "2 * (2 + 2)", + "2 + 2 + 2", + // Return has lower precedence than a binary operator. + "(return 2) + 2", + "2 + (return 2)", // FIXME: no parenthesis needed. + "(return) + 2", // FIXME: no parenthesis needed. + // These mean different things. + "return - 2", + "(return) - 2", + // These mean different things. + "if let _ = true && false {}", + "if let _ = (true && false) {}", + // Conditions end at the first curly brace, so struct expressions need to be + // parenthesized. Except in a match guard, where conditions end at arrow. + "if let _ = (Struct {}) {}", + "match 2 { _ if let _ = Struct {} => {} }", + // Match arms terminate eagerly, so parenthesization is needed around some + // expressions. + "match 2 { _ => 1 - 1 }", + "match 2 { _ => ({ 1 }) - 1 }", + // Grammar restriction: break value starting with a labeled loop is not + // allowed, except if the break is also labeled. + "break 'outer 'inner: loop {} + 2", + "break ('inner: loop {} + 2)", + // Grammar restriction: the value in let-else is not allowed to end in a + // curly brace. + "{ let _ = 1 + 1 else {}; }", + "{ let _ = (loop {}) else {}; }", + "{ let _ = mac!() else {}; }", + "{ let _ = (mac! {}) else {}; }", + // Parentheses are necessary to prevent an eager statement boundary. + "{ 2 - 1 }", + "{ (match 2 {}) - 1 }", + "{ (match 2 {})() - 1 }", + "{ (match 2 {})[0] - 1 }", + "{ (loop {}) - 1 }", + // Angle bracket is eagerly parsed as a path's generic argument list. + "(2 as T) < U", + "(2 as T<U>) < V", // FIXME: no parentheses needed. + /* + // FIXME: pretty-printer produces invalid syntax. `2 + 2 as T < U` + "(2 + 2 as T) < U", + */ + /* + // FIXME: pretty-printer produces invalid syntax. `if (let _ = () && Struct {}.x) {}` + "if let _ = () && (Struct {}).x {}", + */ + /* + // FIXME: pretty-printer produces invalid syntax. `(1 < 2 == false) as usize` + "((1 < 2) == false) as usize", + */ + /* + // FIXME: pretty-printer produces invalid syntax. `for _ in 1..{ 2 } {}` + "for _ in (1..{ 2 }) {}", + */ + /* + // FIXME: pretty-printer loses the attribute. `{ let Struct { field } = s; }` + "{ let Struct { #[attr] field } = s; }", + */ + /* + // FIXME: pretty-printer turns this into a range. `0..to_string()` + "(0.).to_string()", + "0. .. 1.", + */ + /* + // FIXME: pretty-printer loses the dyn*. `i as Trait` + "i as dyn* Trait", + */ +]; + +// Flatten the content of parenthesis nodes into their parent node. For example +// this syntax tree representing the expression a*(b+c): +// +// Binary('*', Path("a"), Paren(Binary('+', Path("b"), Path("c")))) +// +// would unparenthesize to: +// +// Binary('*', Path("a"), Binary('+', Path("b"), Path("c"))) +struct Unparenthesize; + +impl MutVisitor for Unparenthesize { + fn visit_expr(&mut self, e: &mut P<Expr>) { + while let ExprKind::Paren(paren) = &mut e.kind { + **e = mem::replace(&mut *paren, Expr::dummy()); + } + mut_visit::walk_expr(self, e); + } +} + +// Erase Span information that could distinguish between identical expressions +// parsed from different source strings. +struct Normalize; + +impl MutVisitor for Normalize { + const VISIT_TOKENS: bool = true; + + fn visit_id(&mut self, id: &mut NodeId) { + *id = DUMMY_NODE_ID; + } + + fn visit_span(&mut self, span: &mut Span) { + *span = DUMMY_SP; + } +} + +fn parse_expr(psess: &ParseSess, source_code: &str) -> Option<P<Expr>> { + let parser = rustc_parse::unwrap_or_emit_fatal(rustc_parse::new_parser_from_source_str( + psess, + FileName::anon_source_code(source_code), + source_code.to_owned(), + )); + + let mut expr = parser.recovery(Recovery::Forbidden).parse_expr().map_err(Diag::cancel).ok()?; + Normalize.visit_expr(&mut expr); + Some(expr) +} + +fn main() -> ExitCode { + let mut status = ExitCode::SUCCESS; + let mut fail = |description: &str, before: &str, after: &str| { + status = ExitCode::FAILURE; + eprint!( + "{description}\n BEFORE: {before}\n AFTER: {after}\n\n", + before = before.replace('\n', "\n "), + after = after.replace('\n', "\n "), + ); + }; + + rustc_span::create_default_session_globals_then(|| { + let psess = &ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]); + + for &source_code in EXPRS { + let expr = parse_expr(psess, source_code).unwrap(); + + // Check for FALSE POSITIVE: pretty-printer inserting parentheses where not needed. + // Pseudocode: + // assert(expr == parse(print(expr))) + let printed = &pprust::expr_to_string(&expr); + let Some(expr2) = parse_expr(psess, printed) else { + fail("Pretty-printer produced invalid syntax", source_code, printed); + continue; + }; + if format!("{expr:#?}") != format!("{expr2:#?}") { + fail("Pretty-printer inserted unnecessary parenthesis", source_code, printed); + continue; + } + + // Check for FALSE NEGATIVE: pretty-printer failing to place necessary parentheses. + // Pseudocode: + // assert(unparenthesize(expr) == unparenthesize(parse(print(unparenthesize(expr))))) + let mut expr = expr; + Unparenthesize.visit_expr(&mut expr); + let printed = &pprust::expr_to_string(&expr); + let Some(mut expr2) = parse_expr(psess, printed) else { + fail("Pretty-printer with no parens produced invalid syntax", source_code, printed); + continue; + }; + Unparenthesize.visit_expr(&mut expr2); + if format!("{expr:#?}") != format!("{expr2:#?}") { + fail("Pretty-printer lost necessary parentheses", source_code, printed); + continue; + } + } + }); + + status +} diff --git a/tests/ui/README.md b/tests/ui/README.md index c14d0ee78c8..aa36481ae06 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -6,9 +6,9 @@ This folder contains `rustc`'s ## Test Directives (Headers) Typically, a UI test will have some test directives / headers which are -special comments that tell compiletest how to build and intepret a test. +special comments that tell compiletest how to build and interpret a test. -As part of an on-going effort to rewrite compiletest +As part of an ongoing effort to rewrite compiletest (see <https://github.com/rust-lang/compiler-team/issues/536>), a major change proposal to change legacy compiletest-style headers `// <directive>` to [`ui_test`](https://github.com/oli-obk/ui_test)-style headers @@ -30,6 +30,6 @@ but in `ui_test` style, the header would be written as compiletest is changed to accept only `//@` directives for UI tests (currently), and will reject and report an error if it encounters any -comments `// <content>` that may be parsed as an legacy compiletest-style +comments `// <content>` that may be parsed as a legacy compiletest-style test header. To fix this, you should migrate to the `ui_test`-style header `//@ <content>`. diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs index b5798adc71c..e6c80a7e54e 100644 --- a/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs +++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs @@ -18,17 +18,17 @@ impl Foo for Def { pub fn test<A: Foo, B: Foo>(arg: EFoo) { match arg { A::X => println!("A::X"), - //~^ error: constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters B::X => println!("B::X"), - //~^ error: constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters _ => (), } } pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) { - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters let A::X = arg; - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters } fn main() { diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr index adc8f399207..a8256f775a6 100644 --- a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr +++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr @@ -1,26 +1,57 @@ -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/associated-const-type-parameter-pattern.rs:20:9 | +LL | pub trait Foo { + | ------------- +LL | const X: EFoo; + | ------------- constant defined here +... +LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) { + | - constant depends on this generic parameter +LL | match arg { LL | A::X => println!("A::X"), - | ^^^^ + | ^^^^ `const` depends on a generic parameter -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/associated-const-type-parameter-pattern.rs:22:9 | +LL | pub trait Foo { + | ------------- +LL | const X: EFoo; + | ------------- constant defined here +... +LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) { + | - constant depends on this generic parameter +... LL | B::X => println!("B::X"), - | ^^^^ + | ^^^^ `const` depends on a generic parameter -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/associated-const-type-parameter-pattern.rs:30:9 | +LL | pub trait Foo { + | ------------- +LL | const X: EFoo; + | ------------- constant defined here +... +LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) { + | - constant depends on this generic parameter +LL | LL | let A::X = arg; - | ^^^^ + | ^^^^ `const` depends on a generic parameter -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/associated-const-type-parameter-pattern.rs:28:48 | +LL | pub trait Foo { + | ------------- +LL | const X: EFoo; + | ------------- constant defined here +... LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) { - | ^^^^ + | - ^^^^ `const` depends on a generic parameter + | | + | constant depends on this generic parameter error: aborting due to 4 previous errors diff --git a/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs b/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs index 5ed65425f34..8309cfbd58f 100644 --- a/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs +++ b/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs @@ -10,7 +10,7 @@ fn main() { block_on::block_on(async { let x = async || {}; - async fn needs_async_fn_mut(mut x: impl async FnMut()) { + async fn needs_async_fn_mut(mut x: impl AsyncFnMut()) { x().await; } needs_async_fn_mut(x).await; diff --git a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs index be436465315..e7644e3dfe0 100644 --- a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs +++ b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs @@ -8,7 +8,7 @@ extern crate block_on; fn main() { block_on::block_on(async { - async fn needs_async_fn_once(x: impl async FnOnce()) { + async fn needs_async_fn_once(x: impl AsyncFnOnce()) { x().await; } diff --git a/tests/ui/async-await/async-closures/auxiliary/foreign.rs b/tests/ui/async-await/async-closures/auxiliary/foreign.rs index 2c935f5e1fa..33548a1b30d 100644 --- a/tests/ui/async-await/async-closures/auxiliary/foreign.rs +++ b/tests/ui/async-await/async-closures/auxiliary/foreign.rs @@ -2,6 +2,6 @@ #![feature(async_closure)] -pub fn closure() -> impl async Fn() { +pub fn closure() -> impl AsyncFn() { async || { /* Don't really need to do anything here. */ } } diff --git a/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs b/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs index 4382a689e75..a72ff8e5dce 100644 --- a/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs +++ b/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs @@ -11,7 +11,7 @@ extern crate block_on; async fn empty() {} -pub async fn call_once<F: async FnOnce()>(f: F) { +pub async fn call_once<F: AsyncFnOnce()>(f: F) { f().await; } diff --git a/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs b/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs index 8b2de578b24..5ec1c5ee50e 100644 --- a/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs +++ b/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs @@ -16,7 +16,7 @@ impl Trait for (i32,) { } } -async fn call_once(f: impl async FnOnce()) { +async fn call_once(f: impl AsyncFnOnce()) { f().await; } diff --git a/tests/ui/async-await/async-closures/brand.rs b/tests/ui/async-await/async-closures/brand.rs index 5168f3696d7..db1f5d271c6 100644 --- a/tests/ui/async-await/async-closures/brand.rs +++ b/tests/ui/async-await/async-closures/brand.rs @@ -13,7 +13,7 @@ struct S; struct B<'b>(PhantomData<&'b mut &'b mut ()>); impl S { - async fn q<F: async Fn(B<'_>)>(self, f: F) { + async fn q<F: AsyncFn(B<'_>)>(self, f: F) { f(B(PhantomData)).await; } } diff --git a/tests/ui/async-await/async-closures/captures.rs b/tests/ui/async-await/async-closures/captures.rs index 0a9d0529bf5..2bd4b685997 100644 --- a/tests/ui/async-await/async-closures/captures.rs +++ b/tests/ui/async-await/async-closures/captures.rs @@ -13,11 +13,11 @@ fn main() { block_on::block_on(async_main()); } -async fn call<T>(f: &impl async Fn() -> T) -> T { +async fn call<T>(f: &impl AsyncFn() -> T) -> T { f().await } -async fn call_once<T>(f: impl async FnOnce() -> T) -> T { +async fn call_once<T>(f: impl AsyncFnOnce() -> T) -> T { f().await } @@ -80,7 +80,7 @@ async fn async_main() { call_once(c).await; } - fn force_fnonce<T>(f: impl async FnOnce() -> T) -> impl async FnOnce() -> T { + fn force_fnonce<T>(f: impl AsyncFnOnce() -> T) -> impl AsyncFnOnce() -> T { f } diff --git a/tests/ui/async-await/async-closures/clone-closure.rs b/tests/ui/async-await/async-closures/clone-closure.rs index 807897e3e03..a9e1d6bccc7 100644 --- a/tests/ui/async-await/async-closures/clone-closure.rs +++ b/tests/ui/async-await/async-closures/clone-closure.rs @@ -7,7 +7,7 @@ extern crate block_on; -async fn for_each(f: impl async FnOnce(&str) + Clone) { +async fn for_each(f: impl AsyncFnOnce(&str) + Clone) { f.clone()("world").await; f.clone()("world2").await; } diff --git a/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs b/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs index 3b222d00bae..1acbf0311b3 100644 --- a/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs +++ b/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs @@ -6,7 +6,7 @@ #![feature(async_closure)] -fn constrain<T: async FnOnce()>(t: T) -> T { +fn constrain<T: AsyncFnOnce()>(t: T) -> T { t } @@ -14,7 +14,7 @@ fn call_once<T>(f: impl FnOnce() -> T) -> T { f() } -async fn async_call_once<T>(f: impl async FnOnce() -> T) -> T { +async fn async_call_once<T>(f: impl AsyncFnOnce() -> T) -> T { f().await } diff --git a/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs b/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs index 6f339f0c8ef..f71cc1ef537 100644 --- a/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs +++ b/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs @@ -7,7 +7,7 @@ extern crate block_on; -async fn call_once(f: impl async FnOnce()) { +async fn call_once(f: impl AsyncFnOnce()) { f().await; } diff --git a/tests/ui/async-await/async-closures/drop.rs b/tests/ui/async-await/async-closures/drop.rs index 2884a20f244..9c99550e3b7 100644 --- a/tests/ui/async-await/async-closures/drop.rs +++ b/tests/ui/async-await/async-closures/drop.rs @@ -16,7 +16,7 @@ impl Drop for DropMe { } } -async fn call_once(f: impl async FnOnce()) { +async fn call_once(f: impl AsyncFnOnce()) { println!("before call"); let fut = Box::pin(f()); println!("after call"); diff --git a/tests/ui/async-await/async-closures/fn-exception-target-features.rs b/tests/ui/async-await/async-closures/fn-exception-target-features.rs index de62fc8bf7e..eb554650b7c 100644 --- a/tests/ui/async-await/async-closures/fn-exception-target-features.rs +++ b/tests/ui/async-await/async-closures/fn-exception-target-features.rs @@ -10,7 +10,7 @@ use std::future::Future; #[target_feature(enable = "sse2")] fn target_feature() -> Pin<Box<dyn Future<Output = ()> + 'static>> { todo!() } -fn test(f: impl async Fn()) {} +fn test(f: impl AsyncFn()) {} fn main() { test(target_feature); //~ ERROR the trait bound diff --git a/tests/ui/async-await/async-closures/fn-exception-target-features.stderr b/tests/ui/async-await/async-closures/fn-exception-target-features.stderr index e965c40fb5b..db5895108bb 100644 --- a/tests/ui/async-await/async-closures/fn-exception-target-features.stderr +++ b/tests/ui/async-await/async-closures/fn-exception-target-features.stderr @@ -9,8 +9,8 @@ LL | test(target_feature); note: required by a bound in `test` --> $DIR/fn-exception-target-features.rs:13:17 | -LL | fn test(f: impl async Fn()) {} - | ^^^^^^^^^^ required by this bound in `test` +LL | fn test(f: impl AsyncFn()) {} + | ^^^^^^^^^ required by this bound in `test` error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-closures/fn-exception.rs b/tests/ui/async-await/async-closures/fn-exception.rs index 0e06ebf48a4..36cb955cd5c 100644 --- a/tests/ui/async-await/async-closures/fn-exception.rs +++ b/tests/ui/async-await/async-closures/fn-exception.rs @@ -13,7 +13,7 @@ unsafe extern "C" { pub safe fn abi() -> Pin<Box<dyn Future<Output = ()> + 'static>>; } -fn test(f: impl async Fn()) {} +fn test(f: impl AsyncFn()) {} fn main() { test(unsafety); //~ ERROR the trait bound diff --git a/tests/ui/async-await/async-closures/fn-exception.stderr b/tests/ui/async-await/async-closures/fn-exception.stderr index 20132e42833..b3118664c15 100644 --- a/tests/ui/async-await/async-closures/fn-exception.stderr +++ b/tests/ui/async-await/async-closures/fn-exception.stderr @@ -9,8 +9,8 @@ LL | test(unsafety); note: required by a bound in `test` --> $DIR/fn-exception.rs:16:17 | -LL | fn test(f: impl async Fn()) {} - | ^^^^^^^^^^ required by this bound in `test` +LL | fn test(f: impl AsyncFn()) {} + | ^^^^^^^^^ required by this bound in `test` error[E0277]: the trait bound `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}: AsyncFn()` is not satisfied --> $DIR/fn-exception.rs:20:10 @@ -23,8 +23,8 @@ LL | test(abi); note: required by a bound in `test` --> $DIR/fn-exception.rs:16:17 | -LL | fn test(f: impl async Fn()) {} - | ^^^^^^^^^^ required by this bound in `test` +LL | fn test(f: impl AsyncFn()) {} + | ^^^^^^^^^ required by this bound in `test` error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs b/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs index 7ce210a33c3..c20e3664d8b 100644 --- a/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs +++ b/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs @@ -6,7 +6,7 @@ extern crate block_on; -fn force_fnonce<T: async FnOnce()>(t: T) -> T { t } +fn force_fnonce<T: AsyncFnOnce()>(t: T) -> T { t } fn main() { block_on::block_on(async { diff --git a/tests/ui/async-await/async-closures/foreign.rs b/tests/ui/async-await/async-closures/foreign.rs index ab6fe06a3f4..a244eef4102 100644 --- a/tests/ui/async-await/async-closures/foreign.rs +++ b/tests/ui/async-await/async-closures/foreign.rs @@ -12,7 +12,7 @@ extern crate foreign; struct NoCopy; -async fn call_once(f: impl async FnOnce()) { +async fn call_once(f: impl AsyncFnOnce()) { f().await; } diff --git a/tests/ui/async-await/async-closures/implements-fnmut.rs b/tests/ui/async-await/async-closures/implements-fnmut.rs index 8e780ce9889..f49d1423c40 100644 --- a/tests/ui/async-await/async-closures/implements-fnmut.rs +++ b/tests/ui/async-await/async-closures/implements-fnmut.rs @@ -1,7 +1,7 @@ //@ build-pass //@ edition: 2021 -// Demonstrates that an async closure may implement `FnMut` (not just `async FnMut`!) +// Demonstrates that an async closure may implement `FnMut` (not just `AsyncFnMut`!) // if it has no self-borrows. In this case, `&Ty` is not borrowed from the closure env, // since it's fine to reborrow it with its original lifetime. See the doc comment on // `should_reborrow_from_env_of_parent_coroutine_closure` for more detail for when we diff --git a/tests/ui/async-await/async-closures/inline-body.rs b/tests/ui/async-await/async-closures/inline-body.rs index a842d98d1de..1bd2da6e899 100644 --- a/tests/ui/async-await/async-closures/inline-body.rs +++ b/tests/ui/async-await/async-closures/inline-body.rs @@ -24,7 +24,7 @@ pub fn block_on<T>(fut: impl Future<Output = T>) -> T { } } -async fn call_once<T>(f: impl async FnOnce() -> T) -> T { +async fn call_once<T>(f: impl AsyncFnOnce() -> T) -> T { f().await } diff --git a/tests/ui/async-await/async-closures/mangle.rs b/tests/ui/async-await/async-closures/mangle.rs index a428905e40b..3032ca3c02b 100644 --- a/tests/ui/async-await/async-closures/mangle.rs +++ b/tests/ui/async-await/async-closures/mangle.rs @@ -13,11 +13,11 @@ use std::future::Future; use std::pin::pin; use std::task::*; -async fn call_mut(f: &mut impl async FnMut()) { +async fn call_mut(f: &mut impl AsyncFnMut()) { f().await; } -async fn call_once(f: impl async FnOnce()) { +async fn call_once(f: impl AsyncFnOnce()) { f().await; } diff --git a/tests/ui/async-await/async-closures/moro-example.rs b/tests/ui/async-await/async-closures/moro-example.rs index 5a8f42c7ca5..c331b8e5b5e 100644 --- a/tests/ui/async-await/async-closures/moro-example.rs +++ b/tests/ui/async-await/async-closures/moro-example.rs @@ -22,7 +22,7 @@ impl<'scope, 'env: 'scope> Scope<'scope, 'env> { fn scope_with_closure<'env, B>(_body: B) -> BoxFuture<'env, ()> where - for<'scope> B: async FnOnce(&'scope Scope<'scope, 'env>), + for<'scope> B: AsyncFnOnce(&'scope Scope<'scope, 'env>), { todo!() } diff --git a/tests/ui/async-await/async-closures/move-is-async-fn.rs b/tests/ui/async-await/async-closures/move-is-async-fn.rs index 79e2298f609..d0e2bc24b52 100644 --- a/tests/ui/async-await/async-closures/move-is-async-fn.rs +++ b/tests/ui/async-await/async-closures/move-is-async-fn.rs @@ -19,7 +19,7 @@ fn main() { is_static(&c); // Check that `<{async fn} as AsyncFnOnce>::CallOnceFuture` owns its captures. - fn call_once<F: async FnOnce()>(f: F) -> F::CallOnceFuture { f() } + fn call_once<F: AsyncFnOnce()>(f: F) -> F::CallOnceFuture { f() } is_static(&call_once(c)); }); } diff --git a/tests/ui/async-await/async-closures/mut-ref-reborrow.rs b/tests/ui/async-await/async-closures/mut-ref-reborrow.rs index 9f2cbd7ce1c..c37048398e9 100644 --- a/tests/ui/async-await/async-closures/mut-ref-reborrow.rs +++ b/tests/ui/async-await/async-closures/mut-ref-reborrow.rs @@ -9,7 +9,7 @@ extern crate block_on; -async fn call_once(f: impl async FnOnce()) { f().await; } +async fn call_once(f: impl AsyncFnOnce()) { f().await; } pub async fn async_closure(x: &mut i32) { let c = async move || { diff --git a/tests/ui/async-await/async-closures/no-borrow-from-env.rs b/tests/ui/async-await/async-closures/no-borrow-from-env.rs index 3f9d26b9713..36b10c06dca 100644 --- a/tests/ui/async-await/async-closures/no-borrow-from-env.rs +++ b/tests/ui/async-await/async-closures/no-borrow-from-env.rs @@ -5,7 +5,7 @@ fn outlives<'a>(_: impl Sized + 'a) {} -async fn call_once(f: impl async FnOnce()) { +async fn call_once(f: impl AsyncFnOnce()) { f().await; } diff --git a/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs b/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs index cd9d98d0799..cfb50dd5574 100644 --- a/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs +++ b/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs @@ -6,7 +6,7 @@ extern crate block_on; -fn wrapper(f: impl Fn(String)) -> impl async Fn(String) { +fn wrapper(f: impl Fn(String)) -> impl AsyncFn(String) { async move |s| f(s) } diff --git a/tests/ui/async-await/async-closures/overlapping-projs.rs b/tests/ui/async-await/async-closures/overlapping-projs.rs index 6dd00b16103..f778534cfe2 100644 --- a/tests/ui/async-await/async-closures/overlapping-projs.rs +++ b/tests/ui/async-await/async-closures/overlapping-projs.rs @@ -7,7 +7,7 @@ extern crate block_on; -async fn call_once(f: impl async FnOnce()) { +async fn call_once(f: impl AsyncFnOnce()) { f().await; } diff --git a/tests/ui/async-await/async-closures/precise-captures.rs b/tests/ui/async-await/async-closures/precise-captures.rs index c4c67df544f..7dcbf2595f0 100644 --- a/tests/ui/async-await/async-closures/precise-captures.rs +++ b/tests/ui/async-await/async-closures/precise-captures.rs @@ -5,7 +5,7 @@ //@ revisions: call call_once force_once // call - Call the closure regularly. -// call_once - Call the closure w/ `async FnOnce`, so exercising the by_move shim. +// call_once - Call the closure w/ `AsyncFnOnce`, so exercising the by_move shim. // force_once - Force the closure mode to `FnOnce`, so exercising what was fixed // in <https://github.com/rust-lang/rust/pull/123350>. @@ -20,7 +20,7 @@ macro_rules! call { } #[cfg(call_once)] -async fn call_once(f: impl async FnOnce()) { +async fn call_once(f: impl AsyncFnOnce()) { f().await } @@ -35,7 +35,7 @@ macro_rules! guidance { } #[cfg(force_once)] -fn infer_fnonce(c: impl async FnOnce()) -> impl async FnOnce() { c } +fn infer_fnonce(c: impl AsyncFnOnce()) -> impl AsyncFnOnce() { c } #[cfg(force_once)] macro_rules! guidance { diff --git a/tests/ui/async-await/async-closures/refd.rs b/tests/ui/async-await/async-closures/refd.rs index 0b8d3d7aff5..8c16ecb1531 100644 --- a/tests/ui/async-await/async-closures/refd.rs +++ b/tests/ui/async-await/async-closures/refd.rs @@ -10,15 +10,15 @@ struct NoCopy; fn main() { block_on::block_on(async { - async fn call_once(x: impl async Fn()) { x().await } + async fn call_once(x: impl AsyncFn()) { x().await } - // check that `&{async-closure}` implements `async Fn`. + // check that `&{async-closure}` implements `AsyncFn`. call_once(&async || {}).await; - // check that `&{closure}` implements `async Fn`. + // check that `&{closure}` implements `AsyncFn`. call_once(&|| async {}).await; - // check that `&fndef` implements `async Fn`. + // check that `&fndef` implements `AsyncFn`. async fn foo() {} call_once(&foo).await; }); diff --git a/tests/ui/async-await/async-closures/signature-deduction.rs b/tests/ui/async-await/async-closures/signature-deduction.rs index 856f3963ee6..4e9a6747f1f 100644 --- a/tests/ui/async-await/async-closures/signature-deduction.rs +++ b/tests/ui/async-await/async-closures/signature-deduction.rs @@ -3,7 +3,7 @@ #![feature(async_closure)] -async fn foo(x: impl async Fn(&str) -> &str) {} +async fn foo(x: impl AsyncFn(&str) -> &str) {} fn main() { foo(async |x| x); diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs index be3f032b8ff..19f366cc903 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs @@ -8,7 +8,7 @@ fn outlives<'a>(_: impl Sized + 'a) {} -async fn call_once(f: impl async FnOnce()) { +async fn call_once(f: impl AsyncFnOnce()) { f().await; } diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.rs b/tests/ui/async-await/async-closures/wrong-fn-kind.rs index 3d6f856874f..a566b8aa663 100644 --- a/tests/ui/async-await/async-closures/wrong-fn-kind.rs +++ b/tests/ui/async-await/async-closures/wrong-fn-kind.rs @@ -2,7 +2,7 @@ #![feature(async_closure)] -fn needs_async_fn(_: impl async Fn()) {} +fn needs_async_fn(_: impl AsyncFn()) {} fn a() { let mut x = 1; @@ -15,7 +15,7 @@ fn a() { fn b() { let x = String::new(); needs_async_fn(move || async move { - //~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce` + //~^ ERROR expected a closure that implements the `AsyncFn` trait, but this closure only implements `AsyncFnOnce` println!("{x}"); }); } diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr index 4b626c1bed6..d03b10ca2cc 100644 --- a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr +++ b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr @@ -1,29 +1,29 @@ -error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce` +error[E0525]: expected a closure that implements the `AsyncFn` trait, but this closure only implements `AsyncFnOnce` --> $DIR/wrong-fn-kind.rs:17:20 | LL | needs_async_fn(move || async move { | -------------- -^^^^^^ | | | - | _____|______________this closure implements `async FnOnce`, not `async Fn` + | _____|______________this closure implements `AsyncFnOnce`, not `AsyncFn` | | | | | required by a bound introduced by this call LL | | LL | | println!("{x}"); - | | - closure is `async FnOnce` because it moves the variable `x` out of its environment + | | - closure is `AsyncFnOnce` because it moves the variable `x` out of its environment LL | | }); - | |_____- the requirement to implement `async Fn` derives from here + | |_____- the requirement to implement `AsyncFn` derives from here | note: required by a bound in `needs_async_fn` --> $DIR/wrong-fn-kind.rs:5:27 | -LL | fn needs_async_fn(_: impl async Fn()) {} - | ^^^^^^^^^^ required by this bound in `needs_async_fn` +LL | fn needs_async_fn(_: impl AsyncFn()) {} + | ^^^^^^^^^ required by this bound in `needs_async_fn` error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/wrong-fn-kind.rs:9:20 | -LL | fn needs_async_fn(_: impl async Fn()) {} - | --------------- change this to accept `FnMut` instead of `Fn` +LL | fn needs_async_fn(_: impl AsyncFn()) {} + | -------------- change this to accept `FnMut` instead of `Fn` ... LL | needs_async_fn(async || { | -------------- ^^^^^^^^ diff --git a/tests/ui/async-await/async-fn/dyn-pos.rs b/tests/ui/async-await/async-fn/dyn-pos.rs index a16b7c26f0d..129ea282936 100644 --- a/tests/ui/async-await/async-fn/dyn-pos.rs +++ b/tests/ui/async-await/async-fn/dyn-pos.rs @@ -2,7 +2,7 @@ #![feature(async_closure)] -fn foo(x: &dyn async Fn()) {} +fn foo(x: &dyn AsyncFn()) {} //~^ ERROR the trait `AsyncFnMut` cannot be made into an object fn main() {} diff --git a/tests/ui/async-await/async-fn/dyn-pos.stderr b/tests/ui/async-await/async-fn/dyn-pos.stderr index a9abfc5e5c4..aaa8eb2634d 100644 --- a/tests/ui/async-await/async-fn/dyn-pos.stderr +++ b/tests/ui/async-await/async-fn/dyn-pos.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `AsyncFnMut` cannot be made into an object --> $DIR/dyn-pos.rs:5:16 | -LL | fn foo(x: &dyn async Fn()) {} - | ^^^^^^^^^^ `AsyncFnMut` cannot be made into an object +LL | fn foo(x: &dyn AsyncFn()) {} + | ^^^^^^^^^ `AsyncFnMut` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL diff --git a/tests/ui/async-await/async-fn/edition-2015.rs b/tests/ui/async-await/async-fn/edition-2015.rs index e38179758f6..7fc62a8dd93 100644 --- a/tests/ui/async-await/async-fn/edition-2015.rs +++ b/tests/ui/async-await/async-fn/edition-2015.rs @@ -1,8 +1,8 @@ fn foo(x: impl async Fn()) -> impl async Fn() { x } //~^ ERROR `async` trait bounds are only allowed in Rust 2018 or later //~| ERROR `async` trait bounds are only allowed in Rust 2018 or later -//~| ERROR async closures are unstable -//~| ERROR async closures are unstable +//~| ERROR `async` trait bounds are unstable +//~| ERROR `async` trait bounds are unstable //~| ERROR use of unstable library feature `async_closure` //~| ERROR use of unstable library feature `async_closure` diff --git a/tests/ui/async-await/async-fn/edition-2015.stderr b/tests/ui/async-await/async-fn/edition-2015.stderr index 9fbceafd75d..96fb4c9e979 100644 --- a/tests/ui/async-await/async-fn/edition-2015.stderr +++ b/tests/ui/async-await/async-fn/edition-2015.stderr @@ -16,27 +16,27 @@ LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/edition-2015.rs:1:16 | LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } | ^^^^^ | = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: to use an async block, remove the `||`: `async {` + = help: use the desugared name of the async trait, such as `AsyncFn` -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/edition-2015.rs:1:36 | LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } | ^^^^^ | = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: to use an async block, remove the `||`: `async {` + = help: use the desugared name of the async trait, such as `AsyncFn` error[E0658]: use of unstable library feature `async_closure` --> $DIR/edition-2015.rs:1:42 diff --git a/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs b/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs index f8da517213a..5d675921028 100644 --- a/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs +++ b/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs @@ -15,7 +15,7 @@ async fn f(arg: &i32) {} async fn func<F>(f: F) where - F: for<'a> async Fn(&'a i32), + F: for<'a> AsyncFn(&'a i32), { let x: i32 = 0; f(&x).await; diff --git a/tests/ui/async-await/async-fn/impl-trait.rs b/tests/ui/async-await/async-fn/impl-trait.rs index 686addcb1a9..11faf9ac983 100644 --- a/tests/ui/async-await/async-fn/impl-trait.rs +++ b/tests/ui/async-await/async-fn/impl-trait.rs @@ -3,13 +3,13 @@ #![feature(async_closure, type_alias_impl_trait)] -type Tait = impl async Fn(); +type Tait = impl AsyncFn(); fn tait() -> Tait { || async {} } -fn foo(x: impl async Fn()) -> impl async Fn() { x } +fn foo(x: impl AsyncFn()) -> impl AsyncFn() { x } -fn param<T: async Fn()>() {} +fn param<T: AsyncFn()>() {} fn main() {} diff --git a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs index abc429772fd..ea67831b68e 100644 --- a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs +++ b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs @@ -13,9 +13,9 @@ macro_rules! demo { } demo! { impl async Trait } -//~^ ERROR async closures are unstable +//~^ ERROR `async` trait bounds are unstable demo! { dyn async Trait } -//~^ ERROR async closures are unstable +//~^ ERROR `async` trait bounds are unstable fn main() {} diff --git a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr index 13b8e72b49d..a463944d113 100644 --- a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr +++ b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr @@ -20,27 +20,27 @@ LL | demo! { dyn async Trait } | = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:15:14 | LL | demo! { impl async Trait } | ^^^^^ | = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: to use an async block, remove the `||`: `async {` + = help: use the desugared name of the async trait, such as `AsyncFn` -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:18:13 | LL | demo! { dyn async Trait } | ^^^^^ | = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: to use an async block, remove the `||`: `async {` + = help: use the desugared name of the async trait, such as `AsyncFn` error: aborting due to 4 previous errors diff --git a/tests/ui/async-await/async-fn/not-a-trait.rs b/tests/ui/async-await/async-fn/not-a-trait.rs index 0d22cbd2c07..5cf23f2456a 100644 --- a/tests/ui/async-await/async-fn/not-a-trait.rs +++ b/tests/ui/async-await/async-fn/not-a-trait.rs @@ -1,6 +1,6 @@ //@ edition:2018 -#![feature(async_closure)] +#![feature(async_trait_bounds)] struct S; diff --git a/tests/ui/async-await/async-fn/project.rs b/tests/ui/async-await/async-fn/project.rs index 5cbdc378dda..b6068a916ae 100644 --- a/tests/ui/async-await/async-fn/project.rs +++ b/tests/ui/async-await/async-fn/project.rs @@ -6,7 +6,9 @@ #![feature(async_closure, unboxed_closures, async_fn_traits)] -fn project<F: async Fn<()>>(_: F) -> Option<F::Output> { None } +use std::ops::AsyncFn; + +fn project<F: AsyncFn<()>>(_: F) -> Option<F::Output> { None } fn main() { let x: Option<i32> = project(|| async { 1i32 }); diff --git a/tests/ui/async-await/async-fn/sugar.rs b/tests/ui/async-await/async-fn/sugar.rs index 29b6abc814a..0225b666ac5 100644 --- a/tests/ui/async-await/async-fn/sugar.rs +++ b/tests/ui/async-await/async-fn/sugar.rs @@ -1,7 +1,7 @@ //@ edition: 2021 //@ check-pass -#![feature(async_closure)] +#![feature(async_closure, async_trait_bounds)] async fn foo() {} diff --git a/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs b/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs index 329a1528e8b..654883966f4 100644 --- a/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs +++ b/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs @@ -6,7 +6,7 @@ macro_rules! x { x! { async fn foo() -> impl async Fn() { } - //~^ ERROR async closures are unstable + //~^ ERROR `async` trait bounds are unstable } fn main() {} diff --git a/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr b/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr index f68c09737db..259e13cd1fe 100644 --- a/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr +++ b/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr @@ -1,13 +1,13 @@ -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/trait-bounds-in-macro.rs:8:28 | LL | async fn foo() -> impl async Fn() { } | ^^^^^ | = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: to use an async block, remove the `||`: `async {` + = help: use the desugared name of the async trait, such as `AsyncFn` error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-fn/wrong-trait.rs b/tests/ui/async-await/async-fn/wrong-trait.rs index e6fb0b46712..38d6bb1d01a 100644 --- a/tests/ui/async-await/async-fn/wrong-trait.rs +++ b/tests/ui/async-await/async-fn/wrong-trait.rs @@ -1,6 +1,6 @@ //@ edition:2018 -#![feature(async_closure)] +#![feature(async_trait_bounds)] trait Foo {} diff --git a/tests/ui/attributes/dump_def_parents.rs b/tests/ui/attributes/dump_def_parents.rs index de0c88bb6c3..04a725f6c14 100644 --- a/tests/ui/attributes/dump_def_parents.rs +++ b/tests/ui/attributes/dump_def_parents.rs @@ -3,16 +3,17 @@ fn bar() { fn foo() { + #[rustc_dump_def_parents] fn baz() { - #[rustc_dump_def_parents] + //~^ ERROR: rustc_dump_def_parents: DefId || { - //~^ ERROR: rustc_dump_def_parents: DefId qux::< { //~^ ERROR: rustc_dump_def_parents: DefId fn inhibits_dump() { qux::< { + //~^ ERROR: rustc_dump_def_parents: DefId "hi"; 1 }, diff --git a/tests/ui/attributes/dump_def_parents.stderr b/tests/ui/attributes/dump_def_parents.stderr index b2cc32d09b0..a928e8e33a4 100644 --- a/tests/ui/attributes/dump_def_parents.stderr +++ b/tests/ui/attributes/dump_def_parents.stderr @@ -1,11 +1,50 @@ error: rustc_dump_def_parents: DefId(..) - --> $DIR/dump_def_parents.rs:8:13 + --> $DIR/dump_def_parents.rs:7:9 + | +LL | fn baz() { + | ^^^^^^^^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:5:5 + | +LL | fn foo() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:4:1 + | +LL | fn bar() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:2:1 + | +LL | / #![feature(rustc_attrs)] +LL | | +LL | | fn bar() { +LL | | fn foo() { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:11:21 + | +LL | / { +LL | | +LL | | fn inhibits_dump() { +LL | | qux::< +... | +LL | | 1 +LL | | }, + | |_____________________^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:9:13 | LL | || { | ^^ - | note: DefId(..) - --> $DIR/dump_def_parents.rs:6:9 + --> $DIR/dump_def_parents.rs:7:9 | LL | fn baz() { | ^^^^^^^^ @@ -32,6 +71,21 @@ LL | | fn main() {} | |____________^ error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:15:33 + | +LL | / ... { +LL | | ... +LL | | ... "hi"; +LL | | ... 1 +LL | | ... }, + | |_______________________^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:13:25 + | +LL | fn inhibits_dump() { + | ^^^^^^^^^^^^^^^^^^ +note: DefId(..) --> $DIR/dump_def_parents.rs:11:21 | LL | / { @@ -42,14 +96,13 @@ LL | | qux::< LL | | 1 LL | | }, | |_____________________^ - | note: DefId(..) - --> $DIR/dump_def_parents.rs:8:13 + --> $DIR/dump_def_parents.rs:9:13 | LL | || { | ^^ note: DefId(..) - --> $DIR/dump_def_parents.rs:6:9 + --> $DIR/dump_def_parents.rs:7:9 | LL | fn baz() { | ^^^^^^^^ @@ -76,7 +129,7 @@ LL | | fn main() {} | |____________^ error: rustc_dump_def_parents: DefId(..) - --> $DIR/dump_def_parents.rs:22:31 + --> $DIR/dump_def_parents.rs:23:31 | LL | qux::<{ 1 + 1 }>(); | ^^^^^^^^^ @@ -93,12 +146,12 @@ LL | | 1 LL | | }, | |_____________________^ note: DefId(..) - --> $DIR/dump_def_parents.rs:8:13 + --> $DIR/dump_def_parents.rs:9:13 | LL | || { | ^^ note: DefId(..) - --> $DIR/dump_def_parents.rs:6:9 + --> $DIR/dump_def_parents.rs:7:9 | LL | fn baz() { | ^^^^^^^^ @@ -124,5 +177,5 @@ LL | | LL | | fn main() {} | |____________^ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/binding/const-param.rs b/tests/ui/binding/const-param.rs index 2d051808fe0..98bc90f508a 100644 --- a/tests/ui/binding/const-param.rs +++ b/tests/ui/binding/const-param.rs @@ -2,7 +2,7 @@ fn check<const N: usize>() { match 1 { - N => {} //~ ERROR const parameters cannot be referenced in patterns + N => {} //~ ERROR constant parameters cannot be referenced in patterns _ => {} } } diff --git a/tests/ui/binding/const-param.stderr b/tests/ui/binding/const-param.stderr index e68893a59e4..b0b8108945c 100644 --- a/tests/ui/binding/const-param.stderr +++ b/tests/ui/binding/const-param.stderr @@ -1,8 +1,11 @@ -error[E0158]: const parameters cannot be referenced in patterns +error[E0158]: constant parameters cannot be referenced in patterns --> $DIR/const-param.rs:5:9 | +LL | fn check<const N: usize>() { + | -------------- constant defined here +LL | match 1 { LL | N => {} - | ^ + | ^ can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/binop/binary-op-on-fn-ptr-eq.rs b/tests/ui/binop/binary-op-on-fn-ptr-eq.rs index a5ec63587f9..47b79f3855f 100644 --- a/tests/ui/binop/binary-op-on-fn-ptr-eq.rs +++ b/tests/ui/binop/binary-op-on-fn-ptr-eq.rs @@ -1,6 +1,9 @@ //@ run-pass // Tests equality between supertype and subtype of a function // See the issue #91636 + +#![allow(unpredictable_function_pointer_comparisons)] + fn foo(_a: &str) {} fn main() { diff --git a/tests/ui/box/unit/unique-ffi-symbols.rs b/tests/ui/box/unit/unique-ffi-symbols.rs index 65a9a32b2bb..75877f8397e 100644 --- a/tests/ui/box/unit/unique-ffi-symbols.rs +++ b/tests/ui/box/unit/unique-ffi-symbols.rs @@ -1,6 +1,9 @@ //@ run-pass // We used to have a __rust_abi shim that resulted in duplicated symbols // whenever the item path wasn't enough to disambiguate between them. + +#![allow(unpredictable_function_pointer_comparisons)] + fn main() { let a = { extern "C" fn good() -> i32 { return 0; } diff --git a/tests/ui/check-cfg/and-more-diagnostic.rs b/tests/ui/check-cfg/and-more-diagnostic.rs new file mode 100644 index 00000000000..82867f3b435 --- /dev/null +++ b/tests/ui/check-cfg/and-more-diagnostic.rs @@ -0,0 +1,13 @@ +// This test makes sure that we don't emit a long list of possible values +// but that we stop at a fix point and say "and X more". +// +//@ check-pass +//@ no-auto-check-cfg +//@ compile-flags: --check-cfg=cfg() +//@ normalize-stderr-test: "and \d+ more" -> "and X more" +//@ normalize-stderr-test: "`[a-zA-Z0-9_-]+`" -> "`xxx`" + +fn main() { + cfg!(target_feature = "zebra"); + //~^ WARNING unexpected `cfg` condition value +} diff --git a/tests/ui/check-cfg/and-more-diagnostic.stderr b/tests/ui/check-cfg/and-more-diagnostic.stderr new file mode 100644 index 00000000000..2ac80c84c37 --- /dev/null +++ b/tests/ui/check-cfg/and-more-diagnostic.stderr @@ -0,0 +1,12 @@ +warning: unexpected `xxx` condition value: `xxx` + --> $DIR/and-more-diagnostic.rs:11:10 + | +LL | cfg!(target_feature = "zebra"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected values for `xxx` are: `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, `xxx`, and `xxx` and X more + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/check-cfg/mix.rs b/tests/ui/check-cfg/mix.rs index ac244f4fc09..e9a2de2f672 100644 --- a/tests/ui/check-cfg/mix.rs +++ b/tests/ui/check-cfg/mix.rs @@ -75,8 +75,6 @@ fn test_cfg_macro() { //~^ WARNING unexpected `cfg` condition value //~| WARNING unexpected `cfg` condition value //~| WARNING unexpected `cfg` condition value - cfg!(target_feature = "zebra"); - //~^ WARNING unexpected `cfg` condition value } fn main() {} diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 32eb01c7018..231236799c6 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -245,14 +245,5 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration -warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:78:10 - | -LL | cfg!(target_feature = "zebra"); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 252 more - = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration - -warning: 27 warnings emitted +warning: 26 warnings emitted diff --git a/tests/ui/check-cfg/target_feature.rs b/tests/ui/check-cfg/target_feature.rs new file mode 100644 index 00000000000..6028dae66c4 --- /dev/null +++ b/tests/ui/check-cfg/target_feature.rs @@ -0,0 +1,18 @@ +// This test prints all the possible values for the `target_feature` cfg +// as a way to assert the expected values and reflect on any changes made +// to the `target_feature` cfg in the compiler. +// +// The output of this test does not reflect the actual output seen by +// users which will see a truncated list of possible values (at worst). +// +// In case of test output differences, just `--bless` the test. +// +//@ check-pass +//@ no-auto-check-cfg +//@ compile-flags: --check-cfg=cfg() -Zcheck-cfg-all-expected +//@ normalize-stderr-test: "`, `" -> "`\n`" + +fn main() { + cfg!(target_feature = "_UNEXPECTED_VALUE"); + //~^ WARNING unexpected `cfg` condition value +} diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr new file mode 100644 index 00000000000..2674a97a551 --- /dev/null +++ b/tests/ui/check-cfg/target_feature.stderr @@ -0,0 +1,297 @@ +warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` + --> $DIR/target_feature.rs:16:10 + | +LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected values for `target_feature` are: `10e60` +`2e3` +`3e3r1` +`3e3r2` +`3e3r3` +`3e7` +`7e10` +`a` +`aclass` +`adx` +`aes` +`altivec` +`alu32` +`amx-bf16` +`amx-complex` +`amx-fp16` +`amx-int8` +`amx-tile` +`atomics` +`avx` +`avx2` +`avx512bf16` +`avx512bitalg` +`avx512bw` +`avx512cd` +`avx512dq` +`avx512f` +`avx512fp16` +`avx512ifma` +`avx512vbmi` +`avx512vbmi2` +`avx512vl` +`avx512vnni` +`avx512vp2intersect` +`avx512vpopcntdq` +`avxifma` +`avxneconvert` +`avxvnni` +`avxvnniint16` +`avxvnniint8` +`backchain` +`bf16` +`bmi1` +`bmi2` +`bti` +`bulk-memory` +`c` +`cache` +`cmpxchg16b` +`crc` +`crt-static` +`cssc` +`d` +`d32` +`dit` +`doloop` +`dotprod` +`dpb` +`dpb2` +`dsp` +`dsp1e2` +`dspe60` +`e` +`e1` +`e2` +`ecv` +`edsp` +`elrw` +`ermsb` +`exception-handling` +`extended-const` +`f` +`f16c` +`f32mm` +`f64mm` +`faminmax` +`fcma` +`fdivdu` +`fhm` +`flagm` +`flagm2` +`float1e2` +`float1e3` +`float3e4` +`float7e60` +`floate1` +`fma` +`fp-armv8` +`fp16` +`fp64` +`fp8` +`fp8dot2` +`fp8dot4` +`fp8fma` +`fpuv2_df` +`fpuv2_sf` +`fpuv3_df` +`fpuv3_hf` +`fpuv3_hi` +`fpuv3_sf` +`frecipe` +`frintts` +`fxsr` +`gfni` +`hard-float` +`hard-float-abi` +`hard-tp` +`hbc` +`high-registers` +`hvx` +`hvx-length128b` +`hwdiv` +`i8mm` +`jsconv` +`lahfsahf` +`lasx` +`lbt` +`leoncasa` +`lor` +`lse` +`lse128` +`lse2` +`lsx` +`lut` +`lvz` +`lzcnt` +`m` +`mclass` +`mops` +`movbe` +`mp` +`mp1e2` +`msa` +`mte` +`multivalue` +`mutable-globals` +`neon` +`nontrapping-fptoint` +`nvic` +`paca` +`pacg` +`pan` +`partword-atomics` +`pauth-lr` +`pclmulqdq` +`pmuv3` +`popcnt` +`power10-vector` +`power8-altivec` +`power8-vector` +`power9-altivec` +`power9-vector` +`prfchw` +`quadword-atomics` +`rand` +`ras` +`rclass` +`rcpc` +`rcpc2` +`rcpc3` +`rdm` +`rdrand` +`rdseed` +`reference-types` +`relax` +`relaxed-simd` +`reserve-x18` +`rtm` +`sb` +`sha` +`sha2` +`sha3` +`sha512` +`sign-ext` +`simd128` +`sm3` +`sm4` +`sme` +`sme-b16b16` +`sme-f16f16` +`sme-f64f64` +`sme-f8f16` +`sme-f8f32` +`sme-fa64` +`sme-i16i64` +`sme-lutv2` +`sme2` +`sme2p1` +`spe` +`ssbs` +`sse` +`sse2` +`sse3` +`sse4.1` +`sse4.2` +`sse4a` +`ssse3` +`ssve-fp8dot2` +`ssve-fp8dot4` +`ssve-fp8fma` +`sve` +`sve-b16b16` +`sve2` +`sve2-aes` +`sve2-bitperm` +`sve2-sha3` +`sve2-sm4` +`sve2p1` +`tail-call` +`tbm` +`thumb-mode` +`thumb2` +`tme` +`trust` +`trustzone` +`ual` +`unaligned-scalar-mem` +`v` +`v5te` +`v6` +`v6k` +`v6t2` +`v7` +`v8` +`v8.1a` +`v8.2a` +`v8.3a` +`v8.4a` +`v8.5a` +`v8.6a` +`v8.7a` +`v8.8a` +`v8.9a` +`v8plus` +`v9` +`v9.1a` +`v9.2a` +`v9.3a` +`v9.4a` +`v9.5a` +`v9a` +`vaes` +`vdsp2e60f` +`vdspv1` +`vdspv2` +`vector` +`vfp2` +`vfp3` +`vfp4` +`vh` +`virt` +`virtualization` +`vpclmulqdq` +`vsx` +`wfxt` +`wide-arithmetic` +`xop` +`xsave` +`xsavec` +`xsaveopt` +`xsaves` +`zaamo` +`zabha` +`zalrsc` +`zba` +`zbb` +`zbc` +`zbkb` +`zbkc` +`zbkx` +`zbs` +`zdinx` +`zfh` +`zfhmin` +`zfinx` +`zhinx` +`zhinxmin` +`zk` +`zkn` +`zknd` +`zkne` +`zknh` +`zkr` +`zks` +`zksed` +`zksh`, and `zkt` + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/check-cfg/well-known-values.rs b/tests/ui/check-cfg/well-known-values.rs index 1fda4b2089e..40b7b2db836 100644 --- a/tests/ui/check-cfg/well-known-values.rs +++ b/tests/ui/check-cfg/well-known-values.rs @@ -60,8 +60,8 @@ //~^ WARN unexpected `cfg` condition value target_family = "_UNEXPECTED_VALUE", //~^ WARN unexpected `cfg` condition value - target_feature = "_UNEXPECTED_VALUE", - //~^ WARN unexpected `cfg` condition value + // target_feature = "_UNEXPECTED_VALUE", + // ^ tested in target_feature.rs target_has_atomic = "_UNEXPECTED_VALUE", //~^ WARN unexpected `cfg` condition value target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE", diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 4d375d80e77..7c03d0570db 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -169,15 +169,6 @@ LL | target_family = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:63:5 - | -LL | target_feature = "_UNEXPECTED_VALUE", - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `cssc`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `ecv`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `faminmax`, `fcma`, `fdivdu`, `fhm`, `flagm`, `flagm2`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fp8`, `fp8dot2`, `fp8dot4`, `fp8fma`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `hbc`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `leoncasa`, `lor`, `lse`, `lse128`, `lse2`, `lsx`, `lut`, `lvz`, `lzcnt`, `m`, `mclass`, `mops`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `partword-atomics`, `pauth-lr`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `quadword-atomics`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rcpc3`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `reserve-x18`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `sme`, `sme-b16b16`, `sme-f16f16`, `sme-f64f64`, `sme-f8f16`, `sme-f8f32`, `sme-fa64`, `sme-i16i64`, `sme-lutv2`, `sme2`, `sme2p1`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `ssve-fp8dot2`, `ssve-fp8dot4`, `ssve-fp8fma`, `sve`, `sve-b16b16`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `sve2p1`, `tail-call`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `v8.8a`, `v8.9a`, `v8plus`, `v9`, `v9.1a`, `v9.2a`, `v9.3a`, `v9.4a`, `v9.5a`, `v9a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `wfxt`, `wide-arithmetic`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zaamo`, `zabha`, `zalrsc`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` - = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration - -warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:65:5 | LL | target_has_atomic = "_UNEXPECTED_VALUE", @@ -297,5 +288,5 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration -warning: 30 warnings emitted +warning: 29 warnings emitted diff --git a/tests/ui/coercion/coerce-loop-issue-122561.rs b/tests/ui/coercion/coerce-loop-issue-122561.rs index e08884ad6a4..50a2aacc91a 100644 --- a/tests/ui/coercion/coerce-loop-issue-122561.rs +++ b/tests/ui/coercion/coerce-loop-issue-122561.rs @@ -39,8 +39,7 @@ fn for_single_line() -> bool { for i in 0.. { return false; } } // b. format the suggestion correctly so // that it's readable fn for_in_arg(a: &[(); for x in 0..2 {}]) -> bool { -//~^ ERROR `for` is not allowed in a `const` -//~| ERROR mismatched types + //~^ ERROR mismatched types true } @@ -84,16 +83,14 @@ fn loop_() -> bool { const C: i32 = { for i in 0.. { - //~^ ERROR `for` is not allowed in a `const` - //~| ERROR mismatched types + //~^ ERROR mismatched types } }; fn main() { let _ = [10; { for i in 0..5 { - //~^ ERROR `for` is not allowed in a `const` - //~| ERROR mismatched types + //~^ ERROR mismatched types } }]; @@ -105,6 +102,5 @@ fn main() { let _ = |a: &[(); for x in 0..2 {}]| {}; - //~^ ERROR `for` is not allowed in a `const` - //~| ERROR mismatched types + //~^ ERROR mismatched types } diff --git a/tests/ui/coercion/coerce-loop-issue-122561.stderr b/tests/ui/coercion/coerce-loop-issue-122561.stderr index 0f77fd1364d..90e9f41c291 100644 --- a/tests/ui/coercion/coerce-loop-issue-122561.stderr +++ b/tests/ui/coercion/coerce-loop-issue-122561.stderr @@ -1,5 +1,5 @@ warning: denote infinite loops with `loop { ... }` - --> $DIR/coerce-loop-issue-122561.rs:48:5 + --> $DIR/coerce-loop-issue-122561.rs:47:5 | LL | while true { | ^^^^^^^^^^ help: use `loop` @@ -7,57 +7,11 @@ LL | while true { = note: `#[warn(while_true)]` on by default warning: denote infinite loops with `loop { ... }` - --> $DIR/coerce-loop-issue-122561.rs:72:5 + --> $DIR/coerce-loop-issue-122561.rs:71:5 | LL | while true { | ^^^^^^^^^^ help: use `loop` -error[E0658]: `for` is not allowed in a `const` - --> $DIR/coerce-loop-issue-122561.rs:41:24 - | -LL | fn for_in_arg(a: &[(); for x in 0..2 {}]) -> bool { - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0658]: `for` is not allowed in a `const` - --> $DIR/coerce-loop-issue-122561.rs:86:5 - | -LL | / for i in 0.. { -LL | | -LL | | -LL | | } - | |_____^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0658]: `for` is not allowed in a `const` - --> $DIR/coerce-loop-issue-122561.rs:94:9 - | -LL | / for i in 0..5 { -LL | | -LL | | -LL | | } - | |_________^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0658]: `for` is not allowed in a `const` - --> $DIR/coerce-loop-issue-122561.rs:107:23 - | -LL | let _ = |a: &[(); for x in 0..2 {}]| {}; - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0308]: mismatched types --> $DIR/coerce-loop-issue-122561.rs:41:24 | @@ -71,11 +25,10 @@ LL | fn for_in_arg(a: &[(); for x in 0..2 {} /* `usize` value */]) -> bool { | +++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:86:5 + --> $DIR/coerce-loop-issue-122561.rs:85:5 | LL | / for i in 0.. { LL | | -LL | | LL | | } | |_____^ expected `i32`, found `()` | @@ -174,7 +127,7 @@ LL | fn for_single_line() -> bool { for i in 0.. { return false; } /* `bool` val | ++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:48:5 + --> $DIR/coerce-loop-issue-122561.rs:47:5 | LL | fn while_inifinite() -> bool { | ---- expected `bool` because of return type @@ -193,7 +146,7 @@ LL + /* `bool` value */ | error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:57:5 + --> $DIR/coerce-loop-issue-122561.rs:56:5 | LL | fn while_finite() -> bool { | ---- expected `bool` because of return type @@ -213,7 +166,7 @@ LL + /* `bool` value */ | error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:65:5 + --> $DIR/coerce-loop-issue-122561.rs:64:5 | LL | fn while_zero_times() -> bool { | ---- expected `bool` because of return type @@ -231,7 +184,7 @@ LL + /* `bool` value */ | error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:72:5 + --> $DIR/coerce-loop-issue-122561.rs:71:5 | LL | fn while_never_type() -> ! { | - expected `!` because of return type @@ -251,11 +204,10 @@ LL + /* `loop {}` or `panic!("...")` */ | error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:94:9 + --> $DIR/coerce-loop-issue-122561.rs:92:9 | LL | / for i in 0..5 { LL | | -LL | | LL | | } | |_________^ expected `usize`, found `()` | @@ -267,7 +219,7 @@ LL + /* `usize` value */ | error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:101:9 + --> $DIR/coerce-loop-issue-122561.rs:98:9 | LL | / while false { LL | | @@ -282,7 +234,7 @@ LL + /* `usize` value */ | error[E0308]: mismatched types - --> $DIR/coerce-loop-issue-122561.rs:107:23 + --> $DIR/coerce-loop-issue-122561.rs:104:23 | LL | let _ = |a: &[(); for x in 0..2 {}]| {}; | ^^^^^^^^^^^^^^^^ expected `usize`, found `()` @@ -293,7 +245,6 @@ help: consider returning a value here LL | let _ = |a: &[(); for x in 0..2 {} /* `usize` value */]| {}; | +++++++++++++++++++ -error: aborting due to 18 previous errors; 2 warnings emitted +error: aborting due to 14 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/generic_arg_infer/array-repeat-expr-lib.rs b/tests/ui/const-generics/generic_arg_infer/array-repeat-expr-lib.rs new file mode 100644 index 00000000000..c1f725db126 --- /dev/null +++ b/tests/ui/const-generics/generic_arg_infer/array-repeat-expr-lib.rs @@ -0,0 +1,12 @@ +//@ check-pass + +#![feature(generic_arg_infer)] +#![crate_type = "lib"] + +// Test that encoding the hallucinated `DefId` for the `_` const argument doesn't +// ICE (see #133468). This requires this to be a library crate. + +pub fn foo() { + let s: [u8; 10]; + s = [0; _]; +} diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index 30a45ce377e..4eb374b2020 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -72,6 +72,20 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more LL + #![feature(adt_const_params)] | +note: erroneous constant encountered + --> $DIR/unevaluated-const-ice-119731.rs:22:19 + | +LL | impl v17<512, v0> { + | ^^ + +note: erroneous constant encountered + --> $DIR/unevaluated-const-ice-119731.rs:22:19 + | +LL | impl v17<512, v0> { + | ^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0} --> $DIR/unevaluated-const-ice-119731.rs:28:37 | diff --git a/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs b/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs new file mode 100644 index 00000000000..5a67d34d6e5 --- /dev/null +++ b/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs @@ -0,0 +1,18 @@ +//@ check-pass + +// Regression test for #128176. Previously we would call `type_of` on the `1` anon const +// before the anon const had been lowered and had the `type_of` fed with a result. + +#![feature(generic_const_exprs)] +#![feature(dyn_compatible_for_dispatch)] +#![allow(incomplete_features)] + +trait X { + type Y<const N: i16>; +} + +const _: () = { + fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {} +}; + +fn main() {} diff --git a/tests/ui/const-generics/issues/issue-83765.stderr b/tests/ui/const-generics/issues/issue-83765.stderr index cce62749912..6b62012c14f 100644 --- a/tests/ui/const-generics/issues/issue-83765.stderr +++ b/tests/ui/const-generics/issues/issue-83765.stderr @@ -10,11 +10,11 @@ note: ...which requires computing candidate for `<LazyUpdim<'_, T, <T as TensorD LL | trait TensorDimension { | ^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`, completing the cycle -note: cycle used when computing candidate for `<LazyUpdim<'_, T, { T::DIM }, DIM> as TensorDimension>` - --> $DIR/issue-83765.rs:4:1 +note: cycle used when checking assoc item `<impl at $DIR/issue-83765.rs:50:1: 50:94>::size` is compatible with trait definition + --> $DIR/issue-83765.rs:51:5 | -LL | trait TensorDimension { - | ^^^^^^^^^^^^^^^^^^^^^ +LL | fn size(&self) -> [usize; DIM] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error[E0391]: cycle detected when resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM` diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs index 09f7e2ba5b1..270496d45a6 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs @@ -12,8 +12,7 @@ impl Opcode2 { pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) { move |i| match msg_type { - Opcode2::OP2 => unimplemented!(), - //~^ ERROR: could not evaluate constant pattern + Opcode2::OP2 => unimplemented!(), // ok, `const` already emitted an error } } diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr index 9442eac0cf5..d95a8861230 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr @@ -17,13 +17,7 @@ help: you might be missing a type parameter LL | pub struct Opcode2<S>(&'a S); | +++ -error: could not evaluate constant pattern - --> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9 - | -LL | Opcode2::OP2 => unimplemented!(), - | ^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0261, E0412. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/consts/const-eval-fail-too-big.rs b/tests/ui/consts/const-eval-fail-too-big.rs new file mode 100644 index 00000000000..4b5dbc1d7a4 --- /dev/null +++ b/tests/ui/consts/const-eval-fail-too-big.rs @@ -0,0 +1,12 @@ +//Error output test for #78834: Type is too big for the target architecture +struct B< + A: Sized = [(); { + let x = [0u8; !0usize]; + //~^ ERROR evaluation of constant value failed + 1 + }], +> { + a: A, +} + +fn main() {} diff --git a/tests/ui/consts/const-eval-fail-too-big.stderr b/tests/ui/consts/const-eval-fail-too-big.stderr new file mode 100644 index 00000000000..ae666483233 --- /dev/null +++ b/tests/ui/consts/const-eval-fail-too-big.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/const-eval-fail-too-big.rs:4:28 + | +LL | let x = [0u8; !0usize]; + | ^^^^^^^^^^^^^^ values of the type `[u8; usize::MAX]` are too big for the target architecture + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/const-eval-overflow-2.rs b/tests/ui/consts/const-eval/const-eval-overflow-2.rs index c19a0c443ec..bae8a7ce243 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-2.rs +++ b/tests/ui/consts/const-eval/const-eval-overflow-2.rs @@ -12,8 +12,7 @@ const NEG_NEG_128: i8 = -NEG_128; //~ ERROR constant fn main() { match -128i8 { - NEG_NEG_128 => println!("A"), - //~^ ERROR could not evaluate constant pattern + NEG_NEG_128 => println!("A"), // ok, `const` error already emitted _ => println!("B"), } } diff --git a/tests/ui/consts/const-eval/const-eval-overflow-2.stderr b/tests/ui/consts/const-eval/const-eval-overflow-2.stderr index fc0baf11051..5599ff931e8 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-2.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-2.stderr @@ -4,12 +4,6 @@ error[E0080]: evaluation of constant value failed LL | const NEG_NEG_128: i8 = -NEG_128; | ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow -error: could not evaluate constant pattern - --> $DIR/const-eval-overflow-2.rs:15:9 - | -LL | NEG_NEG_128 => println!("A"), - | ^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr b/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr index 8175fe6016a..18935626af1 100644 --- a/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr +++ b/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr @@ -7,12 +7,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error: could not evaluate constant pattern - --> $DIR/ref_to_int_match.rs:7:14 - | -LL | 10..=BAR => {}, - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr b/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr index 8175fe6016a..18935626af1 100644 --- a/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr +++ b/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr @@ -7,12 +7,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error: could not evaluate constant pattern - --> $DIR/ref_to_int_match.rs:7:14 - | -LL | 10..=BAR => {}, - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/ref_to_int_match.rs b/tests/ui/consts/const-eval/ref_to_int_match.rs index c627ad97bb0..be9420e0215 100644 --- a/tests/ui/consts/const-eval/ref_to_int_match.rs +++ b/tests/ui/consts/const-eval/ref_to_int_match.rs @@ -4,7 +4,7 @@ fn main() { let n: Int = 40; match n { 0..=10 => {}, - 10..=BAR => {}, //~ ERROR could not evaluate constant pattern + 10..=BAR => {}, // ok, `const` error already emitted _ => {}, } } diff --git a/tests/ui/consts/const-extern-function.rs b/tests/ui/consts/const-extern-function.rs index acc438189cb..7629d63266a 100644 --- a/tests/ui/consts/const-extern-function.rs +++ b/tests/ui/consts/const-extern-function.rs @@ -1,5 +1,7 @@ //@ run-pass + #![allow(non_upper_case_globals)] +#![allow(unpredictable_function_pointer_comparisons)] extern "C" fn foopy() {} diff --git a/tests/ui/consts/const-fn-error.rs b/tests/ui/consts/const-fn-error.rs index 42061ef0670..b7151782423 100644 --- a/tests/ui/consts/const-fn-error.rs +++ b/tests/ui/consts/const-fn-error.rs @@ -3,9 +3,8 @@ const X : usize = 2; const fn f(x: usize) -> usize { let mut sum = 0; for i in 0..x { - //~^ ERROR cannot convert - //~| ERROR `for` is not allowed in a `const fn` - //~| ERROR cannot call non-const fn + //~^ ERROR cannot use `for` + //~| ERROR cannot use `for` sum += i; } sum diff --git a/tests/ui/consts/const-fn-error.stderr b/tests/ui/consts/const-fn-error.stderr index 42a6f2704c9..3d4cf6539c8 100644 --- a/tests/ui/consts/const-fn-error.stderr +++ b/tests/ui/consts/const-fn-error.stderr @@ -1,37 +1,20 @@ -error[E0658]: `for` is not allowed in a `const fn` - --> $DIR/const-fn-error.rs:5:5 - | -LL | / for i in 0..x { -LL | | -LL | | -LL | | -LL | | sum += i; -LL | | } - | |_____^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0015]: cannot convert `std::ops::Range<usize>` into an iterator in constant functions +error[E0015]: cannot use `for` loop on `std::ops::Range<usize>` in constant functions --> $DIR/const-fn-error.rs:5:14 | LL | for i in 0..x { | ^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const fn `<std::ops::Range<usize> as Iterator>::next` in constant functions +error[E0015]: cannot use `for` loop on `std::ops::Range<usize>` in constant functions --> $DIR/const-fn-error.rs:5:14 | LL | for i in 0..x { | ^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0658. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-for-feature-gate.rs b/tests/ui/consts/const-for-feature-gate.rs index d74178662b3..b643e63c096 100644 --- a/tests/ui/consts/const-for-feature-gate.rs +++ b/tests/ui/consts/const-for-feature-gate.rs @@ -2,9 +2,8 @@ const _: () = { for _ in 0..5 {} - //~^ error: `for` is not allowed in a `const` - //~| ERROR: cannot convert - //~| ERROR: cannot call + //~^ ERROR cannot use `for` + //~| ERROR cannot use `for` }; fn main() {} diff --git a/tests/ui/consts/const-for-feature-gate.stderr b/tests/ui/consts/const-for-feature-gate.stderr index 6e099a3159d..29db5d24ac8 100644 --- a/tests/ui/consts/const-for-feature-gate.stderr +++ b/tests/ui/consts/const-for-feature-gate.stderr @@ -1,32 +1,20 @@ -error[E0658]: `for` is not allowed in a `const` - --> $DIR/const-for-feature-gate.rs:4:5 - | -LL | for _ in 0..5 {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0015]: cannot convert `std::ops::Range<i32>` into an iterator in constants +error[E0015]: cannot use `for` loop on `std::ops::Range<i32>` in constants --> $DIR/const-for-feature-gate.rs:4:14 | LL | for _ in 0..5 {} | ^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants +error[E0015]: cannot use `for` loop on `std::ops::Range<i32>` in constants --> $DIR/const-for-feature-gate.rs:4:14 | LL | for _ in 0..5 {} | ^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0658. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-for.rs b/tests/ui/consts/const-for.rs index 4f8034e73f0..6f7895457c5 100644 --- a/tests/ui/consts/const-for.rs +++ b/tests/ui/consts/const-for.rs @@ -2,8 +2,8 @@ const _: () = { for _ in 0..5 {} - //~^ error: cannot call - //~| error: cannot convert + //~^ ERROR cannot use `for` + //~| ERROR cannot use `for` }; fn main() {} diff --git a/tests/ui/consts/const-for.stderr b/tests/ui/consts/const-for.stderr index 78336dc93e8..d1308a8dedc 100644 --- a/tests/ui/consts/const-for.stderr +++ b/tests/ui/consts/const-for.stderr @@ -1,20 +1,19 @@ -error[E0015]: cannot convert `std::ops::Range<i32>` into an iterator in constants +error[E0015]: cannot use `for` loop on `std::ops::Range<i32>` in constants --> $DIR/const-for.rs:4:14 | LL | for _ in 0..5 {} | ^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants +error[E0015]: cannot use `for` loop on `std::ops::Range<i32>` in constants --> $DIR/const-for.rs:4:14 | LL | for _ in 0..5 {} | ^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-integer-bool-ops.stderr b/tests/ui/consts/const-integer-bool-ops.stderr index 4e503e5a5c0..d58a8e93ff6 100644 --- a/tests/ui/consts/const-integer-bool-ops.stderr +++ b/tests/ui/consts/const-integer-bool-ops.stderr @@ -16,6 +16,12 @@ error[E0308]: mismatched types LL | const X: usize = 42 && 39; | ^^^^^^^^ expected `usize`, found `bool` +note: erroneous constant encountered + --> $DIR/const-integer-bool-ops.rs:8:18 + | +LL | const ARR: [i32; X] = [99; 34]; + | ^ + error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:10:19 | @@ -34,6 +40,12 @@ error[E0308]: mismatched types LL | const X1: usize = 42 || 39; | ^^^^^^^^ expected `usize`, found `bool` +note: erroneous constant encountered + --> $DIR/const-integer-bool-ops.rs:17:19 + | +LL | const ARR1: [i32; X1] = [99; 47]; + | ^^ + error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:19:19 | @@ -52,6 +64,12 @@ error[E0308]: mismatched types LL | const X2: usize = -42 || -39; | ^^^^^^^^^^ expected `usize`, found `bool` +note: erroneous constant encountered + --> $DIR/const-integer-bool-ops.rs:26:19 + | +LL | const ARR2: [i32; X2] = [99; 18446744073709551607]; + | ^^ + error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:28:19 | @@ -70,42 +88,84 @@ error[E0308]: mismatched types LL | const X3: usize = -42 && -39; | ^^^^^^^^^^ expected `usize`, found `bool` +note: erroneous constant encountered + --> $DIR/const-integer-bool-ops.rs:35:19 + | +LL | const ARR3: [i32; X3] = [99; 6]; + | ^^ + error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:37:18 | LL | const Y: usize = 42.0 == 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` +note: erroneous constant encountered + --> $DIR/const-integer-bool-ops.rs:40:19 + | +LL | const ARRR: [i32; Y] = [99; 1]; + | ^ + error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:42:19 | LL | const Y1: usize = 42.0 >= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` +note: erroneous constant encountered + --> $DIR/const-integer-bool-ops.rs:45:20 + | +LL | const ARRR1: [i32; Y1] = [99; 1]; + | ^^ + error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:47:19 | LL | const Y2: usize = 42.0 <= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` +note: erroneous constant encountered + --> $DIR/const-integer-bool-ops.rs:50:20 + | +LL | const ARRR2: [i32; Y2] = [99; 1]; + | ^^ + error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:52:19 | LL | const Y3: usize = 42.0 > 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` +note: erroneous constant encountered + --> $DIR/const-integer-bool-ops.rs:55:20 + | +LL | const ARRR3: [i32; Y3] = [99; 0]; + | ^^ + error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:57:19 | LL | const Y4: usize = 42.0 < 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` +note: erroneous constant encountered + --> $DIR/const-integer-bool-ops.rs:60:20 + | +LL | const ARRR4: [i32; Y4] = [99; 0]; + | ^^ + error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:62:19 | LL | const Y5: usize = 42.0 != 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` +note: erroneous constant encountered + --> $DIR/const-integer-bool-ops.rs:65:20 + | +LL | const ARRR5: [i32; Y5] = [99; 0]; + | ^^ + error: aborting due to 18 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-mut-refs/issue-76510.stderr b/tests/ui/consts/const-mut-refs/issue-76510.stderr index aff86e83578..a63be676fda 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.stderr +++ b/tests/ui/consts/const-mut-refs/issue-76510.stderr @@ -4,6 +4,12 @@ error[E0764]: mutable references are not allowed in the final value of constants LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ +note: erroneous constant encountered + --> $DIR/issue-76510.rs:7:70 + | +LL | let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3)); + | ^ + error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0764`. diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs index 4df3a793b4c..598904d3c44 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs @@ -1,6 +1,5 @@ #![feature(extern_types)] #![feature(core_intrinsics)] -#![feature(const_size_of_val, const_align_of_val)] use std::intrinsics::{min_align_of_val, size_of_val}; diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr index ad2de0f4d31..4c0252123a4 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/const-size_of_val-align_of_val-extern-type.rs:11:31 + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:31 | LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout error[E0080]: evaluation of constant value failed - --> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:32 + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:11:32 | LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout diff --git a/tests/ui/consts/const-size_of_val-align_of_val.rs b/tests/ui/consts/const-size_of_val-align_of_val.rs index ee9dfca0170..d4b5a903517 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val.rs +++ b/tests/ui/consts/const-size_of_val-align_of_val.rs @@ -1,7 +1,6 @@ //@ run-pass -#![feature(const_size_of_val, const_align_of_val)] -#![feature(const_size_of_val_raw, const_align_of_val_raw, layout_for_ptr)] +#![feature(layout_for_ptr)] use std::{mem, ptr}; diff --git a/tests/ui/consts/const-try-feature-gate.rs b/tests/ui/consts/const-try-feature-gate.rs index 1cc045bf612..09985079e8e 100644 --- a/tests/ui/consts/const-try-feature-gate.rs +++ b/tests/ui/consts/const-try-feature-gate.rs @@ -2,9 +2,8 @@ const fn t() -> Option<()> { Some(())?; - //~^ error: `?` is not allowed in a `const fn` - //~| ERROR: cannot convert - //~| ERROR: cannot determine + //~^ ERROR `?` is not allowed + //~| ERROR `?` is not allowed None } diff --git a/tests/ui/consts/const-try-feature-gate.stderr b/tests/ui/consts/const-try-feature-gate.stderr index dc1dabc2f4f..0ad19d05b38 100644 --- a/tests/ui/consts/const-try-feature-gate.stderr +++ b/tests/ui/consts/const-try-feature-gate.stderr @@ -1,34 +1,19 @@ -error[E0658]: `?` is not allowed in a `const fn` +error[E0015]: `?` is not allowed on `Option<()>` in constant functions --> $DIR/const-try-feature-gate.rs:4:5 | LL | Some(())?; | ^^^^^^^^^ | - = note: see issue #74935 <https://github.com/rust-lang/rust/issues/74935> for more information - = help: add `#![feature(const_try)]` 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[E0015]: `?` cannot determine the branch of `Option<()>` in constant functions - --> $DIR/const-try-feature-gate.rs:4:5 - | -LL | Some(())?; - | ^^^^^^^^^ - | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/option.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0015]: `?` cannot convert from residual of `Option<()>` in constant functions +error[E0015]: `?` is not allowed on `Option<()>` in constant functions --> $DIR/const-try-feature-gate.rs:4:5 | LL | Some(())?; | ^^^^^^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/option.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0658. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-try.rs b/tests/ui/consts/const-try.rs index d30b22accef..26aa9230a39 100644 --- a/tests/ui/consts/const-try.rs +++ b/tests/ui/consts/const-try.rs @@ -33,8 +33,8 @@ impl const Try for TryMe { const fn t() -> TryMe { TryMe?; - //~^ ERROR `?` cannot determine the branch of `TryMe` in constant functions - //~| ERROR `?` cannot convert from residual of `TryMe` in constant functions + //~^ ERROR `?` is not allowed on + //~| ERROR `?` is not allowed on TryMe } diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 1f4f814cb93..abb03a74c82 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -16,7 +16,7 @@ LL | impl const Try for TryMe { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions +error[E0015]: `?` is not allowed on `TryMe` in constant functions --> $DIR/const-try.rs:35:5 | LL | TryMe?; @@ -24,7 +24,7 @@ LL | TryMe?; | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions +error[E0015]: `?` is not allowed on `TryMe` in constant functions --> $DIR/const-try.rs:35:5 | LL | TryMe?; diff --git a/tests/ui/consts/const-tup-index-span.stderr b/tests/ui/consts/const-tup-index-span.stderr index 792e18aa8fd..2a3f0cfb06d 100644 --- a/tests/ui/consts/const-tup-index-span.stderr +++ b/tests/ui/consts/const-tup-index-span.stderr @@ -11,6 +11,12 @@ help: use a trailing comma to create a tuple with one element LL | const TUP: (usize,) = (5usize << 64,); | + ++ +note: erroneous constant encountered + --> $DIR/const-tup-index-span.rs:6:18 + | +LL | const ARR: [i32; TUP.0] = []; + | ^^^ + error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs index 163a47f4333..f02e780f30e 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs @@ -9,15 +9,13 @@ fn main() { let _ = Defaulted; match None { consts::SOME => panic!(), - //~^ must be annotated with `#[derive(PartialEq)]` - + //~^ ERROR constant of non-structural type `CustomEq` in a pattern _ => {} } match None { <Defaulted as consts::AssocConst>::SOME => panic!(), - //~^ must be annotated with `#[derive(PartialEq)]` - + //~^ ERROR constant of non-structural type `CustomEq` in a pattern _ => {} } } diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr index e0f97a9abd2..7cada883645 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr @@ -1,19 +1,33 @@ -error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `CustomEq` in a pattern --> $DIR/cross-crate-fail.rs:11:9 | LL | consts::SOME => panic!(), - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ constant of non-structural type + | + ::: $DIR/auxiliary/consts.rs:1:1 + | +LL | pub struct CustomEq; + | ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | pub const SOME: Option<CustomEq> = Some(CustomEq); + | -------------------------------- constant defined here | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cross-crate-fail.rs:18:9 +error: constant of non-structural type `CustomEq` in a pattern + --> $DIR/cross-crate-fail.rs:17:9 | LL | <Defaulted as consts::AssocConst>::SOME => panic!(), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type + | + ::: $DIR/auxiliary/consts.rs:1:1 + | +LL | pub struct CustomEq; + | ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const SOME: Option<CustomEq> = Some(CustomEq); + | ---------------------------- constant defined here | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr index aa208341c13..0453a88e43d 100644 --- a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr +++ b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr @@ -1,26 +1,46 @@ -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:9:9 | +LL | const C: *const u8 = &0; + | ------------------ constant defined here +... LL | C => {} - | ^ + | ^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:16:9 | +LL | const C_INNER: (*const u8, u8) = (C, 0); + | ------------------------------ constant defined here +... LL | C_INNER => {} - | ^^^^^^^ + | ^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:27:9 | +LL | const D: *const [u8; 4] = b"abcd"; + | ----------------------- constant defined here +... LL | D => {} - | ^ + | ^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:32:9 | +LL | const STR: *const str = "abcd"; + | --------------------- constant defined here +... LL | STR => {} - | ^^^ + | ^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details error: aborting due to 4 previous errors diff --git a/tests/ui/consts/const_in_pattern/issue-44333.stderr b/tests/ui/consts/const_in_pattern/issue-44333.stderr index d377bfd95f9..61b45377c76 100644 --- a/tests/ui/consts/const_in_pattern/issue-44333.stderr +++ b/tests/ui/consts/const_in_pattern/issue-44333.stderr @@ -1,14 +1,24 @@ -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-44333.rs:15:9 | +LL | const FOO: Func = foo; + | --------------- constant defined here +... LL | FOO => println!("foo"), - | ^^^ + | ^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-44333.rs:16:9 | +LL | const BAR: Func = bar; + | --------------- constant defined here +... LL | BAR => println!("bar"), - | ^^^ + | ^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const_in_pattern/issue-65466.rs b/tests/ui/consts/const_in_pattern/issue-65466.rs index 62efce64876..82838657b02 100644 --- a/tests/ui/consts/const_in_pattern/issue-65466.rs +++ b/tests/ui/consts/const_in_pattern/issue-65466.rs @@ -11,7 +11,7 @@ const C: &[O<B>] = &[O::None]; fn main() { let x = O::None; match &[x][..] { - C => (), //~ERROR: the type must implement `PartialEq` + C => (), //~ ERROR constant of non-structural type `&[O<B>]` in a pattern _ => (), } } diff --git a/tests/ui/consts/const_in_pattern/issue-65466.stderr b/tests/ui/consts/const_in_pattern/issue-65466.stderr index 7d5e5b5b0c6..511a38bbc00 100644 --- a/tests/ui/consts/const_in_pattern/issue-65466.stderr +++ b/tests/ui/consts/const_in_pattern/issue-65466.stderr @@ -1,8 +1,16 @@ -error: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq` +error: constant of non-structural type `&[O<B>]` in a pattern --> $DIR/issue-65466.rs:14:9 | +LL | struct B; + | -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns +LL | +LL | const C: &[O<B>] = &[O::None]; + | ---------------- constant defined here +... LL | C => (), - | ^ + | ^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs index cf013c1a790..91ef5ac5329 100644 --- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs +++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs @@ -16,8 +16,7 @@ const BAR_BAZ: Foo = if 42 == 42 { fn main() { match Foo::Qux(NoEq) { - BAR_BAZ => panic!(), - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + BAR_BAZ => panic!(), //~ ERROR constant of non-structural type `Foo` in a pattern _ => {} } } diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr index 7766c6ce683..154c94c6d38 100644 --- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr +++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr @@ -1,10 +1,15 @@ -error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `Foo` in a pattern --> $DIR/no-eq-branch-fail.rs:19:9 | +LL | enum Foo { + | -------- `Foo` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const BAR_BAZ: Foo = if 42 == 42 { + | ------------------ constant defined here +... LL | BAR_BAZ => panic!(), - | ^^^^^^^ + | ^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs index 645e1418912..e555ecfeb8f 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs @@ -26,7 +26,7 @@ fn main() { match None { NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"), - //~^ ERROR must implement `PartialEq` + //~^ ERROR constant of non-structural type `Option<NoPartialEq>` in a pattern _ => panic!("whoops"), } } diff --git a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr index ed531a1fead..43894f00886 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr @@ -1,8 +1,16 @@ -error: to use a constant of type `Option<NoPartialEq>` in a pattern, the type must implement `PartialEq` +error: constant of non-structural type `Option<NoPartialEq>` in a pattern --> $DIR/reject_non_partial_eq.rs:28:9 | +LL | struct NoPartialEq(u32); + | ------------------ must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const NO_PARTIAL_EQ_NONE: Option<NoPartialEq> = None; + | --------------------------------------------- constant defined here +... LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"), - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs index e3dcecec960..39e5f732a89 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs @@ -17,9 +17,29 @@ struct NoPartialEq; #[derive(Copy, Clone, Debug)] struct NoDerive; +//~^ NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` +//~| NOTE must be annotated with `#[derive(PartialEq)]` // This impl makes `NoDerive` irreflexive. impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } +//~^ NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details +//~| NOTE StructuralPartialEq.html for details impl Eq for NoDerive { } @@ -36,65 +56,55 @@ fn main() { #[derive(PartialEq, Eq, Debug)] enum Derive<X> { Some(X), None, } - const ENUM: Derive<NoDerive> = Derive::Some(NoDerive); + const ENUM: Derive<NoDerive> = Derive::Some(NoDerive); //~ NOTE constant defined here match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const FIELD: OND = TrivialEq(Some(NoDerive)).0; + const FIELD: OND = TrivialEq(Some(NoDerive)).0; //~ NOTE constant defined here match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type const NO_DERIVE_SOME: OND = Some(NoDerive); - const INDIRECT: OND = NO_DERIVE_SOME; + const INDIRECT: OND = NO_DERIVE_SOME; //~ NOTE constant defined here match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const TUPLE: (OND, OND) = (None, Some(NoDerive)); + const TUPLE: (OND, OND) = (None, Some(NoDerive)); //~ NOTE constant defined here match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND); + const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND); //~ NOTE constant defined here match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const ARRAY: [OND; 2] = [None, Some(NoDerive)]; + const ARRAY: [OND; 2] = [None, Some(NoDerive)]; //~ NOTE constant defined here match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const REPEAT: [OND; 2] = [Some(NoDerive); 2]; + const REPEAT: [OND; 2] = [Some(NoDerive); 2]; //~ NOTE constant defined here match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - trait Trait: Sized { const ASSOC: Option<Self>; } + trait Trait: Sized { const ASSOC: Option<Self>; } //~ NOTE constant defined here impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); } match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const BLOCK: OND = { NoDerive; Some(NoDerive) }; + const BLOCK: OND = { NoDerive; Some(NoDerive) }; //~ NOTE constant defined here match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type - const ADDR_OF: &OND = &Some(NoDerive); + const ADDR_OF: &OND = &Some(NoDerive); //~ NOTE constant defined here match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; - //~^ ERROR must be annotated with `#[derive(PartialEq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralPartialEq.html for details + //~^ ERROR constant of non-structural type `NoDerive` in a pattern + //~| NOTE constant of non-structural type } diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr index c068db42e4d..fa16d0b06a7 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr @@ -1,92 +1,173 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:40:36 - | +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:60:36 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const ENUM: Derive<NoDerive> = Derive::Some(NoDerive); + | ---------------------------- constant defined here LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; - | ^^^^ + | ^^^^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:46:28 +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:65:28 | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const FIELD: OND = TrivialEq(Some(NoDerive)).0; + | ---------------- constant defined here LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; - | ^^^^^ + | ^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:53:27 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:71:27 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const INDIRECT: OND = NO_DERIVE_SOME; + | ------------------- constant defined here LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; - | ^^^^^^^^ + | ^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:59:36 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:76:36 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const TUPLE: (OND, OND) = (None, Some(NoDerive)); + | ----------------------- constant defined here LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; - | ^^^^^ + | ^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:65:28 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:81:28 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND); + | -------------------------- constant defined here LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:71:36 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:86:36 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const ARRAY: [OND; 2] = [None, Some(NoDerive)]; + | --------------------- constant defined here LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; - | ^^^^^ + | ^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:77:33 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:91:33 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const REPEAT: [OND; 2] = [Some(NoDerive); 2]; + | ---------------------- constant defined here LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; - | ^^^^^^ + | ^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:84:28 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:97:28 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | trait Trait: Sized { const ASSOC: Option<Self>; } + | ------------------ ------------------------- constant defined here +LL | impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); } LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:90:28 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:102:28 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const BLOCK: OND = { NoDerive; Some(NoDerive) }; + | ---------------- constant defined here LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; - | ^^^^^ + | ^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:96:29 +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: constant of non-structural type `NoDerive` in a pattern + --> $DIR/reject_non_structural.rs:107:29 + | +LL | struct NoDerive; + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const ADDR_OF: &OND = &Some(NoDerive); + | ------------------- constant defined here LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; - | ^^^^^^^ + | ^^^^^^^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/reject_non_structural.rs:32:1 | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 10 previous errors diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs index a160862a0fa..aa101cf9d8a 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -11,7 +11,7 @@ fn invalid() { // This must be rejected here (or earlier), since it's not a valid `&bool`. match &true { - C => {} //~ERROR: could not evaluate constant pattern + C => {} // ok, `const` already emitted an error _ => {} } } @@ -27,7 +27,7 @@ fn extern_() { // This must be rejected here (or earlier), since the pattern cannot be read. match &0 { - C => {} //~ERROR: could not evaluate constant pattern + C => {} // ok, `const` already emitted an error _ => {} } } @@ -42,7 +42,7 @@ fn mutable() { // This *must not build*, the constant we are matching against // could change its value! match &42 { - C => {} //~ERROR: could not evaluate constant pattern + C => {} // ok, `const` already emitted an error _ => {} } } diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr index 0153f501174..c9d5cb60bf7 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr @@ -31,24 +31,6 @@ LL | const C: &i32 = unsafe { &S_MUT }; HEX_DUMP } -error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:14:9 - | -LL | C => {} - | ^ - -error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:30:9 - | -LL | C => {} - | ^ - -error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:45:9 - | -LL | C => {} - | ^ - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/control-flow/loop.rs b/tests/ui/consts/control-flow/loop.rs index f8d9f3ddb9b..b02c31c4c25 100644 --- a/tests/ui/consts/control-flow/loop.rs +++ b/tests/ui/consts/control-flow/loop.rs @@ -50,15 +50,15 @@ const _: i32 = { const _: i32 = { let mut x = 0; - for i in 0..4 { //~ ERROR `for` is not allowed in a `const` - //~^ ERROR: cannot call - //~| ERROR: cannot convert + for i in 0..4 { + //~^ ERROR: cannot use `for` + //~| ERROR: cannot use `for` x += i; } - for i in 0..4 { //~ ERROR `for` is not allowed in a `const` - //~^ ERROR: cannot call - //~| ERROR: cannot convert + for i in 0..4 { + //~^ ERROR: cannot use `for` + //~| ERROR: cannot use `for` x += i; } diff --git a/tests/ui/consts/control-flow/loop.stderr b/tests/ui/consts/control-flow/loop.stderr index 5e43c70e9df..b91371f9dc2 100644 --- a/tests/ui/consts/control-flow/loop.stderr +++ b/tests/ui/consts/control-flow/loop.stderr @@ -1,68 +1,37 @@ -error[E0658]: `for` is not allowed in a `const` - --> $DIR/loop.rs:53:5 - | -LL | / for i in 0..4 { -LL | | -LL | | -LL | | x += i; -LL | | } - | |_____^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0658]: `for` is not allowed in a `const` - --> $DIR/loop.rs:59:5 - | -LL | / for i in 0..4 { -LL | | -LL | | -LL | | x += i; -LL | | } - | |_____^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0015]: cannot convert `std::ops::Range<i32>` into an iterator in constants +error[E0015]: cannot use `for` loop on `std::ops::Range<i32>` in constants --> $DIR/loop.rs:53:14 | LL | for i in 0..4 { | ^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants +error[E0015]: cannot use `for` loop on `std::ops::Range<i32>` in constants --> $DIR/loop.rs:53:14 | LL | for i in 0..4 { | ^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0015]: cannot convert `std::ops::Range<i32>` into an iterator in constants +error[E0015]: cannot use `for` loop on `std::ops::Range<i32>` in constants --> $DIR/loop.rs:59:14 | LL | for i in 0..4 { | ^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants +error[E0015]: cannot use `for` loop on `std::ops::Range<i32>` in constants --> $DIR/loop.rs:59:14 | LL | for i in 0..4 { | ^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0015, E0658. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/control-flow/try.rs b/tests/ui/consts/control-flow/try.rs index 5c6957df405..67083e1a39b 100644 --- a/tests/ui/consts/control-flow/try.rs +++ b/tests/ui/consts/control-flow/try.rs @@ -3,9 +3,9 @@ const fn opt() -> Option<i32> { let x = Some(2); - x?; //~ ERROR `?` is not allowed in a `const fn` - //~^ ERROR: cannot convert - //~| ERROR: cannot determine + x?; + //~^ ERROR: `?` is not allowed + //~| ERROR: `?` is not allowed None } diff --git a/tests/ui/consts/control-flow/try.stderr b/tests/ui/consts/control-flow/try.stderr index 5e2c77318e7..62a3e3ce6bc 100644 --- a/tests/ui/consts/control-flow/try.stderr +++ b/tests/ui/consts/control-flow/try.stderr @@ -1,34 +1,19 @@ -error[E0658]: `?` is not allowed in a `const fn` +error[E0015]: `?` is not allowed on `Option<i32>` in constant functions --> $DIR/try.rs:6:5 | LL | x?; | ^^ | - = note: see issue #74935 <https://github.com/rust-lang/rust/issues/74935> for more information - = help: add `#![feature(const_try)]` 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[E0015]: `?` cannot determine the branch of `Option<i32>` in constant functions - --> $DIR/try.rs:6:5 - | -LL | x?; - | ^^ - | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/option.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0015]: `?` cannot convert from residual of `Option<i32>` in constant functions +error[E0015]: `?` is not allowed on `Option<i32>` in constant functions --> $DIR/try.rs:6:5 | LL | x?; | ^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/option.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0658. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr index 2e48837bdcd..b22f99f40d3 100644 --- a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr +++ b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr @@ -11,7 +11,7 @@ error: could not evaluate constant pattern --> $DIR/invalid-inline-const-in-match-arm.rs:5:9 | LL | const { (|| {})() } => {} - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ could not evaluate constant error: aborting due to 2 previous errors diff --git a/tests/ui/consts/issue-43105.rs b/tests/ui/consts/issue-43105.rs index 20b78d64209..a4ee34c0532 100644 --- a/tests/ui/consts/issue-43105.rs +++ b/tests/ui/consts/issue-43105.rs @@ -5,8 +5,7 @@ const NUM: u8 = xyz(); fn main() { match 1 { - NUM => unimplemented!(), - //~^ ERROR could not evaluate constant pattern + NUM => unimplemented!(), // ok, the `const` already emitted an error _ => unimplemented!(), } } diff --git a/tests/ui/consts/issue-43105.stderr b/tests/ui/consts/issue-43105.stderr index 856a8f0dab6..0e08feb58de 100644 --- a/tests/ui/consts/issue-43105.stderr +++ b/tests/ui/consts/issue-43105.stderr @@ -6,12 +6,6 @@ LL | const NUM: u8 = xyz(); | = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error: could not evaluate constant pattern - --> $DIR/issue-43105.rs:8:9 - | -LL | NUM => unimplemented!(), - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/issue-54954.stderr b/tests/ui/consts/issue-54954.stderr index b8c983eb7b8..ed6aa9c44a3 100644 --- a/tests/ui/consts/issue-54954.stderr +++ b/tests/ui/consts/issue-54954.stderr @@ -19,6 +19,24 @@ LL | | core::mem::size_of::<T>() LL | | } | |_____- `Tt::const_val` defined here +note: erroneous constant encountered + --> $DIR/issue-54954.rs:11:15 + | +LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { + | ^^^^^^^ + +note: erroneous constant encountered + --> $DIR/issue-54954.rs:11:34 + | +LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { + | ^^^^^^^ + +note: erroneous constant encountered + --> $DIR/issue-54954.rs:16:22 + | +LL | let _ = f([1f32; ARR_LEN]); + | ^^^^^^^ + error: aborting due to 2 previous errors Some errors have detailed explanations: E0379, E0790. diff --git a/tests/ui/consts/issue-73976-polymorphic.rs b/tests/ui/consts/issue-73976-polymorphic.rs index 2c576d1f9ef..98b4005792d 100644 --- a/tests/ui/consts/issue-73976-polymorphic.rs +++ b/tests/ui/consts/issue-73976-polymorphic.rs @@ -18,7 +18,7 @@ impl<T: 'static> GetTypeId<T> { const fn check_type_id<T: 'static>() -> bool { matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters } pub struct GetTypeNameLen<T>(T); @@ -29,7 +29,7 @@ impl<T: 'static> GetTypeNameLen<T> { const fn check_type_name_len<T: 'static>() -> bool { matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters } fn main() { diff --git a/tests/ui/consts/issue-73976-polymorphic.stderr b/tests/ui/consts/issue-73976-polymorphic.stderr index 8a44eb9854f..ec9512a2616 100644 --- a/tests/ui/consts/issue-73976-polymorphic.stderr +++ b/tests/ui/consts/issue-73976-polymorphic.stderr @@ -1,14 +1,28 @@ -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/issue-73976-polymorphic.rs:20:37 | +LL | impl<T: 'static> GetTypeId<T> { + | ----------------------------- +LL | pub const VALUE: TypeId = TypeId::of::<T>(); + | ----------------------- constant defined here +... +LL | const fn check_type_id<T: 'static>() -> bool { + | - constant depends on this generic parameter LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/issue-73976-polymorphic.rs:31:42 | +LL | impl<T: 'static> GetTypeNameLen<T> { + | ---------------------------------- +LL | pub const VALUE: usize = any::type_name::<T>().len(); + | ---------------------- constant defined here +... +LL | const fn check_type_name_len<T: 'static>() -> bool { + | - constant depends on this generic parameter LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter error: aborting due to 2 previous errors diff --git a/tests/ui/consts/issue-78655.rs b/tests/ui/consts/issue-78655.rs index cd95ee32c60..b0f862e8418 100644 --- a/tests/ui/consts/issue-78655.rs +++ b/tests/ui/consts/issue-78655.rs @@ -4,6 +4,5 @@ const FOO: *const u32 = { }; fn main() { - let FOO = FOO; - //~^ ERROR could not evaluate constant pattern + let FOO = FOO; // ok, the `const` already emitted an error } diff --git a/tests/ui/consts/issue-78655.stderr b/tests/ui/consts/issue-78655.stderr index ccaed03b4c1..6a93c1a8cec 100644 --- a/tests/ui/consts/issue-78655.stderr +++ b/tests/ui/consts/issue-78655.stderr @@ -11,12 +11,6 @@ help: consider assigning a value LL | let x = 42; | ++++ -error: could not evaluate constant pattern - --> $DIR/issue-78655.rs:7:9 - | -LL | let FOO = FOO; - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0381`. diff --git a/tests/ui/consts/issue-79137-toogeneric.rs b/tests/ui/consts/issue-79137-toogeneric.rs index a80c9f48d7b..43e06f3d676 100644 --- a/tests/ui/consts/issue-79137-toogeneric.rs +++ b/tests/ui/consts/issue-79137-toogeneric.rs @@ -10,7 +10,7 @@ impl<T> GetVariantCount<T> { const fn check_variant_count<T>() -> bool { matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE) - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters } fn main() { diff --git a/tests/ui/consts/issue-79137-toogeneric.stderr b/tests/ui/consts/issue-79137-toogeneric.stderr index de81512ec6d..33e32a7d15d 100644 --- a/tests/ui/consts/issue-79137-toogeneric.stderr +++ b/tests/ui/consts/issue-79137-toogeneric.stderr @@ -1,8 +1,15 @@ -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/issue-79137-toogeneric.rs:12:43 | +LL | impl<T> GetVariantCount<T> { + | -------------------------- +LL | pub const VALUE: usize = std::mem::variant_count::<T>(); + | ---------------------- constant defined here +... +LL | const fn check_variant_count<T>() -> bool { + | - constant depends on this generic parameter LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter error: aborting due to 1 previous error diff --git a/tests/ui/consts/issue-87046.stderr b/tests/ui/consts/issue-87046.stderr index 0f965e1ac3f..36e2564fae6 100644 --- a/tests/ui/consts/issue-87046.stderr +++ b/tests/ui/consts/issue-87046.stderr @@ -1,6 +1,9 @@ error: cannot use unsized non-slice type `Username` in constant patterns --> $DIR/issue-87046.rs:28:13 | +LL | pub const ROOT_USER: &Username = Username::from_str("root"); + | ------------------------------ constant defined here +... LL | ROOT_USER => true, | ^^^^^^^^^ diff --git a/tests/ui/consts/issue-89088.rs b/tests/ui/consts/issue-89088.rs index 02a786e7465..f6dbf8f0125 100644 --- a/tests/ui/consts/issue-89088.rs +++ b/tests/ui/consts/issue-89088.rs @@ -13,7 +13,7 @@ fn main() { let var = A::Field(Cow::Borrowed("bar")); match &var { - FOO => todo!(), //~ERROR derive(PartialEq) + FOO => todo!(), //~ ERROR constant of non-structural type `Cow<'_, str>` in a pattern _ => todo!() } } diff --git a/tests/ui/consts/issue-89088.stderr b/tests/ui/consts/issue-89088.stderr index 362c63a2a45..56025e0d9b2 100644 --- a/tests/ui/consts/issue-89088.stderr +++ b/tests/ui/consts/issue-89088.stderr @@ -1,10 +1,15 @@ -error: to use a constant of type `Cow<'_, str>` in a pattern, `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `Cow<'_, str>` in a pattern --> $DIR/issue-89088.rs:16:9 | +LL | const FOO: &A = &A::Field(Cow::Borrowed("foo")); + | ------------- constant defined here +... LL | FOO => todo!(), - | ^^^ + | ^^^ constant of non-structural type + --> $SRC_DIR/alloc/src/borrow.rs:LL:COL + | + = note: `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/match_ice.rs b/tests/ui/consts/match_ice.rs index ed1fd78809b..477a2de09a4 100644 --- a/tests/ui/consts/match_ice.rs +++ b/tests/ui/consts/match_ice.rs @@ -8,8 +8,7 @@ struct T; fn main() { const C: &S = &S; match C { - C => {} - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + C => {} //~ ERROR constant of non-structural type `S` in a pattern } const K: &T = &T; match K { diff --git a/tests/ui/consts/match_ice.stderr b/tests/ui/consts/match_ice.stderr index 472c24a5cbe..95e96bbbd67 100644 --- a/tests/ui/consts/match_ice.stderr +++ b/tests/ui/consts/match_ice.stderr @@ -1,10 +1,15 @@ -error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `S` in a pattern --> $DIR/match_ice.rs:11:9 | +LL | struct S; + | -------- `S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const C: &S = &S; + | ----------- constant defined here +LL | match C { LL | C => {} - | ^ + | ^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index a6d75658c75..facb21a04ef 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -37,16 +37,14 @@ const U8_MUT3: &u8 = { pub fn test(x: &[u8; 1]) -> bool { match x { - SLICE_MUT => true, - //~^ ERROR could not evaluate constant pattern + SLICE_MUT => true, // ok, `const` error already emitted &[1..] => false, } } pub fn test2(x: &u8) -> bool { match x { - U8_MUT => true, - //~^ ERROR could not evaluate constant pattern + U8_MUT => true, // ok, `const` error already emitted &(1..) => false, } } @@ -55,15 +53,13 @@ pub fn test2(x: &u8) -> bool { // the errors above otherwise stop compilation too early? pub fn test3(x: &u8) -> bool { match x { - U8_MUT2 => true, - //~^ ERROR could not evaluate constant pattern + U8_MUT2 => true, // ok, `const` error already emitted &(1..) => false, } } pub fn test4(x: &u8) -> bool { match x { - U8_MUT3 => true, - //~^ ERROR could not evaluate constant pattern + U8_MUT3 => true, // ok, `const` error already emitted &(1..) => false, } } diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr index 147d3f238f7..8f8271cce38 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr @@ -37,30 +37,6 @@ error[E0080]: evaluation of constant value failed LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory -error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:40:9 - | -LL | SLICE_MUT => true, - | ^^^^^^^^^ - -error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:48:9 - | -LL | U8_MUT => true, - | ^^^^^^ - -error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:58:9 - | -LL | U8_MUT2 => true, - | ^^^^^^^ - -error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:65:9 - | -LL | U8_MUT3 => true, - | ^^^^^^^ - -error: aborting due to 8 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/missing_assoc_const_type.rs b/tests/ui/consts/missing_assoc_const_type.rs index 633998e9bc1..61042bfa96d 100644 --- a/tests/ui/consts/missing_assoc_const_type.rs +++ b/tests/ui/consts/missing_assoc_const_type.rs @@ -9,14 +9,13 @@ trait Range { struct TwoDigits; impl Range for TwoDigits { - const FIRST: = 10; - //~^ ERROR: missing type for `const` item + const FIRST: = 10; //~ ERROR missing type for `const` item const LAST: u8 = 99; } const fn digits(x: u8) -> usize { match x { - TwoDigits::FIRST..=TwoDigits::LAST => 0, //~ ERROR: could not evaluate constant pattern + TwoDigits::FIRST..=TwoDigits::LAST => 0, // ok, `const` error already emitted 0..=9 | 100..=255 => panic!(), } } diff --git a/tests/ui/consts/missing_assoc_const_type.stderr b/tests/ui/consts/missing_assoc_const_type.stderr index ef7ff962d2d..28af1f0f321 100644 --- a/tests/ui/consts/missing_assoc_const_type.stderr +++ b/tests/ui/consts/missing_assoc_const_type.stderr @@ -4,11 +4,5 @@ error: missing type for `const` item LL | const FIRST: = 10; | ^ help: provide a type for the associated constant: `u8` -error: could not evaluate constant pattern - --> $DIR/missing_assoc_const_type.rs:19:9 - | -LL | TwoDigits::FIRST..=TwoDigits::LAST => 0, - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/consts/missing_assoc_const_type2.stderr b/tests/ui/consts/missing_assoc_const_type2.stderr index 1255ca2d102..3279a077464 100644 --- a/tests/ui/consts/missing_assoc_const_type2.stderr +++ b/tests/ui/consts/missing_assoc_const_type2.stderr @@ -4,5 +4,11 @@ error: missing type for `const` item LL | const FIRST: = 10; | ^ help: provide a type for the associated constant: `u8` +note: erroneous constant encountered + --> $DIR/missing_assoc_const_type2.rs:18:5 + | +LL | TwoDigits::FIRST as usize + | ^^^^^^^^^^^^^^^^ + error: aborting due to 1 previous error diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr index 50e920f05f9..f5d767efceb 100644 --- a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr +++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr @@ -4,12 +4,6 @@ error[E0080]: evaluation of constant value failed LL | const _: &'static Data = &Data([0; (1 << 47) - 1]); | ^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler -note: erroneous constant encountered - --> $DIR/promoted_running_out_of_memory_issue-130687.rs:8:26 - | -LL | const _: &'static Data = &Data([0; (1 << 47) - 1]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/promoted_size_overflow.rs b/tests/ui/consts/promoted_size_overflow.rs new file mode 100644 index 00000000000..3d606905e78 --- /dev/null +++ b/tests/ui/consts/promoted_size_overflow.rs @@ -0,0 +1,7 @@ +//@ only-64bit +pub struct Data([u8; usize::MAX >> 2]); +const _: &'static [Data] = &[]; +//~^ERROR: evaluation of constant value failed +//~| too big for the target architecture + +fn main() {} diff --git a/tests/ui/consts/promoted_size_overflow.stderr b/tests/ui/consts/promoted_size_overflow.stderr new file mode 100644 index 00000000000..cfb8260bed0 --- /dev/null +++ b/tests/ui/consts/promoted_size_overflow.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/promoted_size_overflow.rs:3:29 + | +LL | const _: &'static [Data] = &[]; + | ^^ values of the type `[u8; 4611686018427387903]` are too big for the target architecture + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/transmute-size-mismatch-before-typeck.rs b/tests/ui/consts/transmute-size-mismatch-before-typeck.rs index 44eac5b16cc..ffb143da2d4 100644 --- a/tests/ui/consts/transmute-size-mismatch-before-typeck.rs +++ b/tests/ui/consts/transmute-size-mismatch-before-typeck.rs @@ -5,7 +5,7 @@ fn main() { match &b""[..] { - ZST => {} //~ ERROR: could not evaluate constant pattern + ZST => {} // ok, `const` error already emitted } } diff --git a/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr b/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr index e0d658db997..6bc7e7203aa 100644 --- a/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr +++ b/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr @@ -7,12 +7,6 @@ LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; = note: source type: `usize` (word size) = note: target type: `&[u8]` (2 * word size) -error: could not evaluate constant pattern - --> $DIR/transmute-size-mismatch-before-typeck.rs:8:9 - | -LL | ZST => {} - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/consts/try-operator.stderr b/tests/ui/consts/try-operator.stderr index 40d96ed3a10..fc37039d260 100644 --- a/tests/ui/consts/try-operator.stderr +++ b/tests/ui/consts/try-operator.stderr @@ -4,44 +4,36 @@ error[E0635]: unknown feature `const_convert` LL | #![feature(const_convert)] | ^^^^^^^^^^^^^ -error[E0015]: `?` cannot determine the branch of `Result<(), ()>` in constant functions +error[E0015]: `?` is not allowed on `Result<(), ()>` in constant functions --> $DIR/try-operator.rs:10:9 | LL | Err(())?; | ^^^^^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/result.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0015]: `?` cannot convert from residual of `Result<bool, ()>` in constant functions +error[E0015]: `?` is not allowed on `Result<bool, ()>` in constant functions --> $DIR/try-operator.rs:10:9 | LL | Err(())?; | ^^^^^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/result.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0015]: `?` cannot determine the branch of `Option<()>` in constant functions +error[E0015]: `?` is not allowed on `Option<()>` in constant functions --> $DIR/try-operator.rs:18:9 | LL | None?; | ^^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/option.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0015]: `?` cannot convert from residual of `Option<()>` in constant functions +error[E0015]: `?` is not allowed on `Option<()>` in constant functions --> $DIR/try-operator.rs:18:9 | LL | None?; | ^^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/option.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 5 previous errors diff --git a/tests/ui/consts/uninhabited-const-issue-61744.rs b/tests/ui/consts/uninhabited-const-issue-61744.rs index 6168268bfed..19ee842c36b 100644 --- a/tests/ui/consts/uninhabited-const-issue-61744.rs +++ b/tests/ui/consts/uninhabited-const-issue-61744.rs @@ -5,15 +5,15 @@ pub const unsafe fn fake_type<T>() -> T { } pub const unsafe fn hint_unreachable() -> ! { - fake_type() + fake_type() //~ inside } trait Const { - const CONSTANT: i32 = unsafe { fake_type() }; + const CONSTANT: i32 = unsafe { fake_type() }; //~ inside } impl<T> Const for T {} pub fn main() -> () { - dbg!(i32::CONSTANT); //~ constant + dbg!(i32::CONSTANT); } diff --git a/tests/ui/consts/uninhabited-const-issue-61744.stderr b/tests/ui/consts/uninhabited-const-issue-61744.stderr index c6dd11ee5db..7575ad730b3 100644 --- a/tests/ui/consts/uninhabited-const-issue-61744.stderr +++ b/tests/ui/consts/uninhabited-const-issue-61744.stderr @@ -645,20 +645,6 @@ note: inside `<i32 as Const>::CONSTANT` LL | const CONSTANT: i32 = unsafe { fake_type() }; | ^^^^^^^^^^^ -note: erroneous constant encountered - --> $DIR/uninhabited-const-issue-61744.rs:18:10 - | -LL | dbg!(i32::CONSTANT); - | ^^^^^^^^^^^^^ - -note: erroneous constant encountered - --> $DIR/uninhabited-const-issue-61744.rs:18:10 - | -LL | dbg!(i32::CONSTANT); - | ^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/coroutine/coroutine-in-orphaned-anon-const.rs b/tests/ui/coroutine/coroutine-in-orphaned-anon-const.rs index 07c13239a2c..c98ec1de17e 100644 --- a/tests/ui/coroutine/coroutine-in-orphaned-anon-const.rs +++ b/tests/ui/coroutine/coroutine-in-orphaned-anon-const.rs @@ -3,8 +3,6 @@ trait X { fn test() -> Self::Assoc<{ async {} }>; //~^ ERROR associated type `Assoc` not found for `Self` - //~| ERROR associated type `Assoc` not found for `Self` - } pub fn main() {} diff --git a/tests/ui/coroutine/coroutine-in-orphaned-anon-const.stderr b/tests/ui/coroutine/coroutine-in-orphaned-anon-const.stderr index 864c6556d79..58553728753 100644 --- a/tests/ui/coroutine/coroutine-in-orphaned-anon-const.stderr +++ b/tests/ui/coroutine/coroutine-in-orphaned-anon-const.stderr @@ -4,14 +4,6 @@ error[E0220]: associated type `Assoc` not found for `Self` LL | fn test() -> Self::Assoc<{ async {} }>; | ^^^^^ associated type `Assoc` not found -error[E0220]: associated type `Assoc` not found for `Self` - --> $DIR/coroutine-in-orphaned-anon-const.rs:4:24 - | -LL | fn test() -> Self::Assoc<{ async {} }>; - | ^^^^^ associated type `Assoc` not found - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/cross-crate/const-cross-crate-extern.rs b/tests/ui/cross-crate/const-cross-crate-extern.rs index 8d48a6a5206..0ec8753c30f 100644 --- a/tests/ui/cross-crate/const-cross-crate-extern.rs +++ b/tests/ui/cross-crate/const-cross-crate-extern.rs @@ -1,6 +1,8 @@ //@ run-pass //@ aux-build:cci_const.rs + #![allow(non_upper_case_globals)] +#![allow(unpredictable_function_pointer_comparisons)] extern crate cci_const; use cci_const::bar; diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.rs b/tests/ui/deriving/deriving-coerce-pointee-neg.rs index deef35cdf70..da25c854c54 100644 --- a/tests/ui/deriving/deriving-coerce-pointee-neg.rs +++ b/tests/ui/deriving/deriving-coerce-pointee-neg.rs @@ -29,7 +29,7 @@ struct NoFieldUnit<'a, #[pointee] T: ?Sized>(); struct NoGeneric<'a>(&'a u8); #[derive(CoercePointee)] -//~^ ERROR: exactly one generic type parameter must be marked as #[pointee] to derive CoercePointee traits +//~^ ERROR: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits #[repr(transparent)] struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> { a: (&'a T1, &'a T2), @@ -38,7 +38,7 @@ struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> { #[derive(CoercePointee)] #[repr(transparent)] struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B)); -//~^ ERROR: only one type parameter can be marked as `#[pointee]` when deriving CoercePointee traits +//~^ ERROR: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits #[derive(CoercePointee)] //~^ ERROR: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]` @@ -49,7 +49,7 @@ struct NotTransparent<'a, #[pointee] T: ?Sized> { #[derive(CoercePointee)] #[repr(transparent)] struct NoMaybeSized<'a, #[pointee] T> { - //~^ ERROR: `derive(CoercePointee)` requires T to be marked `?Sized` + //~^ ERROR: `derive(CoercePointee)` requires `T` to be marked `?Sized` ptr: &'a T, } diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr index e590d636d0e..c1e8be49d37 100644 --- a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr +++ b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr @@ -30,7 +30,7 @@ LL | #[derive(CoercePointee)] | = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) -error: exactly one generic type parameter must be marked as #[pointee] to derive CoercePointee traits +error: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits --> $DIR/deriving-coerce-pointee-neg.rs:31:10 | LL | #[derive(CoercePointee)] @@ -38,11 +38,11 @@ LL | #[derive(CoercePointee)] | = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) -error: only one type parameter can be marked as `#[pointee]` when deriving CoercePointee traits +error: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits --> $DIR/deriving-coerce-pointee-neg.rs:40:39 | LL | struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B)); - | ^ ^ + | ^ - here another type parameter is marked as `#[pointee]` error: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]` --> $DIR/deriving-coerce-pointee-neg.rs:43:10 @@ -52,7 +52,7 @@ LL | #[derive(CoercePointee)] | = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `derive(CoercePointee)` requires T to be marked `?Sized` +error: `derive(CoercePointee)` requires `T` to be marked `?Sized` --> $DIR/deriving-coerce-pointee-neg.rs:51:36 | LL | struct NoMaybeSized<'a, #[pointee] T> { diff --git a/tests/ui/drop/lint-if-let-rescope.fixed b/tests/ui/drop/lint-if-let-rescope.fixed index fec2e3b2ae7..182190aa323 100644 --- a/tests/ui/drop/lint-if-let-rescope.fixed +++ b/tests/ui/drop/lint-if-let-rescope.fixed @@ -14,7 +14,7 @@ impl Drop for Droppy { } } impl Droppy { - fn get(&self) -> Option<u8> { + const fn get(&self) -> Option<u8> { None } } @@ -62,11 +62,10 @@ fn main() { //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } - if let () = { match Droppy.get() { Some(_value) => {} _ => {}} } { - //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 - //~| WARN: this changes meaning in Rust 2024 - //~| HELP: the value is now dropped here in Edition 2024 - //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 + if let () = { if let Some(_value) = Droppy.get() {} } { + // This should not lint. + // This `if let` sits is a tail expression of a block. + // In Edition 2024, the temporaries are dropped before exiting the surrounding block. } #[rustfmt::skip] @@ -94,4 +93,17 @@ fn main() { //~| HELP: the value is now dropped here in Edition 2024 //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } + + // We want to keep the `if let`s below as direct descendents of match arms, + // so the formatting is suppressed. + #[rustfmt::skip] + match droppy().get() { + _ => if let Some(_value) = droppy().get() {}, + // Should not lint + // There is implicitly a block surrounding the `if let`. + // Given that it is a tail expression, the temporaries are dropped duly before + // the execution is exiting the `match`. + } + + if let Some(_value) = droppy().get() {} } diff --git a/tests/ui/drop/lint-if-let-rescope.rs b/tests/ui/drop/lint-if-let-rescope.rs index ee184695b97..e1b38be0a0f 100644 --- a/tests/ui/drop/lint-if-let-rescope.rs +++ b/tests/ui/drop/lint-if-let-rescope.rs @@ -14,7 +14,7 @@ impl Drop for Droppy { } } impl Droppy { - fn get(&self) -> Option<u8> { + const fn get(&self) -> Option<u8> { None } } @@ -63,10 +63,9 @@ fn main() { } if let () = { if let Some(_value) = Droppy.get() {} } { - //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 - //~| WARN: this changes meaning in Rust 2024 - //~| HELP: the value is now dropped here in Edition 2024 - //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 + // This should not lint. + // This `if let` sits is a tail expression of a block. + // In Edition 2024, the temporaries are dropped before exiting the surrounding block. } #[rustfmt::skip] @@ -94,4 +93,17 @@ fn main() { //~| HELP: the value is now dropped here in Edition 2024 //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } + + // We want to keep the `if let`s below as direct descendents of match arms, + // so the formatting is suppressed. + #[rustfmt::skip] + match droppy().get() { + _ => if let Some(_value) = droppy().get() {}, + // Should not lint + // There is implicitly a block surrounding the `if let`. + // Given that it is a tail expression, the temporaries are dropped duly before + // the execution is exiting the `match`. + } + + if let Some(_value) = droppy().get() {} } diff --git a/tests/ui/drop/lint-if-let-rescope.stderr b/tests/ui/drop/lint-if-let-rescope.stderr index ef60d141b79..cfb7070c097 100644 --- a/tests/ui/drop/lint-if-let-rescope.stderr +++ b/tests/ui/drop/lint-if-let-rescope.stderr @@ -112,27 +112,7 @@ LL | if let Some(1) = { match Droppy.get() { Some(_value) => { Some(1) } _ = | ~~~~~ +++++++++++++++++ ~~~~ + error: `if let` assigns a shorter lifetime since Edition 2024 - --> $DIR/lint-if-let-rescope.rs:65:22 - | -LL | if let () = { if let Some(_value) = Droppy.get() {} } { - | ^^^^^^^^^^^^^^^^^^^------^^^^^^ - | | - | this value has a significant drop implementation which may observe a major change in drop order and requires your discretion - | - = warning: this changes meaning in Rust 2024 - = note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085> -help: the value is now dropped here in Edition 2024 - --> $DIR/lint-if-let-rescope.rs:65:55 - | -LL | if let () = { if let Some(_value) = Droppy.get() {} } { - | ^ -help: a `match` with a single arm can preserve the drop order up to Edition 2021 - | -LL | if let () = { match Droppy.get() { Some(_value) => {} _ => {}} } { - | ~~~~~ +++++++++++++++++ ++++++++ - -error: `if let` assigns a shorter lifetime since Edition 2024 - --> $DIR/lint-if-let-rescope.rs:73:12 + --> $DIR/lint-if-let-rescope.rs:72:12 | LL | if (if let Some(_value) = droppy().get() { true } else { false }) { | ^^^^^^^^^^^^^^^^^^^--------^^^^^^ @@ -142,7 +122,7 @@ LL | if (if let Some(_value) = droppy().get() { true } else { false }) { = warning: this changes meaning in Rust 2024 = note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085> help: the value is now dropped here in Edition 2024 - --> $DIR/lint-if-let-rescope.rs:73:53 + --> $DIR/lint-if-let-rescope.rs:72:53 | LL | if (if let Some(_value) = droppy().get() { true } else { false }) { | ^ @@ -152,7 +132,7 @@ LL | if (match droppy().get() { Some(_value) => { true } _ => { false }}) { | ~~~~~ +++++++++++++++++ ~~~~ + error: `if let` assigns a shorter lifetime since Edition 2024 - --> $DIR/lint-if-let-rescope.rs:79:21 + --> $DIR/lint-if-let-rescope.rs:78:21 | LL | } else if (((if let Some(_value) = droppy().get() { true } else { false }))) { | ^^^^^^^^^^^^^^^^^^^--------^^^^^^ @@ -162,7 +142,7 @@ LL | } else if (((if let Some(_value) = droppy().get() { true } else { false = warning: this changes meaning in Rust 2024 = note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085> help: the value is now dropped here in Edition 2024 - --> $DIR/lint-if-let-rescope.rs:79:62 + --> $DIR/lint-if-let-rescope.rs:78:62 | LL | } else if (((if let Some(_value) = droppy().get() { true } else { false }))) { | ^ @@ -172,7 +152,7 @@ LL | } else if (((match droppy().get() { Some(_value) => { true } _ => { fal | ~~~~~ +++++++++++++++++ ~~~~ + error: `if let` assigns a shorter lifetime since Edition 2024 - --> $DIR/lint-if-let-rescope.rs:91:15 + --> $DIR/lint-if-let-rescope.rs:90:15 | LL | while (if let Some(_value) = droppy().get() { false } else { true }) { | ^^^^^^^^^^^^^^^^^^^--------^^^^^^ @@ -182,7 +162,7 @@ LL | while (if let Some(_value) = droppy().get() { false } else { true }) { = warning: this changes meaning in Rust 2024 = note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085> help: the value is now dropped here in Edition 2024 - --> $DIR/lint-if-let-rescope.rs:91:57 + --> $DIR/lint-if-let-rescope.rs:90:57 | LL | while (if let Some(_value) = droppy().get() { false } else { true }) { | ^ @@ -191,5 +171,5 @@ help: a `match` with a single arm can preserve the drop order up to Edition 2021 LL | while (match droppy().get() { Some(_value) => { false } _ => { true }}) { | ~~~~~ +++++++++++++++++ ~~~~ + -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors diff --git a/tests/ui/enum-discriminant/issue-41394.stderr b/tests/ui/enum-discriminant/issue-41394.stderr index e81562df04f..9bf4fc79b1b 100644 --- a/tests/ui/enum-discriminant/issue-41394.stderr +++ b/tests/ui/enum-discriminant/issue-41394.stderr @@ -6,6 +6,12 @@ LL | A = "" + 1 | | | &str +note: erroneous constant encountered + --> $DIR/issue-41394.rs:7:9 + | +LL | A = Foo::A as isize + | ^^^^^^^^^^^^^^^ + error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/error-codes/E0622.rs b/tests/ui/error-codes/E0622.rs index ae7378a707e..08c6d171296 100644 --- a/tests/ui/error-codes/E0622.rs +++ b/tests/ui/error-codes/E0622.rs @@ -1,6 +1,6 @@ #![feature(intrinsics)] extern "rust-intrinsic" { - pub static breakpoint : unsafe extern "rust-intrinsic" fn(); + pub static atomic_singlethreadfence_seqcst : unsafe extern "rust-intrinsic" fn(); //~^ ERROR intrinsic must be a function [E0622] } -fn main() { unsafe { breakpoint(); } } +fn main() { unsafe { atomic_singlethreadfence_seqcst(); } } diff --git a/tests/ui/error-codes/E0622.stderr b/tests/ui/error-codes/E0622.stderr index c59776b211f..739ec984fc6 100644 --- a/tests/ui/error-codes/E0622.stderr +++ b/tests/ui/error-codes/E0622.stderr @@ -1,8 +1,8 @@ error[E0622]: intrinsic must be a function --> $DIR/E0622.rs:3:5 | -LL | pub static breakpoint : unsafe extern "rust-intrinsic" fn(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a function +LL | pub static atomic_singlethreadfence_seqcst : unsafe extern "rust-intrinsic" fn(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a function error: aborting due to 1 previous error diff --git a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr index 4a1e50b4111..46769cdea8a 100644 --- a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr +++ b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr @@ -25,12 +25,6 @@ note: inside `ID_ED` LL | const ID_ED: u32 = rec_id(ORIGINAL); | ^^^^^^^^^^^^^^^^ -note: erroneous constant encountered - --> $DIR/ctfe-id-unlimited.rs:31:40 - | -LL | const ASSERT: () = assert!(ORIGINAL == ID_ED); - | ^^^^^ - error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/extern/extern-compare-with-return-type.rs b/tests/ui/extern/extern-compare-with-return-type.rs index 316e8b2fc73..7d1027d5e77 100644 --- a/tests/ui/extern/extern-compare-with-return-type.rs +++ b/tests/ui/extern/extern-compare-with-return-type.rs @@ -2,6 +2,7 @@ // Tests that we can compare various kinds of extern fn signatures. #![allow(non_camel_case_types)] +#![allow(unpredictable_function_pointer_comparisons)] // `dbg!()` differentiates these functions to ensure they won't be merged. extern "C" fn voidret1() { dbg!() } diff --git a/tests/ui/extern/extern-take-value.rs b/tests/ui/extern/extern-take-value.rs index 56ed3328614..f3df82b2610 100644 --- a/tests/ui/extern/extern-take-value.rs +++ b/tests/ui/extern/extern-take-value.rs @@ -1,6 +1,8 @@ //@ run-pass //@ aux-build:extern-take-value.rs +#![allow(unpredictable_function_pointer_comparisons)] + extern crate extern_take_value; pub fn main() { diff --git a/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs b/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs new file mode 100644 index 00000000000..db5d7aa06d2 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs @@ -0,0 +1,7 @@ +//@ edition: 2021 + +fn test(_: impl async Fn()) {} +//~^ ERROR `async` trait bounds are unstable +//~| ERROR use of unstable library feature `async_closure` + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr b/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr new file mode 100644 index 00000000000..abc7e37c45f --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr @@ -0,0 +1,24 @@ +error[E0658]: `async` trait bounds are unstable + --> $DIR/feature-gate-async-trait-bounds.rs:3:17 + | +LL | fn test(_: impl async Fn()) {} + | ^^^^^ + | + = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information + = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: use the desugared name of the async trait, such as `AsyncFn` + +error[E0658]: use of unstable library feature `async_closure` + --> $DIR/feature-gate-async-trait-bounds.rs:3:23 + | +LL | fn test(_: impl async Fn()) {} + | ^^^^ + | + = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information + = help: add `#![feature(async_closure)]` 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/feature-gates/feature-gate-generic_associated_types_extended.rs b/tests/ui/feature-gates/feature-gate-generic_associated_types_extended.rs deleted file mode 100644 index 7842d44ac4f..00000000000 --- a/tests/ui/feature-gates/feature-gate-generic_associated_types_extended.rs +++ /dev/null @@ -1,4 +0,0 @@ -// This feature doesn't *currently* fire on any specific code; it's just a -// behavior change. Future changes might. -#[rustc_error] //~ the -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr b/tests/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr deleted file mode 100644 index a5ab1b0d631..00000000000 --- a/tests/ui/feature-gates/feature-gate-generic_associated_types_extended.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable - --> $DIR/feature-gate-generic_associated_types_extended.rs:3:1 - | -LL | #[rustc_error] - | ^^^^^^^^^^^^^^ - | - = help: add `#![feature(rustc_attrs)]` 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 - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/function-pointer/function-pointer-comparison-issue-54685.rs b/tests/ui/function-pointer/function-pointer-comparison-issue-54685.rs index 2e1c863e0f4..3ec958f2ebf 100644 --- a/tests/ui/function-pointer/function-pointer-comparison-issue-54685.rs +++ b/tests/ui/function-pointer/function-pointer-comparison-issue-54685.rs @@ -1,6 +1,8 @@ //@ compile-flags: -C opt-level=3 //@ run-pass +#![allow(unpredictable_function_pointer_comparisons)] + fn foo(_i: i32) -> i32 { 1 } diff --git a/tests/ui/generic-associated-types/extended/lending_iterator.rs b/tests/ui/generic-associated-types/extended/lending_iterator.rs index 7cd32413001..8d815f6dc78 100644 --- a/tests/ui/generic-associated-types/extended/lending_iterator.rs +++ b/tests/ui/generic-associated-types/extended/lending_iterator.rs @@ -1,9 +1,4 @@ -//@ revisions: base extended -//@[base] check-fail -//@[extended] check-pass - -#![cfg_attr(extended, feature(generic_associated_types_extended))] -#![cfg_attr(extended, allow(incomplete_features))] +//@ known-bug: #133805 pub trait FromLendingIterator<A>: Sized { fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self; @@ -11,7 +6,6 @@ pub trait FromLendingIterator<A>: Sized { impl<A> FromLendingIterator<A> for Vec<A> { fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self { - //[base]~^ impl has stricter let mut v = vec![]; while let Some(item) = iter.next() { v.push(item); @@ -32,7 +26,6 @@ pub trait LendingIterator { Self: for<'q> LendingIterator<Item<'q> = A>, { <B as FromLendingIterator<A>>::from_iter(self) - //[base]~^ ERROR: does not live long enough } } diff --git a/tests/ui/generic-associated-types/extended/lending_iterator.base.stderr b/tests/ui/generic-associated-types/extended/lending_iterator.stderr index b19280b45c2..84f5ed07bda 100644 --- a/tests/ui/generic-associated-types/extended/lending_iterator.base.stderr +++ b/tests/ui/generic-associated-types/extended/lending_iterator.stderr @@ -1,5 +1,5 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/lending_iterator.rs:13:45 + --> $DIR/lending_iterator.rs:8:45 | LL | fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self; | ------------------------------------------------------------------------ definition of `from_iter` from trait @@ -8,7 +8,7 @@ LL | fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> | ^^^^^^^^^^^^ impl has extra requirement `I: 'x` error: `Self` does not live long enough - --> $DIR/lending_iterator.rs:34:9 + --> $DIR/lending_iterator.rs:28:9 | LL | <B as FromLendingIterator<A>>::from_iter(self) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/generic-associated-types/extended/lending_iterator_2.rs b/tests/ui/generic-associated-types/extended/lending_iterator_2.rs index f4b0dae0a91..0545d4d12bb 100644 --- a/tests/ui/generic-associated-types/extended/lending_iterator_2.rs +++ b/tests/ui/generic-associated-types/extended/lending_iterator_2.rs @@ -1,9 +1,4 @@ -//@ revisions: base extended -//@[base] check-fail -//@[extended] check-pass - -#![cfg_attr(extended, feature(generic_associated_types_extended))] -#![cfg_attr(extended, allow(incomplete_features))] +//@ known-bug: #133805 pub trait FromLendingIterator<A>: Sized { fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self; @@ -11,7 +6,6 @@ pub trait FromLendingIterator<A>: Sized { impl<A> FromLendingIterator<A> for Vec<A> { fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self { - //[base]~^ impl has stricter let mut v = vec![]; while let Some(item) = iter.next() { v.push(item); diff --git a/tests/ui/generic-associated-types/extended/lending_iterator_2.base.stderr b/tests/ui/generic-associated-types/extended/lending_iterator_2.stderr index 717d867057e..47c32a28aea 100644 --- a/tests/ui/generic-associated-types/extended/lending_iterator_2.base.stderr +++ b/tests/ui/generic-associated-types/extended/lending_iterator_2.stderr @@ -1,5 +1,5 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/lending_iterator_2.rs:13:45 + --> $DIR/lending_iterator_2.rs:8:45 | LL | fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self; | ------------------------------------------------------------------------ definition of `from_iter` from trait diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.rs b/tests/ui/generic-associated-types/gat-in-trait-path.rs index 7eb0aabb333..cd759a73cf2 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path.rs +++ b/tests/ui/generic-associated-types/gat-in-trait-path.rs @@ -1,10 +1,6 @@ -//@ revisions: base extended -//@[base] check-fail -//@[extended] check-pass +//@ check-fail #![feature(associated_type_defaults)] -#![cfg_attr(extended, feature(generic_associated_types_extended))] -#![cfg_attr(extended, allow(incomplete_features))] trait Foo { type A<'a> where Self: 'a; @@ -24,12 +20,12 @@ impl<T> Foo for Fooer<T> { } fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {} -//[base]~^ the trait `Foo` cannot be made into an object +//~^ the trait `Foo` cannot be made into an object fn main() { let foo = Fooer(5); f(Box::new(foo)); - //[base]~^ the trait `Foo` cannot be made into an object - //[base]~| the trait `Foo` cannot be made into an object + //~^ the trait `Foo` cannot be made into an object + //~| the trait `Foo` cannot be made into an object } diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.stderr b/tests/ui/generic-associated-types/gat-in-trait-path.stderr new file mode 100644 index 00000000000..b2176fa6de3 --- /dev/null +++ b/tests/ui/generic-associated-types/gat-in-trait-path.stderr @@ -0,0 +1,58 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/gat-in-trait-path.rs:22:17 + | +LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/gat-in-trait-path.rs:6:10 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | type A<'a> where Self: 'a; + | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead: + Fooy + Fooer<T> + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/gat-in-trait-path.rs:28:5 + | +LL | f(Box::new(foo)); + | ^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/gat-in-trait-path.rs:6:10 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | type A<'a> where Self: 'a; + | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead: + Fooy + Fooer<T> + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/gat-in-trait-path.rs:28:5 + | +LL | f(Box::new(foo)); + | ^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/gat-in-trait-path.rs:6:10 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | type A<'a> where Self: 'a; + | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead: + Fooy + Fooer<T> + = note: required for the cast from `Box<Fooer<{integer}>>` to `Box<(dyn Foo<A<'a> = &'a ()> + 'static)>` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/issue-67510-pass.rs b/tests/ui/generic-associated-types/issue-67510-pass.rs index 1596f401bbc..a48d9c37cd4 100644 --- a/tests/ui/generic-associated-types/issue-67510-pass.rs +++ b/tests/ui/generic-associated-types/issue-67510-pass.rs @@ -1,15 +1,10 @@ -//@ revisions: base extended -//@[base] check-fail -//@[extended] check-pass - -#![cfg_attr(extended, feature(generic_associated_types_extended))] -#![cfg_attr(extended, allow(incomplete_features))] +//@ check-fail trait X { type Y<'a>; } fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {} -//[base]~^ ERROR the trait `X` cannot be made into an object +//~^ ERROR the trait `X` cannot be made into an object fn main() {} diff --git a/tests/ui/generic-associated-types/issue-67510-pass.stderr b/tests/ui/generic-associated-types/issue-67510-pass.stderr new file mode 100644 index 00000000000..5560cb0f64d --- /dev/null +++ b/tests/ui/generic-associated-types/issue-67510-pass.stderr @@ -0,0 +1,18 @@ +error[E0038]: the trait `X` cannot be made into an object + --> $DIR/issue-67510-pass.rs:7:23 + | +LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {} + | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-67510-pass.rs:4:10 + | +LL | trait X { + | - this trait cannot be made into an object... +LL | type Y<'a>; + | ^ ...because it contains the generic associated type `Y` + = help: consider moving `Y` to another trait + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/issue-76535.rs b/tests/ui/generic-associated-types/issue-76535.rs index cf26b65c85f..9e18c82c7f1 100644 --- a/tests/ui/generic-associated-types/issue-76535.rs +++ b/tests/ui/generic-associated-types/issue-76535.rs @@ -1,8 +1,3 @@ -//@ revisions: base extended - -#![cfg_attr(extended, feature(generic_associated_types_extended))] -#![cfg_attr(extended, allow(incomplete_features))] - pub trait SubTrait {} pub trait SuperTrait { @@ -38,6 +33,6 @@ impl SuperTrait for SuperStruct { fn main() { let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0)); //~^ ERROR missing generics for associated type - //[base]~^^ ERROR the trait - //[base]~| ERROR the trait + //~^^ ERROR the trait + //~| ERROR the trait } diff --git a/tests/ui/generic-associated-types/issue-76535.stderr b/tests/ui/generic-associated-types/issue-76535.stderr new file mode 100644 index 00000000000..613ded6f1ef --- /dev/null +++ b/tests/ui/generic-associated-types/issue-76535.stderr @@ -0,0 +1,55 @@ +error[E0107]: missing generics for associated type `SuperTrait::SubType` + --> $DIR/issue-76535.rs:34:33 + | +LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0)); + | ^^^^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-76535.rs:4:10 + | +LL | type SubType<'a>: SubTrait where Self: 'a; + | ^^^^^^^ -- +help: add missing lifetime argument + | +LL | let sub: Box<dyn SuperTrait<SubType<'a> = SubStruct>> = Box::new(SuperStruct::new(0)); + | ++++ + +error[E0038]: the trait `SuperTrait` cannot be made into an object + --> $DIR/issue-76535.rs:34:14 + | +LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-76535.rs:4:10 + | +LL | pub trait SuperTrait { + | ---------- this trait cannot be made into an object... +LL | type SubType<'a>: SubTrait where Self: 'a; + | ^^^^^^^ ...because it contains the generic associated type `SubType` + = help: consider moving `SubType` to another trait + = help: only type `SuperStruct` is seen to implement the trait in this crate, consider using it directly instead + = note: `SuperTrait` can be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type + +error[E0038]: the trait `SuperTrait` cannot be made into an object + --> $DIR/issue-76535.rs:34:57 + | +LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-76535.rs:4:10 + | +LL | pub trait SuperTrait { + | ---------- this trait cannot be made into an object... +LL | type SubType<'a>: SubTrait where Self: 'a; + | ^^^^^^^ ...because it contains the generic associated type `SubType` + = help: consider moving `SubType` to another trait + = help: only type `SuperStruct` is seen to implement the trait in this crate, consider using it directly instead + = note: `SuperTrait` can be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type + = note: required for the cast from `Box<SuperStruct>` to `Box<dyn SuperTrait<SubType<'_> = SubStruct<'_>>>` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/issue-78671.rs b/tests/ui/generic-associated-types/issue-78671.rs index ce4c040644a..0871def1731 100644 --- a/tests/ui/generic-associated-types/issue-78671.rs +++ b/tests/ui/generic-associated-types/issue-78671.rs @@ -1,15 +1,10 @@ -//@ revisions: base extended - -#![cfg_attr(extended, feature(generic_associated_types_extended))] -#![cfg_attr(extended, allow(incomplete_features))] - trait CollectionFamily { type Member<T>; } fn floatify() { Box::new(Family) as &dyn CollectionFamily<Member=usize> //~^ ERROR: missing generics for associated type - //[base]~^^ ERROR: the trait `CollectionFamily` cannot be made into an object + //~| ERROR: the trait `CollectionFamily` cannot be made into an object } struct Family; diff --git a/tests/ui/generic-associated-types/issue-78671.stderr b/tests/ui/generic-associated-types/issue-78671.stderr new file mode 100644 index 00000000000..fbd76c73895 --- /dev/null +++ b/tests/ui/generic-associated-types/issue-78671.stderr @@ -0,0 +1,35 @@ +error[E0107]: missing generics for associated type `CollectionFamily::Member` + --> $DIR/issue-78671.rs:5:47 + | +LL | Box::new(Family) as &dyn CollectionFamily<Member=usize> + | ^^^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-78671.rs:2:10 + | +LL | type Member<T>; + | ^^^^^^ - +help: add missing generic argument + | +LL | Box::new(Family) as &dyn CollectionFamily<Member<T>=usize> + | +++ + +error[E0038]: the trait `CollectionFamily` cannot be made into an object + --> $DIR/issue-78671.rs:5:25 + | +LL | Box::new(Family) as &dyn CollectionFamily<Member=usize> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-78671.rs:2:10 + | +LL | trait CollectionFamily { + | ---------------- this trait cannot be made into an object... +LL | type Member<T>; + | ^^^^^^ ...because it contains the generic associated type `Member` + = help: consider moving `Member` to another trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/issue-79422.rs b/tests/ui/generic-associated-types/issue-79422.rs index bf61dcaee3a..fba7a86990e 100644 --- a/tests/ui/generic-associated-types/issue-79422.rs +++ b/tests/ui/generic-associated-types/issue-79422.rs @@ -1,8 +1,3 @@ -//@ revisions: base extended - -#![cfg_attr(extended, feature(generic_associated_types_extended))] -#![cfg_attr(extended, allow(incomplete_features))] - trait RefCont<'a, T> { fn t(&'a self) -> &'a T; } @@ -42,9 +37,8 @@ impl<K, V: Default> MapLike<K, V> for Source { fn main() { let m = Box::new(std::collections::BTreeMap::<u8, u8>::new()) - //[base]~^ ERROR the trait - //[extended]~^^ type mismatch + //~^ ERROR the trait as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>; //~^ ERROR missing generics for associated type - //[base]~^^ ERROR the trait + //~| ERROR the trait } diff --git a/tests/ui/generic-associated-types/issue-79422.stderr b/tests/ui/generic-associated-types/issue-79422.stderr new file mode 100644 index 00000000000..26567e5e927 --- /dev/null +++ b/tests/ui/generic-associated-types/issue-79422.stderr @@ -0,0 +1,57 @@ +error[E0107]: missing generics for associated type `MapLike::VRefCont` + --> $DIR/issue-79422.rs:41:36 + | +LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>; + | ^^^^^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-79422.rs:18:10 + | +LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; + | ^^^^^^^^ -- +help: add missing lifetime argument + | +LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>; + | ++++ + +error[E0038]: the trait `MapLike` cannot be made into an object + --> $DIR/issue-79422.rs:41:12 + | +LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-79422.rs:18:10 + | +LL | trait MapLike<K, V> { + | ------- this trait cannot be made into an object... +LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; + | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` + = help: consider moving `VRefCont` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `MapLike` for this new enum and using it instead: + std::collections::BTreeMap<K, V> + Source + +error[E0038]: the trait `MapLike` cannot be made into an object + --> $DIR/issue-79422.rs:39:13 + | +LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/issue-79422.rs:18:10 + | +LL | trait MapLike<K, V> { + | ------- this trait cannot be made into an object... +LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; + | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` + = help: consider moving `VRefCont` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `MapLike` for this new enum and using it instead: + std::collections::BTreeMap<K, V> + Source + = note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont<'_> = (dyn RefCont<'_, u8> + 'static)>>` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/trait-objects.rs b/tests/ui/generic-associated-types/trait-objects.rs index 743a3df0acc..bad9289ee5e 100644 --- a/tests/ui/generic-associated-types/trait-objects.rs +++ b/tests/ui/generic-associated-types/trait-objects.rs @@ -1,8 +1,3 @@ -//@ revisions: base extended - -#![cfg_attr(extended, feature(generic_associated_types_extended))] -#![cfg_attr(extended, allow(incomplete_features))] - trait StreamingIterator { type Item<'a> where Self: 'a; fn size_hint(&self) -> (usize, Option<usize>); @@ -11,11 +6,10 @@ trait StreamingIterator { } fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize { - //[base]~^ the trait `StreamingIterator` cannot be made into an object + //~^ the trait `StreamingIterator` cannot be made into an object x.size_hint().0 - //[extended]~^ borrowed data escapes - //[base]~^^ the trait `StreamingIterator` cannot be made into an object - //[base]~| the trait `StreamingIterator` cannot be made into an object + //~^ the trait `StreamingIterator` cannot be made into an object + //~| the trait `StreamingIterator` cannot be made into an object } fn main() {} diff --git a/tests/ui/generic-associated-types/trait-objects.stderr b/tests/ui/generic-associated-types/trait-objects.stderr new file mode 100644 index 00000000000..3e74776f999 --- /dev/null +++ b/tests/ui/generic-associated-types/trait-objects.stderr @@ -0,0 +1,48 @@ +error[E0038]: the trait `StreamingIterator` cannot be made into an object + --> $DIR/trait-objects.rs:8:21 + | +LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/trait-objects.rs:2:10 + | +LL | trait StreamingIterator { + | ----------------- this trait cannot be made into an object... +LL | type Item<'a> where Self: 'a; + | ^^^^ ...because it contains the generic associated type `Item` + = help: consider moving `Item` to another trait + +error[E0038]: the trait `StreamingIterator` cannot be made into an object + --> $DIR/trait-objects.rs:10:7 + | +LL | x.size_hint().0 + | ^^^^^^^^^ `StreamingIterator` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/trait-objects.rs:2:10 + | +LL | trait StreamingIterator { + | ----------------- this trait cannot be made into an object... +LL | type Item<'a> where Self: 'a; + | ^^^^ ...because it contains the generic associated type `Item` + = help: consider moving `Item` to another trait + +error[E0038]: the trait `StreamingIterator` cannot be made into an object + --> $DIR/trait-objects.rs:10:5 + | +LL | x.size_hint().0 + | ^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/trait-objects.rs:2:10 + | +LL | trait StreamingIterator { + | ----------------- this trait cannot be made into an object... +LL | type Item<'a> where Self: 'a; + | ^^^^ ...because it contains the generic associated type `Item` + = help: consider moving `Item` to another trait + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/higher-ranked/structually-relate-aliases.rs b/tests/ui/higher-ranked/structually-relate-aliases.rs index 73c2cd23d86..1ed3767643a 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.rs +++ b/tests/ui/higher-ranked/structually-relate-aliases.rs @@ -12,6 +12,5 @@ impl<T> Overlap<T> for T {} impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {} //~^ ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied -//~| ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied fn main() {} diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr index e9d91e45e21..cf3e4cc85b9 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.stderr +++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr @@ -10,17 +10,6 @@ help: consider restricting type parameter `T` LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {} | ++++++++++++++++++++ -error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied - --> $DIR/structually-relate-aliases.rs:13:17 - | -LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T` - | -help: consider restricting type parameter `T` - | -LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {} - | ++++++++++++++++++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr index 72646b7bc76..9e04e90a98a 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr @@ -1,5 +1,5 @@ error[E0284]: type annotations needed: cannot satisfy `Foo == _` - --> $DIR/norm-before-method-resolution-opaque-type.rs:16:19 + --> $DIR/norm-before-method-resolution-opaque-type.rs:15:19 | LL | fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X | ^ cannot satisfy `Foo == _` diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr index dbd0d5dc733..479f5984355 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr @@ -1,5 +1,5 @@ error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/norm-before-method-resolution-opaque-type.rs:16:4 + --> $DIR/norm-before-method-resolution-opaque-type.rs:15:4 | LL | fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X | ^^^^^^^^^^^ @@ -11,16 +11,8 @@ note: this opaque type is in the signature LL | type Foo = impl Sized; | ^^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/norm-before-method-resolution-opaque-type.rs:13:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module - error[E0507]: cannot move out of `*x` which is behind a shared reference - --> $DIR/norm-before-method-resolution-opaque-type.rs:23:13 + --> $DIR/norm-before-method-resolution-opaque-type.rs:22:13 | LL | let x = *x; | ^^ move occurs because `*x` has type `<X as Trait<'_>>::Out<Foo>`, which does not implement the `Copy` trait @@ -31,6 +23,6 @@ LL - let x = *x; LL + let x = x; | -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs index cf752f814c9..ffbfc622bb0 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs @@ -11,7 +11,6 @@ impl<'a, T> Trait<'a> for T { } type Foo = impl Sized; -//[old]~^ ERROR: unconstrained opaque type fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X //[old]~^ ERROR: item does not constrain diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr index 79581066a3a..1cfc2a6d944 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr @@ -8,10 +8,10 @@ LL | #![feature(lazy_type_alias)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `usize: Foo` is not satisfied - --> $DIR/alias-bounds-when-not-wf.rs:16:13 + --> $DIR/alias-bounds-when-not-wf.rs:16:15 | LL | fn hello(_: W<A<usize>>) {} - | ^^^^^^^^^^^ the trait `Foo` is not implemented for `usize` + | ^^^^^^^^ the trait `Foo` is not implemented for `usize` | help: this trait has no implementations, consider adding one --> $DIR/alias-bounds-when-not-wf.rs:6:1 diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs index 5a6959ad7e6..ff1d273ae48 100644 --- a/tests/ui/impl-trait/issues/issue-86800.rs +++ b/tests/ui/impl-trait/issues/issue-86800.rs @@ -23,7 +23,6 @@ struct Context { type TransactionResult<O> = Result<O, ()>; type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>; -//~^ ERROR unconstrained opaque type fn execute_transaction_fut<'f, F, O>( //~^ ERROR: item does not constrain diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr index 095f648143c..fd9b8e7ac99 100644 --- a/tests/ui/impl-trait/issues/issue-86800.stderr +++ b/tests/ui/impl-trait/issues/issue-86800.stderr @@ -1,5 +1,5 @@ error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature - --> $DIR/issue-86800.rs:28:4 + --> $DIR/issue-86800.rs:27:4 | LL | fn execute_transaction_fut<'f, F, O>( | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResu | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature - --> $DIR/issue-86800.rs:40:14 + --> $DIR/issue-86800.rs:39:14 | LL | async fn do_transaction<O>( | ^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResu | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature - --> $DIR/issue-86800.rs:44:5 + --> $DIR/issue-86800.rs:43:5 | LL | / { LL | | @@ -43,16 +43,8 @@ note: this opaque type is in the signature LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/issue-86800.rs:25:34 - | -LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `TransactionFuture` must be used in combination with a concrete type within the same module - error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/issue-86800.rs:35:5 + --> $DIR/issue-86800.rs:34:5 | LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>; | --- this generic parameter must be used with a generic lifetime parameter @@ -61,7 +53,7 @@ LL | f | ^ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/issue-86800.rs:44:5 + --> $DIR/issue-86800.rs:43:5 | LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>; | --- this generic parameter must be used with a generic lifetime parameter @@ -75,6 +67,6 @@ LL | | f(&mut transaction).await LL | | } | |_____^ -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs index 46121308fa0..cac5ae177d2 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs @@ -7,7 +7,7 @@ fn polarity() -> impl Sized + ?use<> {} fn asyncness() -> impl Sized + async use<> {} //~^ ERROR expected identifier, found keyword `use` //~| ERROR cannot find trait `r#use` in this scope -//~| ERROR async closures are unstable +//~| ERROR `async` trait bounds are unstable fn constness() -> impl Sized + const use<> {} //~^ ERROR expected identifier, found keyword `use` diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr index 16e7470debf..d4b5b47b41b 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr @@ -46,16 +46,16 @@ error[E0405]: cannot find trait `r#use` in this scope LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ not found in this scope -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/bound-modifiers.rs:7:32 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^^^ | = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: to use an async block, remove the `||`: `async {` + = help: use the desugared name of the async trait, such as `AsyncFn` error[E0658]: const trait impls are experimental --> $DIR/bound-modifiers.rs:12:32 diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs index dc9424c3ca7..3f41c5984b4 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs @@ -2,7 +2,6 @@ mod a { type Foo = impl PartialEq<(Foo, i32)>; - //~^ ERROR: unconstrained opaque type struct Bar; diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr index 6485aa20710..b127bf41800 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr @@ -1,5 +1,5 @@ error[E0053]: method `eq` has an incompatible type for trait - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:30 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:9:30 | LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the found opaque type @@ -15,7 +15,7 @@ LL | fn eq(&self, _other: &(a::Bar, i32)) -> bool { | ~~~~~~~~~~~~~~ error: item does not constrain `a::Foo::{opaque#0}`, but has it in its signature - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:9:12 | LL | fn eq(&self, _other: &(Foo, i32)) -> bool { | ^^ @@ -27,16 +27,8 @@ note: this opaque type is in the signature LL | type Foo = impl PartialEq<(Foo, i32)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16 - | -LL | type Foo = impl PartialEq<(Foo, i32)>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module - error[E0053]: method `eq` has an incompatible type for trait - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:30 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:30 | LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the expected opaque type @@ -47,7 +39,7 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool { = note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _` found signature `fn(&b::Bar, &(b::Bar, _)) -> _` note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:12 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:12 | LL | fn eq(&self, _other: &(Bar, i32)) -> bool { | ^^ @@ -57,13 +49,13 @@ LL | fn eq(&self, _other: &(b::Foo, i32)) -> bool { | ~~~~~~~~~~~~~~ error: unconstrained opaque type - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16 | LL | type Foo = impl PartialEq<(Foo, i32)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `Foo` must be used in combination with a concrete type within the same module -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr index b70676ece0e..7d02a0606fc 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr @@ -11,14 +11,6 @@ note: this opaque type is in the signature LL | type A = impl Foo; | ^^^^^^^^ -error: unconstrained opaque type - --> $DIR/two_tait_defining_each_other2.rs:6:10 - | -LL | type A = impl Foo; - | ^^^^^^^^ - | - = note: `A` must be used in combination with a concrete type within the same module - error: opaque type's hidden type cannot be another opaque type from the same scope --> $DIR/two_tait_defining_each_other2.rs:14:5 | @@ -36,5 +28,5 @@ note: opaque type being used as hidden type LL | type A = impl Foo; | ^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.rs b/tests/ui/impl-trait/two_tait_defining_each_other2.rs index 3311c556568..1681b019418 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs @@ -3,7 +3,7 @@ //@[next] compile-flags: -Znext-solver #![feature(type_alias_impl_trait)] -type A = impl Foo; //[current]~ ERROR unconstrained opaque type +type A = impl Foo; type B = impl Foo; trait Foo {} diff --git a/tests/ui/inline-const/const-match-pat-generic.rs b/tests/ui/inline-const/const-match-pat-generic.rs index 9d76fc2ad65..889c015e9ac 100644 --- a/tests/ui/inline-const/const-match-pat-generic.rs +++ b/tests/ui/inline-const/const-match-pat-generic.rs @@ -5,7 +5,7 @@ fn foo<const V: usize>() { match 0 { const { V } => {}, - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters _ => {}, } } @@ -17,7 +17,7 @@ const fn f(x: usize) -> usize { fn bar<const V: usize>() { match 0 { const { f(V) } => {}, - //~^ ERROR constant pattern depends on a generic parameter + //~^ ERROR constant pattern cannot depend on generic parameters _ => {}, } } diff --git a/tests/ui/inline-const/const-match-pat-generic.stderr b/tests/ui/inline-const/const-match-pat-generic.stderr index 26f72b34eca..7d9e1d9e407 100644 --- a/tests/ui/inline-const/const-match-pat-generic.stderr +++ b/tests/ui/inline-const/const-match-pat-generic.stderr @@ -1,14 +1,14 @@ -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/const-match-pat-generic.rs:7:9 | LL | const { V } => {}, - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ `const` depends on a generic parameter -error[E0158]: constant pattern depends on a generic parameter +error[E0158]: constant pattern cannot depend on generic parameters --> $DIR/const-match-pat-generic.rs:19:9 | LL | const { f(V) } => {}, - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ `const` depends on a generic parameter error: aborting due to 2 previous errors diff --git a/tests/ui/inline-const/pat-match-fndef.stderr b/tests/ui/inline-const/pat-match-fndef.stderr index b189ec51ade..220437a0491 100644 --- a/tests/ui/inline-const/pat-match-fndef.stderr +++ b/tests/ui/inline-const/pat-match-fndef.stderr @@ -1,8 +1,8 @@ -error: `fn() {uwu}` cannot be used in patterns +error: fn item `fn() {uwu}` cannot be used in patterns --> $DIR/pat-match-fndef.rs:8:9 | LL | const { uwu } => {} - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ fn item can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-50582.rs b/tests/ui/issues/issue-50582.rs index 2d5c9358752..1358e0bde4c 100644 --- a/tests/ui/issues/issue-50582.rs +++ b/tests/ui/issues/issue-50582.rs @@ -1,5 +1,4 @@ fn main() { Vec::<[(); 1 + for x in 0..1 {}]>::new(); //~^ ERROR cannot add - //~| ERROR `for` is not allowed in a `const` } diff --git a/tests/ui/issues/issue-50582.stderr b/tests/ui/issues/issue-50582.stderr index af7a36f62fb..168f5894fb0 100644 --- a/tests/ui/issues/issue-50582.stderr +++ b/tests/ui/issues/issue-50582.stderr @@ -1,13 +1,3 @@ -error[E0658]: `for` is not allowed in a `const` - --> $DIR/issue-50582.rs:2:20 - | -LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0277]: cannot add `()` to `{integer}` --> $DIR/issue-50582.rs:2:18 | @@ -26,7 +16,6 @@ LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); `&f64` implements `Add` and 56 others -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0658. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-50585.rs b/tests/ui/issues/issue-50585.rs index a2f11c98d5a..ca2ece8d53b 100644 --- a/tests/ui/issues/issue-50585.rs +++ b/tests/ui/issues/issue-50585.rs @@ -1,5 +1,4 @@ fn main() { |y: Vec<[(); for x in 0..2 {}]>| {}; //~^ ERROR mismatched types - //~| ERROR `for` is not allowed in a `const` } diff --git a/tests/ui/issues/issue-50585.stderr b/tests/ui/issues/issue-50585.stderr index e7f13e63475..7e83ea35fbb 100644 --- a/tests/ui/issues/issue-50585.stderr +++ b/tests/ui/issues/issue-50585.stderr @@ -1,13 +1,3 @@ -error[E0658]: `for` is not allowed in a `const` - --> $DIR/issue-50585.rs:2:18 - | -LL | |y: Vec<[(); for x in 0..2 {}]>| {}; - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0308]: mismatched types --> $DIR/issue-50585.rs:2:18 | @@ -20,7 +10,6 @@ help: consider returning a value here LL | |y: Vec<[(); for x in 0..2 {} /* `usize` value */]>| {}; | +++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-54696.rs b/tests/ui/issues/issue-54696.rs index 75b1824f0b3..63ffbe42bcc 100644 --- a/tests/ui/issues/issue-54696.rs +++ b/tests/ui/issues/issue-54696.rs @@ -1,5 +1,7 @@ //@ run-pass +#![allow(unpredictable_function_pointer_comparisons)] + fn main() { // We shouldn't promote this let _ = &(main as fn() == main as fn()); diff --git a/tests/ui/layout/base-layout-is-sized-ice-123078.stderr b/tests/ui/layout/base-layout-is-sized-ice-123078.stderr index 455bd2cbf8b..ee7f5162552 100644 --- a/tests/ui/layout/base-layout-is-sized-ice-123078.stderr +++ b/tests/ui/layout/base-layout-is-sized-ice-123078.stderr @@ -25,6 +25,12 @@ LL | const C: S = unsafe { std::mem::transmute(()) }; = note: source type: `()` (0 bits) = note: target type: `S` (size can vary because of [u8]) +note: erroneous constant encountered + --> $DIR/base-layout-is-sized-ice-123078.rs:13:5 + | +LL | C; + | ^ + error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0512. diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr index 0a5f17be804..51c4837f458 100644 --- a/tests/ui/limits/issue-55878.stderr +++ b/tests/ui/limits/issue-55878.stderr @@ -11,23 +11,6 @@ note: inside `main` LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: erroneous constant encountered - --> $DIR/issue-55878.rs:7:26 - | -LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: erroneous constant encountered - --> $DIR/issue-55878.rs:7:26 - | -LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) - error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/lint/fn-ptr-comparisons-weird.rs b/tests/ui/lint/fn-ptr-comparisons-weird.rs new file mode 100644 index 00000000000..171fbfb8727 --- /dev/null +++ b/tests/ui/lint/fn-ptr-comparisons-weird.rs @@ -0,0 +1,15 @@ +//@ check-pass + +fn main() { + let f: fn() = main; + let g: fn() = main; + + let _ = f > g; + //~^ WARN function pointer comparisons + let _ = f >= g; + //~^ WARN function pointer comparisons + let _ = f <= g; + //~^ WARN function pointer comparisons + let _ = f < g; + //~^ WARN function pointer comparisons +} diff --git a/tests/ui/lint/fn-ptr-comparisons-weird.stderr b/tests/ui/lint/fn-ptr-comparisons-weird.stderr new file mode 100644 index 00000000000..f2371663922 --- /dev/null +++ b/tests/ui/lint/fn-ptr-comparisons-weird.stderr @@ -0,0 +1,43 @@ +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons-weird.rs:7:13 + | +LL | let _ = f > g; + | ^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> + = note: `#[warn(unpredictable_function_pointer_comparisons)]` on by default + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons-weird.rs:9:13 + | +LL | let _ = f >= g; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons-weird.rs:11:13 + | +LL | let _ = f <= g; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons-weird.rs:13:13 + | +LL | let _ = f < g; + | ^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> + +warning: 4 warnings emitted + diff --git a/tests/ui/lint/fn-ptr-comparisons.fixed b/tests/ui/lint/fn-ptr-comparisons.fixed new file mode 100644 index 00000000000..22f16177a04 --- /dev/null +++ b/tests/ui/lint/fn-ptr-comparisons.fixed @@ -0,0 +1,58 @@ +//@ check-pass +//@ run-rustfix + +extern "C" { + fn test(); +} + +fn a() {} + +extern "C" fn c() {} + +extern "C" fn args(_a: i32) -> i32 { 0 } + +#[derive(PartialEq, Eq)] +struct A { + f: fn(), +} + +fn main() { + let f: fn() = a; + let g: fn() = f; + + let a1 = A { f }; + let a2 = A { f }; + + let _ = std::ptr::fn_addr_eq(f, a as fn()); + //~^ WARN function pointer comparisons + let _ = !std::ptr::fn_addr_eq(f, a as fn()); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(f, g); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(f, f); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(g, g); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(g, g); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(g, g); + //~^ WARN function pointer comparisons + let _ = std::ptr::fn_addr_eq(a as fn(), g); + //~^ WARN function pointer comparisons + + let cfn: extern "C" fn() = c; + let _ = std::ptr::fn_addr_eq(cfn, c as extern "C" fn()); + //~^ WARN function pointer comparisons + + let argsfn: extern "C" fn(i32) -> i32 = args; + let _ = std::ptr::fn_addr_eq(argsfn, args as extern "C" fn(i32) -> i32); + //~^ WARN function pointer comparisons + + let t: unsafe extern "C" fn() = test; + let _ = std::ptr::fn_addr_eq(t, test as unsafe extern "C" fn()); + //~^ WARN function pointer comparisons + + let _ = a1 == a2; // should not warn + let _ = std::ptr::fn_addr_eq(a1.f, a2.f); + //~^ WARN function pointer comparisons +} diff --git a/tests/ui/lint/fn-ptr-comparisons.rs b/tests/ui/lint/fn-ptr-comparisons.rs new file mode 100644 index 00000000000..90a8ab5c926 --- /dev/null +++ b/tests/ui/lint/fn-ptr-comparisons.rs @@ -0,0 +1,58 @@ +//@ check-pass +//@ run-rustfix + +extern "C" { + fn test(); +} + +fn a() {} + +extern "C" fn c() {} + +extern "C" fn args(_a: i32) -> i32 { 0 } + +#[derive(PartialEq, Eq)] +struct A { + f: fn(), +} + +fn main() { + let f: fn() = a; + let g: fn() = f; + + let a1 = A { f }; + let a2 = A { f }; + + let _ = f == a; + //~^ WARN function pointer comparisons + let _ = f != a; + //~^ WARN function pointer comparisons + let _ = f == g; + //~^ WARN function pointer comparisons + let _ = f == f; + //~^ WARN function pointer comparisons + let _ = g == g; + //~^ WARN function pointer comparisons + let _ = g == g; + //~^ WARN function pointer comparisons + let _ = &g == &g; + //~^ WARN function pointer comparisons + let _ = a as fn() == g; + //~^ WARN function pointer comparisons + + let cfn: extern "C" fn() = c; + let _ = cfn == c; + //~^ WARN function pointer comparisons + + let argsfn: extern "C" fn(i32) -> i32 = args; + let _ = argsfn == args; + //~^ WARN function pointer comparisons + + let t: unsafe extern "C" fn() = test; + let _ = t == test; + //~^ WARN function pointer comparisons + + let _ = a1 == a2; // should not warn + let _ = a1.f == a2.f; + //~^ WARN function pointer comparisons +} diff --git a/tests/ui/lint/fn-ptr-comparisons.stderr b/tests/ui/lint/fn-ptr-comparisons.stderr new file mode 100644 index 00000000000..eaba23a461a --- /dev/null +++ b/tests/ui/lint/fn-ptr-comparisons.stderr @@ -0,0 +1,171 @@ +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:26:13 + | +LL | let _ = f == a; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> + = note: `#[warn(unpredictable_function_pointer_comparisons)]` on by default +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(f, a as fn()); + | +++++++++++++++++++++ ~ ++++++++ + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:28:13 + | +LL | let _ = f != a; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = !std::ptr::fn_addr_eq(f, a as fn()); + | ++++++++++++++++++++++ ~ ++++++++ + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:30:13 + | +LL | let _ = f == g; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(f, g); + | +++++++++++++++++++++ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:32:13 + | +LL | let _ = f == f; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(f, f); + | +++++++++++++++++++++ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:34:13 + | +LL | let _ = g == g; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(g, g); + | +++++++++++++++++++++ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:36:13 + | +LL | let _ = g == g; + | ^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(g, g); + | +++++++++++++++++++++ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:38:13 + | +LL | let _ = &g == &g; + | ^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(g, g); + | ~~~~~~~~~~~~~~~~~~~~~ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:40:13 + | +LL | let _ = a as fn() == g; + | ^^^^^^^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(a as fn(), g); + | +++++++++++++++++++++ ~ + + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:44:13 + | +LL | let _ = cfn == c; + | ^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(cfn, c as extern "C" fn()); + | +++++++++++++++++++++ ~ +++++++++++++++++++ + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:48:13 + | +LL | let _ = argsfn == args; + | ^^^^^^^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(argsfn, args as extern "C" fn(i32) -> i32); + | +++++++++++++++++++++ ~ +++++++++++++++++++++++++++++ + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:52:13 + | +LL | let _ = t == test; + | ^^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(t, test as unsafe extern "C" fn()); + | +++++++++++++++++++++ ~ ++++++++++++++++++++++++++ + +warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique + --> $DIR/fn-ptr-comparisons.rs:56:13 + | +LL | let _ = a1.f == a2.f; + | ^^^^^^^^^^^^ + | + = note: the address of the same function can vary between different codegen units + = note: furthermore, different functions could have the same address after being merged together + = note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html> +help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint + | +LL | let _ = std::ptr::fn_addr_eq(a1.f, a2.f); + | +++++++++++++++++++++ ~ + + +warning: 12 warnings emitted + diff --git a/tests/ui/lint/forbid-group-group-2.stderr b/tests/ui/lint/forbid-group-group-2.stderr index 80e2f566eb8..b075a521cc9 100644 --- a/tests/ui/lint/forbid-group-group-2.stderr +++ b/tests/ui/lint/forbid-group-group-2.stderr @@ -43,3 +43,57 @@ LL | #[allow(nonstandard_style)] error: aborting due to 3 previous errors +Future incompatibility report: Future breakage diagnostic: +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/forbid-group-group-2.rs:5:9 + | +LL | #![deny(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/forbid-group-group-2.rs:5:9 + | +LL | #![deny(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/forbid-group-group-2.rs:5:9 + | +LL | #![deny(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/lint/forbid-group-member.stderr b/tests/ui/lint/forbid-group-member.stderr index 8794591bd31..2e0147693f3 100644 --- a/tests/ui/lint/forbid-group-member.stderr +++ b/tests/ui/lint/forbid-group-member.stderr @@ -13,3 +13,17 @@ LL | #[allow(unused_variables)] warning: 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: allow(unused_variables) incompatible with previous forbid + --> $DIR/forbid-group-member.rs:8:9 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | +LL | #[allow(unused_variables)] + | ^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> + = note: `#[warn(forbidden_lint_groups)]` on by default + diff --git a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr index 407eaf1c60a..77c8d1eab58 100644 --- a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr +++ b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr @@ -17,3 +17,399 @@ LL | #![forbid(forbidden_lint_groups)] error: aborting due to 1 previous error +Future incompatibility report: Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/lint/outer-forbid.stderr b/tests/ui/lint/outer-forbid.stderr index a47877980a0..64a1077462a 100644 --- a/tests/ui/lint/outer-forbid.stderr +++ b/tests/ui/lint/outer-forbid.stderr @@ -39,3 +39,417 @@ LL | #[allow(nonstandard_style)] error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0453`. +Future incompatibility report: Future breakage diagnostic: +error: allow(unused_variables) incompatible with previous forbid + --> $DIR/outer-forbid.rs:20:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused_variables)] + | ^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/match/issue-70972-dyn-trait.stderr b/tests/ui/match/issue-70972-dyn-trait.stderr index b0af50f8599..cec9c8539f4 100644 --- a/tests/ui/match/issue-70972-dyn-trait.stderr +++ b/tests/ui/match/issue-70972-dyn-trait.stderr @@ -1,8 +1,11 @@ -error: `dyn Send` cannot be used in patterns +error: trait object `dyn Send` cannot be used in patterns --> $DIR/issue-70972-dyn-trait.rs:6:9 | +LL | const F: &'static dyn Send = &7u32; + | -------------------------- constant defined here +... LL | F => panic!(), - | ^ + | ^ trait object can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/match/issue-72896-non-partial-eq-const.rs b/tests/ui/match/issue-72896-non-partial-eq-const.rs index f15eae83896..e4fc1ac057d 100644 --- a/tests/ui/match/issue-72896-non-partial-eq-const.rs +++ b/tests/ui/match/issue-72896-non-partial-eq-const.rs @@ -16,7 +16,7 @@ const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 }; fn main() { match CONST_SET { - CONST_SET => { /* ok */ } //~ERROR: must implement `PartialEq` + CONST_SET => { /* ok */ } //~ ERROR constant of non-structural type `EnumSet<Enum8>` in a pattern _ => panic!("match fell through?"), } } diff --git a/tests/ui/match/issue-72896-non-partial-eq-const.stderr b/tests/ui/match/issue-72896-non-partial-eq-const.stderr index 4155586c160..1f82d3e822a 100644 --- a/tests/ui/match/issue-72896-non-partial-eq-const.stderr +++ b/tests/ui/match/issue-72896-non-partial-eq-const.stderr @@ -1,8 +1,16 @@ -error: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq` +error: constant of non-structural type `EnumSet<Enum8>` in a pattern --> $DIR/issue-72896-non-partial-eq-const.rs:19:9 | +LL | enum Enum8 { } + | ---------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 }; + | ------------------------------- constant defined here +... LL | CONST_SET => { /* ok */ } - | ^^^^^^^^^ + | ^^^^^^^^^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs b/tests/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs index 44b7fae351c..45d519739eb 100644 --- a/tests/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs +++ b/tests/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs @@ -1,6 +1,8 @@ //@ check-pass //@ compile-flags: -Zvalidate-mir +#![allow(unpredictable_function_pointer_comparisons)] + fn foo(_a: &str) {} fn main() { diff --git a/tests/ui/never_type/issue-52443.rs b/tests/ui/never_type/issue-52443.rs index dcda2b9536a..b112842030e 100644 --- a/tests/ui/never_type/issue-52443.rs +++ b/tests/ui/never_type/issue-52443.rs @@ -7,7 +7,6 @@ fn main() { //~^ WARN denote infinite loops with [(); { for _ in 0usize.. {}; 0}]; - //~^ ERROR `for` is not allowed in a `const` - //~| ERROR cannot convert - //~| ERROR cannot call + //~^ ERROR cannot use `for` + //~| ERROR cannot use `for` } diff --git a/tests/ui/never_type/issue-52443.stderr b/tests/ui/never_type/issue-52443.stderr index 2207ceb5033..1c5a0d65142 100644 --- a/tests/ui/never_type/issue-52443.stderr +++ b/tests/ui/never_type/issue-52443.stderr @@ -6,16 +6,6 @@ LL | [(); {while true {break}; 0}]; | = note: `#[warn(while_true)]` on by default -error[E0658]: `for` is not allowed in a `const` - --> $DIR/issue-52443.rs:9:12 - | -LL | [(); { for _ in 0usize.. {}; 0}]; - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information - = help: add `#![feature(const_for)]` 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[E0308]: mismatched types --> $DIR/issue-52443.rs:2:10 | @@ -41,25 +31,24 @@ help: give the `break` a value of the expected type LL | [(); loop { break 42 }]; | ++ -error[E0015]: cannot convert `RangeFrom<usize>` into an iterator in constants +error[E0015]: cannot use `for` loop on `RangeFrom<usize>` in constants --> $DIR/issue-52443.rs:9:21 | LL | [(); { for _ in 0usize.. {}; 0}]; | ^^^^^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const fn `<RangeFrom<usize> as Iterator>::next` in constants +error[E0015]: cannot use `for` loop on `RangeFrom<usize>` in constants --> $DIR/issue-52443.rs:9:21 | LL | [(); { for _ in 0usize.. {}; 0}]; | ^^^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted -Some errors have detailed explanations: E0015, E0308, E0658. +Some errors have detailed explanations: E0015, E0308. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/nll/closure-requirements/thread_scope_correct_implied_bound.rs b/tests/ui/nll/closure-requirements/thread_scope_correct_implied_bound.rs new file mode 100644 index 00000000000..e2b3b051ea8 --- /dev/null +++ b/tests/ui/nll/closure-requirements/thread_scope_correct_implied_bound.rs @@ -0,0 +1,23 @@ +// This example broke while refactoring the way closure +// requirements are handled. The setup here matches +// `thread::scope`. + +//@ check-pass + +struct Outlives<'hr, 'scope: 'hr>(*mut (&'scope (), &'hr ())); +impl<'hr, 'scope> Outlives<'hr, 'scope> { + fn outlives_hr<T: 'hr>(self) {} +} + +fn takes_closure_implied_bound<'scope>(f: impl for<'hr> FnOnce(Outlives<'hr, 'scope>)) {} + +fn requires_external_outlives_hr<T>() { + // implied bounds: + // - `T: 'scope` as `'scope` is local to this function + // - `'scope: 'hr` as it's an implied bound of `Outlives` + // + // need to prove `T: 'hr` :> + takes_closure_implied_bound(|proof| proof.outlives_hr::<T>()); +} + +fn main() {} diff --git a/tests/ui/nll/closure-requirements/thread_scope_incorrect_implied_bound.rs b/tests/ui/nll/closure-requirements/thread_scope_incorrect_implied_bound.rs new file mode 100644 index 00000000000..cfc8980410a --- /dev/null +++ b/tests/ui/nll/closure-requirements/thread_scope_incorrect_implied_bound.rs @@ -0,0 +1,21 @@ +// This example incorrectly compiled while refactoring the way +// closure requirements are handled. + +struct Outlives<'hr: 'scope, 'scope>(*mut (&'scope (), &'hr ())); +impl<'hr, 'scope> Outlives<'hr, 'scope> { + fn outlives_hr<T: 'hr>(self) {} +} + +fn takes_closure_implied_bound<'scope>(f: impl for<'hr> FnOnce(Outlives<'hr, 'scope>)) {} + +fn requires_external_outlives_hr<T>() { + // implied bounds: + // - `T: 'scope` as `'scope` is local to this function + // - `'hr: 'scope` as it's an implied bound of `Outlives` + // + // need to prove `T: 'hr` :< + takes_closure_implied_bound(|proof| proof.outlives_hr::<T>()); + //~^ ERROR the parameter type `T` may not live long enough +} + +fn main() {} diff --git a/tests/ui/nll/closure-requirements/thread_scope_incorrect_implied_bound.stderr b/tests/ui/nll/closure-requirements/thread_scope_incorrect_implied_bound.stderr new file mode 100644 index 00000000000..e22673c249f --- /dev/null +++ b/tests/ui/nll/closure-requirements/thread_scope_incorrect_implied_bound.stderr @@ -0,0 +1,17 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/thread_scope_incorrect_implied_bound.rs:17:47 + | +LL | takes_closure_implied_bound(|proof| proof.outlives_hr::<T>()); + | ^^^^^^^^^^^ + | | + | the parameter type `T` must be valid for the static lifetime... + | ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | fn requires_external_outlives_hr<T: 'static>() { + | +++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/nll/ty-outlives/projection-implied-bounds.rs b/tests/ui/nll/ty-outlives/projection-implied-bounds.rs index 7d983adfe88..c6572d60bb0 100644 --- a/tests/ui/nll/ty-outlives/projection-implied-bounds.rs +++ b/tests/ui/nll/ty-outlives/projection-implied-bounds.rs @@ -1,8 +1,6 @@ // Test that we can deduce when projections like `T::Item` outlive the // function body. Test that this does not imply that `T: 'a` holds. -//@ compile-flags:-Zverbose-internals - use std::cell::Cell; fn twice<F, T>(mut value: T, mut f: F) diff --git a/tests/ui/nll/ty-outlives/projection-implied-bounds.stderr b/tests/ui/nll/ty-outlives/projection-implied-bounds.stderr index 2aab03ee7b7..5d5b890151d 100644 --- a/tests/ui/nll/ty-outlives/projection-implied-bounds.stderr +++ b/tests/ui/nll/ty-outlives/projection-implied-bounds.stderr @@ -1,5 +1,5 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/projection-implied-bounds.rs:30:36 + --> $DIR/projection-implied-bounds.rs:28:36 | LL | twice(value, |value_ref, item| invoke2(value_ref, item)); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/parser/bad-recover-kw-after-impl.rs b/tests/ui/parser/bad-recover-kw-after-impl.rs index 15c0b377c8a..964d32c55bc 100644 --- a/tests/ui/parser/bad-recover-kw-after-impl.rs +++ b/tests/ui/parser/bad-recover-kw-after-impl.rs @@ -12,6 +12,6 @@ macro_rules! impl_primitive { impl_primitive!(impl async); //~^ ERROR expected identifier, found `<eof>` -//~| ERROR async closures are unstable +//~| ERROR `async` trait bounds are unstable fn main() {} diff --git a/tests/ui/parser/bad-recover-kw-after-impl.stderr b/tests/ui/parser/bad-recover-kw-after-impl.stderr index f617cf65498..7a8979db165 100644 --- a/tests/ui/parser/bad-recover-kw-after-impl.stderr +++ b/tests/ui/parser/bad-recover-kw-after-impl.stderr @@ -7,16 +7,16 @@ LL | ($ty:ty) => { LL | impl_primitive!(impl async); | ^^^^^ expected identifier -error[E0658]: async closures are unstable +error[E0658]: `async` trait bounds are unstable --> $DIR/bad-recover-kw-after-impl.rs:13:22 | LL | impl_primitive!(impl async); | ^^^^^ | = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: add `#![feature(async_trait_bounds)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: to use an async block, remove the `||`: `async {` + = help: use the desugared name of the async trait, such as `AsyncFn` error: aborting due to 2 previous errors diff --git a/tests/ui/parser/typed-self-param.rs b/tests/ui/parser/typed-self-param.rs new file mode 100644 index 00000000000..e3d85ab891b --- /dev/null +++ b/tests/ui/parser/typed-self-param.rs @@ -0,0 +1,14 @@ +struct S; + +impl S { + fn a(&self: Self) {} + //~^ ERROR type not allowed for shorthand `self` parameter + fn b(&mut self: Self) {} + //~^ ERROR type not allowed for shorthand `self` parameter + fn c<'c>(&'c mut self: Self) {} + //~^ ERROR type not allowed for shorthand `self` parameter + fn d<'d>(&'d self: Self) {} + //~^ ERROR type not allowed for shorthand `self` parameter +} + +fn main() {} diff --git a/tests/ui/parser/typed-self-param.stderr b/tests/ui/parser/typed-self-param.stderr new file mode 100644 index 00000000000..c1ecd3b7fef --- /dev/null +++ b/tests/ui/parser/typed-self-param.stderr @@ -0,0 +1,50 @@ +error: type not allowed for shorthand `self` parameter + --> $DIR/typed-self-param.rs:4:17 + | +LL | fn a(&self: Self) {} + | ^^^^ + | +help: move the modifiers on `self` to the type + | +LL - fn a(&self: Self) {} +LL + fn a(self: &Self) {} + | + +error: type not allowed for shorthand `self` parameter + --> $DIR/typed-self-param.rs:6:21 + | +LL | fn b(&mut self: Self) {} + | ^^^^ + | +help: move the modifiers on `self` to the type + | +LL - fn b(&mut self: Self) {} +LL + fn b(self: &mut Self) {} + | + +error: type not allowed for shorthand `self` parameter + --> $DIR/typed-self-param.rs:8:28 + | +LL | fn c<'c>(&'c mut self: Self) {} + | ^^^^ + | +help: move the modifiers on `self` to the type + | +LL - fn c<'c>(&'c mut self: Self) {} +LL + fn c<'c>(self: &'c mut Self) {} + | + +error: type not allowed for shorthand `self` parameter + --> $DIR/typed-self-param.rs:10:24 + | +LL | fn d<'d>(&'d self: Self) {} + | ^^^^ + | +help: move the modifiers on `self` to the type + | +LL - fn d<'d>(&'d self: Self) {} +LL + fn d<'d>(self: &'d Self) {} + | + +error: aborting due to 4 previous errors + diff --git a/tests/ui/pattern/issue-115599.rs b/tests/ui/pattern/issue-115599.rs index 1521d728d95..47fe6b87da9 100644 --- a/tests/ui/pattern/issue-115599.rs +++ b/tests/ui/pattern/issue-115599.rs @@ -3,5 +3,5 @@ const CONST_STRING: String = String::new(); fn main() { let empty_str = String::from(""); if let CONST_STRING = empty_str {} - //~^ ERROR to use a constant of type `Vec<u8>` in a pattern, `Vec<u8>` must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `Vec<u8>` in a pattern } diff --git a/tests/ui/pattern/issue-115599.stderr b/tests/ui/pattern/issue-115599.stderr index adab4e4d241..69d10728ccd 100644 --- a/tests/ui/pattern/issue-115599.stderr +++ b/tests/ui/pattern/issue-115599.stderr @@ -1,10 +1,15 @@ -error: to use a constant of type `Vec<u8>` in a pattern, `Vec<u8>` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `Vec<u8>` in a pattern --> $DIR/issue-115599.rs:5:12 | +LL | const CONST_STRING: String = String::new(); + | -------------------------- constant defined here +... LL | if let CONST_STRING = empty_str {} - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ constant of non-structural type + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | + = note: `Vec<u8>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns | - = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/pattern/issue-72565.stderr b/tests/ui/pattern/issue-72565.stderr index b503a17fe84..e2927ada0f7 100644 --- a/tests/ui/pattern/issue-72565.stderr +++ b/tests/ui/pattern/issue-72565.stderr @@ -1,8 +1,11 @@ -error: `dyn PartialEq<u32>` cannot be used in patterns +error: trait object `dyn PartialEq<u32>` cannot be used in patterns --> $DIR/issue-72565.rs:6:9 | +LL | const F: &'static dyn PartialEq<u32> = &7u32; + | ------------------------------------ constant defined here +... LL | F => panic!(), - | ^ + | ^ trait object can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/pattern/non-constant-in-const-path.stderr b/tests/ui/pattern/non-constant-in-const-path.stderr index 53c3974f780..2ba4963e6dc 100644 --- a/tests/ui/pattern/non-constant-in-const-path.stderr +++ b/tests/ui/pattern/non-constant-in-const-path.stderr @@ -2,25 +2,31 @@ error[E0080]: runtime values cannot be referenced in patterns --> $DIR/non-constant-in-const-path.rs:8:15 | LL | let 0u8..=x = 0; - | ^ + | ^ references a runtime value error[E0158]: statics cannot be referenced in patterns --> $DIR/non-constant-in-const-path.rs:10:15 | +LL | static FOO: u8 = 10; + | -------------- `static` defined here +... LL | let 0u8..=FOO = 0; - | ^^^ + | ^^^ can't be used in patterns error[E0080]: runtime values cannot be referenced in patterns --> $DIR/non-constant-in-const-path.rs:13:15 | LL | 0 ..= x => {} - | ^ + | ^ references a runtime value error[E0158]: statics cannot be referenced in patterns --> $DIR/non-constant-in-const-path.rs:15:15 | +LL | static FOO: u8 = 10; + | -------------- `static` defined here +... LL | 0 ..= FOO => {} - | ^^^ + | ^^^ can't be used in patterns error: aborting due to 4 previous errors diff --git a/tests/ui/pattern/non-structural-match-types.stderr b/tests/ui/pattern/non-structural-match-types.stderr index 9075cf40dda..3588751bf66 100644 --- a/tests/ui/pattern/non-structural-match-types.stderr +++ b/tests/ui/pattern/non-structural-match-types.stderr @@ -1,14 +1,14 @@ -error: `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns +error: closure `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns --> $DIR/non-structural-match-types.rs:9:9 | LL | const { || {} } => {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ closure can't be used in patterns -error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns +error: `async` block `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns --> $DIR/non-structural-match-types.rs:12:9 | LL | const { async {} } => {} - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ `async` block can't be used in patterns error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs index f34093ef149..f09dcf8498f 100644 --- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs +++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs @@ -12,7 +12,7 @@ const CONSTANT: &&MyType = &&MyType; fn main() { if let CONSTANT = &&MyType { - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `MyType` in a pattern println!("did match!"); } } diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr index 0b4d9972758..f9da0430f2e 100644 --- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr +++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `MyType` in a pattern, `MyType` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `MyType` in a pattern --> $DIR/const-partial_eq-fallback-ice.rs:14:12 | +LL | struct MyType; + | ------------- `MyType` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const CONSTANT: &&MyType = &&MyType; + | ------------------------ constant defined here +... LL | if let CONSTANT = &&MyType { - | ^^^^^^^^ + | ^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/const-partial_eq-fallback-ice.rs:5:1 + | +LL | impl PartialEq<usize> for MyType { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr index 32d385eecb4..d52451d9438 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.stderr +++ b/tests/ui/pattern/usefulness/consts-opaque.stderr @@ -1,50 +1,90 @@ -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:96:9 | +LL | const QUUX: Quux = quux; + | ---------------- constant defined here +... LL | QUUX => {} - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:97:9 | +LL | const QUUX: Quux = quux; + | ---------------- constant defined here +... LL | QUUX => {} - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:106:9 | +LL | const WRAPQUUX: Wrap<Quux> = Wrap(quux); + | -------------------------- constant defined here +... LL | WRAPQUUX => {} - | ^^^^^^^^ + | ^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:107:9 | +LL | const WRAPQUUX: Wrap<Quux> = Wrap(quux); + | -------------------------- constant defined here +... LL | WRAPQUUX => {} - | ^^^^^^^^ + | ^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:113:9 | +LL | const WRAPQUUX: Wrap<Quux> = Wrap(quux); + | -------------------------- constant defined here +... LL | WRAPQUUX => {} - | ^^^^^^^^ + | ^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:121:9 | +LL | const WRAPQUUX: Wrap<Quux> = Wrap(quux); + | -------------------------- constant defined here +... LL | WRAPQUUX => {} - | ^^^^^^^^ + | ^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:132:9 | +LL | const WHOKNOWSQUUX: WhoKnows<Quux> = WhoKnows::Yay(quux); + | ---------------------------------- constant defined here +... LL | WHOKNOWSQUUX => {} - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/consts-opaque.rs:134:9 | +LL | const WHOKNOWSQUUX: WhoKnows<Quux> = WhoKnows::Yay(quux); + | ---------------------------------- constant defined here +... LL | WHOKNOWSQUUX => {} - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details error: unreachable pattern --> $DIR/consts-opaque.rs:48:9 diff --git a/tests/ui/print-request/macos-target.rs b/tests/ui/print-request/macos-target.rs index 197edd02474..af74babbed4 100644 --- a/tests/ui/print-request/macos-target.rs +++ b/tests/ui/print-request/macos-target.rs @@ -1,5 +1,6 @@ //@ only-apple //@ compile-flags: --print deployment-target +//@ normalize-stdout-test: "\w*_DEPLOYMENT_TARGET" -> "$$OS_DEPLOYMENT_TARGET" //@ normalize-stdout-test: "\d+\." -> "$$CURRENT_MAJOR_VERSION." //@ normalize-stdout-test: "\d+" -> "$$CURRENT_MINOR_VERSION" //@ check-pass diff --git a/tests/ui/print-request/macos-target.stdout b/tests/ui/print-request/macos-target.stdout index f55ef568ed6..34ade570969 100644 --- a/tests/ui/print-request/macos-target.stdout +++ b/tests/ui/print-request/macos-target.stdout @@ -1 +1 @@ -deployment_target=$CURRENT_MAJOR_VERSION.$CURRENT_MINOR_VERSION +$OS_DEPLOYMENT_TARGET=$CURRENT_MAJOR_VERSION.$CURRENT_MINOR_VERSION diff --git a/tests/ui/process/env-funky-keys.rs b/tests/ui/process/env-funky-keys.rs index 314ccaea015..a4a71c94020 100644 --- a/tests/ui/process/env-funky-keys.rs +++ b/tests/ui/process/env-funky-keys.rs @@ -1,4 +1,5 @@ //@ run-pass +//@ edition: 2021 // Ignore this test on Android, because it segfaults there. //@ ignore-android @@ -32,10 +33,9 @@ fn main() { .unwrap() .as_os_str() .as_bytes()).unwrap(); - let new_env_var = CString::new("FOOBAR").unwrap(); let filename: *const c_char = current_exe.as_ptr(); let argv: &[*const c_char] = &[filename, filename, ptr::null()]; - let envp: &[*const c_char] = &[new_env_var.as_ptr(), ptr::null()]; + let envp: &[*const c_char] = &[c"FOOBAR".as_ptr(), ptr::null()]; unsafe { execve(filename, &argv[0], &envp[0]); } diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr index fbb9ede8aa1..c7e9df10d41 100644 --- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr @@ -29,6 +29,20 @@ LL | const _: u32 = T::C; | = note: a `const` is a separate item from the item that contains it +note: erroneous constant encountered + --> $DIR/generic-params-from-outer-item-in-const-item.rs:22:9 + | +LL | I + | ^ + +note: erroneous constant encountered + --> $DIR/generic-params-from-outer-item-in-const-item.rs:22:9 + | +LL | I + | ^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0401`. diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr index 60aa94038c3..64c436d3ceb 100644 --- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr @@ -35,6 +35,20 @@ LL | const _: u32 = T::C; | = note: a `const` is a separate item from the item that contains it +note: erroneous constant encountered + --> $DIR/generic-params-from-outer-item-in-const-item.rs:22:9 + | +LL | I + | ^ + +note: erroneous constant encountered + --> $DIR/generic-params-from-outer-item-in-const-item.rs:22:9 + | +LL | I + | ^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0401`. diff --git a/tests/ui/resolve/issue-50599.stderr b/tests/ui/resolve/issue-50599.stderr index 24fb3d580b8..427dc9f2049 100644 --- a/tests/ui/resolve/issue-50599.stderr +++ b/tests/ui/resolve/issue-50599.stderr @@ -20,6 +20,12 @@ LL - const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; LL + const M: usize = (f64::from(N) * LOG10_2) as usize; | +note: erroneous constant encountered + --> $DIR/issue-50599.rs:4:29 + | +LL | let mut digits = [0u32; M]; + | ^ + error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs index 65a85a5ed68..e27c8048049 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs @@ -20,7 +20,7 @@ const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0)); fn main() { match WRAP_DIRECT_INLINE { WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_DIRECT_INLINE did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr index cc5d4106331..8787d140e17 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-direct-struct-embedded.rs:22:9 | +LL | struct NoDerive(#[allow(dead_code)] i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0)); + | ------------------------------------ constant defined here +... LL | WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-direct-struct-embedded.rs:11:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs index f840b4040b6..713ff23573d 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs @@ -19,7 +19,7 @@ const WRAP_DIRECT_PARAM: WrapParam<NoDerive> = WrapParam(NoDerive(0)); fn main() { match WRAP_DIRECT_PARAM { WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_DIRECT_PARAM did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr index 3d00ef2dfbf..ec836db02ad 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-direct-struct-param.rs:21:9 | +LL | struct NoDerive(i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_DIRECT_PARAM: WrapParam<NoDerive> = WrapParam(NoDerive(0)); + | -------------------------------------------- constant defined here +... LL | WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-direct-struct-param.rs:10:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs index 898acefc83c..7766a469192 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs @@ -20,7 +20,7 @@ const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0) fn main() { match WRAP_DOUBLY_INDIRECT_INLINE { WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr index 3636307e16c..fdc16fe300c 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:22:9 | +LL | struct NoDerive(#[allow(dead_code)] i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0)); + | ------------------------------------------------ constant defined here +... LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:11:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs index 7cbaada88a3..ed84900b6e9 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs @@ -20,7 +20,7 @@ const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(& & NoDe fn main() { match WRAP_DOUBLY_INDIRECT_PARAM { WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr index 40fd31762b2..b46fc041f14 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-doubly-indirect-param.rs:22:9 | +LL | struct NoDerive(#[allow(dead_code)] i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(& & NoDerive(0)); + | -------------------------------------------------------- constant defined here +... LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-doubly-indirect-param.rs:11:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs index ac868efed6f..5743d7a24d3 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs @@ -20,7 +20,7 @@ const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0)); fn main() { match WRAP_INDIRECT_INLINE { WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_INDIRECT_INLINE did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr index dbf1848326a..70f39aa01d8 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:22:9 | +LL | struct NoDerive(#[allow(dead_code)] i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0)); + | ----------------------------------------- constant defined here +... LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:11:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs index cbfabec6819..9226f9c3ecd 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs @@ -20,7 +20,7 @@ const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0)); fn main() { match WRAP_INDIRECT_PARAM { WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `NoDerive` in a pattern _ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr index 58acc11a744..fceb3acb025 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` +error: constant of non-structural type `NoDerive` in a pattern --> $DIR/cant-hide-behind-indirect-struct-param.rs:22:9 | +LL | struct NoDerive(#[allow(dead_code)] i32); + | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0)); + | ------------------------------------------------- constant defined here +... LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/cant-hide-behind-indirect-struct-param.rs:11:1 + | +LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr index 0bc1e7fc89b..cdbe72ca48f 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr @@ -1,62 +1,112 @@ -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:41:14 | +LL | const CFN1: Wrap<fn()> = Wrap(trivial); + | ---------------------- constant defined here +... LL | Wrap(CFN1) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:49:14 | +LL | const CFN2: Wrap<fn(SM)> = Wrap(sm_to); + | ------------------------ constant defined here +... LL | Wrap(CFN2) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:57:14 | +LL | const CFN3: Wrap<fn() -> SM> = Wrap(to_sm); + | ---------------------------- constant defined here +... LL | Wrap(CFN3) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:65:14 | +LL | const CFN4: Wrap<fn(NotSM)> = Wrap(not_sm_to); + | --------------------------- constant defined here +... LL | Wrap(CFN4) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:73:14 | +LL | const CFN5: Wrap<fn() -> NotSM> = Wrap(to_not_sm); + | ------------------------------- constant defined here +... LL | Wrap(CFN5) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:81:14 | +LL | const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); + | ------------------------- constant defined here +... LL | Wrap(CFN6) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:89:14 | +LL | const CFN7: Wrap<fn(&()) -> &SM> = Wrap(r_to_r_sm); + | -------------------------------- constant defined here +... LL | Wrap(CFN7) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:97:14 | +LL | const CFN8: Wrap<fn(&NotSM)> = Wrap(r_not_sm_to); + | ---------------------------- constant defined here +... LL | Wrap(CFN8) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:105:14 | +LL | const CFN9: Wrap<fn(&()) -> &NotSM> = Wrap(r_to_r_not_sm); + | ----------------------------------- constant defined here +... LL | Wrap(CFN9) => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/fn-ptr-is-not-structurally-matchable.rs:127:9 | +LL | const CFOO: Foo = Foo { + | --------------- constant defined here +... LL | CFOO => count += 1, - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details error: aborting due to 10 previous errors diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs index c01f8934c75..95a3be517a9 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs @@ -12,8 +12,7 @@ const A: &[B] = &[]; pub fn main() { match &[][..] { - A => (), - //~^ ERROR must implement `PartialEq` + A => (), //~ ERROR constant of non-structural type `&[B]` in a pattern _ => (), } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr index 736e4c30c8a..7d3b37686b8 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr @@ -1,8 +1,16 @@ -error: to use a constant of type `&[B]` in a pattern, the type must implement `PartialEq` +error: constant of non-structural type `&[B]` in a pattern --> $DIR/issue-61188-match-slice-forbidden-without-eq.rs:15:9 | +LL | struct B(i32); + | -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns +LL | +LL | const A: &[B] = &[]; + | ------------- constant defined here +... LL | A => (), - | ^ + | ^ constant of non-structural type + | + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs index 0fa2370c95b..843c5a38649 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs @@ -13,27 +13,35 @@ #[derive(Debug)] struct B(i32); +//~^ NOTE `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +//~| NOTE `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns // Overriding `PartialEq` to use this strange notion of "equality" exposes // whether `match` is using structural-equality or method-dispatch // under the hood, which is the antithesis of rust-lang/rfcs#1445 impl PartialEq for B { +//~^ NOTE the `PartialEq` trait must be derived, manual `impl`s are not sufficient +//~| NOTE the `PartialEq` trait must be derived, manual `impl`s are not sufficient fn eq(&self, other: &B) -> bool { std::cmp::min(self.0, other.0) == 0 } } fn main() { const RR_B0: & & B = & & B(0); const RR_B1: & & B = & & B(1); + //~^ NOTE constant defined here + //~| NOTE constant defined here match RR_B0 { RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `B` in a pattern + //~| NOTE constant of non-structural type _ => { } } match RR_B1 { RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `B` in a pattern + //~| NOTE constant of non-structural type _ => { } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr index e79b05fdf9d..34fffd99c2c 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr @@ -1,20 +1,38 @@ -error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:29:9 +error: constant of non-structural type `B` in a pattern + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:35:9 | +LL | struct B(i32); + | -------- `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const RR_B1: & & B = & & B(1); + | ------------------ constant defined here +... LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } - | ^^^^^ + | ^^^^^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:22:1 | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +LL | impl PartialEq for B { + | ^^^^^^^^^^^^^^^^^^^^ -error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:35:9 +error: constant of non-structural type `B` in a pattern + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:42:9 | +LL | struct B(i32); + | -------- `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const RR_B1: & & B = & & B(1); + | ------------------ constant defined here +... LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } - | ^^^^^ + | ^^^^^ constant of non-structural type + | +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:22:1 | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +LL | impl PartialEq for B { + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr index 7b1832ed0fa..ea6121839be 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr @@ -1,14 +1,24 @@ -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-63479-match-fnptr.rs:32:7 | +LL | const TEST: Fn = my_fn; + | -------------- constant defined here +... LL | B(TEST) => println!("matched"), - | ^^^^ + | ^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon --> $DIR/issue-63479-match-fnptr.rs:37:5 | +LL | const TEST2: (Fn, u8) = (TEST, 0); + | --------------------- constant defined here +... LL | TEST2 => println!("matched"), - | ^^^^^ + | ^^^^^ can't be used in patterns + | + = note: see https://github.com/rust-lang/rust/issues/70861 for details error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr index 44b05ea31e9..7c49870e5d0 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr @@ -1,8 +1,11 @@ error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:14:9 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | NAN => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -10,8 +13,11 @@ LL | NAN => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:19:10 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | [NAN, _] => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -19,8 +25,11 @@ LL | [NAN, _] => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:24:9 | +LL | const C: MyType<f32> = MyType(f32::NAN); + | -------------------- constant defined here +... LL | C => {}, - | ^ + | ^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -28,8 +37,11 @@ LL | C => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:30:9 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | NAN..=1.0 => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -37,8 +49,11 @@ LL | NAN..=1.0 => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:31:16 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | -1.0..=NAN => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -46,8 +61,11 @@ LL | -1.0..=NAN => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:32:9 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | NAN.. => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead @@ -55,8 +73,11 @@ LL | NAN.. => {}, error: cannot use NaN in patterns --> $DIR/issue-6804-nan-match.rs:33:11 | +LL | const NAN: f64 = f64::NAN; + | -------------- constant defined here +... LL | ..NAN => {}, - | ^^^ + | ^^^ evaluates to `NaN`, which is not allowed in patterns | = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs index 9020eb291f5..74394698fbc 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs @@ -1,3 +1,5 @@ +// Note: It is no longer true that both `Eq` and `PartialEq` must the derived, only the later. + #[derive(Eq)] struct Foo { x: u32 @@ -15,7 +17,7 @@ fn main() { let y = Foo { x: 1 }; match y { FOO => { } - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR constant of non-structural type `Foo` in a pattern _ => { } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr index efd9c8c45af..bbcab3b62d0 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr @@ -1,11 +1,20 @@ -error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]` - --> $DIR/match-requires-both-partialeq-and-eq.rs:17:9 +error: constant of non-structural type `Foo` in a pattern + --> $DIR/match-requires-both-partialeq-and-eq.rs:19:9 | +LL | struct Foo { + | ---------- `Foo` must be annotated with `#[derive(PartialEq)]` to be usable in patterns +... +LL | const FOO: Foo = Foo { x: 0 }; + | -------------- constant defined here +... LL | FOO => { } - | ^^^ + | ^^^ constant of non-structural type | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details + --> $DIR/match-requires-both-partialeq-and-eq.rs:8:1 + | +LL | impl PartialEq for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.stderr index 606f808f093..eab2604d4c0 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.stderr +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.stderr @@ -6,5 +6,11 @@ LL | !let y = 42; | = note: only supported directly in conditions of `if` and `while` expressions +note: erroneous constant encountered + --> $DIR/avoid-invalid-mir.rs:11:13 + | +LL | x: [(); N] + | ^ + error: aborting due to 1 previous error diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr index cf4c219215e..e4991823d28 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr @@ -17,6 +17,12 @@ LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 { LL | } | - value is dropped here +note: erroneous constant encountered + --> $DIR/arbitrary-self-from-method-substs-ice.rs:24:5 + | +LL | FOO; + | ^^^ + error[E0801]: invalid generic `self` parameter type: `R` --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:49 | diff --git a/tests/ui/self/arbitrary-self-opaque.rs b/tests/ui/self/arbitrary-self-opaque.rs index 3c2e2d9db72..c26ef658b69 100644 --- a/tests/ui/self/arbitrary-self-opaque.rs +++ b/tests/ui/self/arbitrary-self-opaque.rs @@ -2,7 +2,6 @@ struct Foo; type Bar = impl Sized; -//~^ ERROR unconstrained opaque type impl Foo { fn foo(self: Bar) {} diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr index 5634b3d6e64..c75165d9f8e 100644 --- a/tests/ui/self/arbitrary-self-opaque.stderr +++ b/tests/ui/self/arbitrary-self-opaque.stderr @@ -1,5 +1,5 @@ error[E0307]: invalid `self` parameter type: `Bar` - --> $DIR/arbitrary-self-opaque.rs:8:18 + --> $DIR/arbitrary-self-opaque.rs:7:18 | LL | fn foo(self: Bar) {} | ^^^ @@ -8,7 +8,7 @@ LL | fn foo(self: Bar) {} = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) error: item does not constrain `Bar::{opaque#0}`, but has it in its signature - --> $DIR/arbitrary-self-opaque.rs:8:8 + --> $DIR/arbitrary-self-opaque.rs:7:8 | LL | fn foo(self: Bar) {} | ^^^ @@ -20,14 +20,6 @@ note: this opaque type is in the signature LL | type Bar = impl Sized; | ^^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/arbitrary-self-opaque.rs:4:12 - | -LL | type Bar = impl Sized; - | ^^^^^^^^^^ - | - = note: `Bar` must be used in combination with a concrete type within the same module - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0307`. diff --git a/tests/ui/simd/intrinsic/float-math-pass.rs b/tests/ui/simd/intrinsic/float-math-pass.rs index 9b14d410acb..24b9941133e 100644 --- a/tests/ui/simd/intrinsic/float-math-pass.rs +++ b/tests/ui/simd/intrinsic/float-math-pass.rs @@ -23,6 +23,7 @@ extern "rust-intrinsic" { fn simd_fexp<T>(x: T) -> T; fn simd_fexp2<T>(x: T) -> T; fn simd_fma<T>(x: T, y: T, z: T) -> T; + fn simd_relaxed_fma<T>(x: T, y: T, z: T) -> T; fn simd_flog<T>(x: T) -> T; fn simd_flog10<T>(x: T) -> T; fn simd_flog2<T>(x: T) -> T; @@ -77,6 +78,9 @@ fn main() { let r = simd_fma(x, h, h); assert_approx_eq!(x, r); + let r = simd_relaxed_fma(x, h, h); + assert_approx_eq!(x, r); + let r = simd_fsqrt(x); assert_approx_eq!(x, r); diff --git a/tests/ui/traits/bound/unknown-assoc-with-const-arg.rs b/tests/ui/traits/bound/unknown-assoc-with-const-arg.rs index 48a98efea5e..0da68afb592 100644 --- a/tests/ui/traits/bound/unknown-assoc-with-const-arg.rs +++ b/tests/ui/traits/bound/unknown-assoc-with-const-arg.rs @@ -3,7 +3,6 @@ trait X { fn a<T>() -> T::unknown<{}> {} //~^ ERROR: associated type `unknown` not found for `T` - //~| ERROR: associated type `unknown` not found for `T` } trait Y { @@ -14,7 +13,6 @@ trait Y { trait Z<T> { fn a() -> T::unknown<{}> {} //~^ ERROR: associated type `unknown` not found for `T` - //~| ERROR: associated type `unknown` not found for `T` } fn main() {} diff --git a/tests/ui/traits/bound/unknown-assoc-with-const-arg.stderr b/tests/ui/traits/bound/unknown-assoc-with-const-arg.stderr index 9598c373e6e..49e41f75ff3 100644 --- a/tests/ui/traits/bound/unknown-assoc-with-const-arg.stderr +++ b/tests/ui/traits/bound/unknown-assoc-with-const-arg.stderr @@ -5,34 +5,18 @@ LL | fn a<T>() -> T::unknown<{}> {} | ^^^^^^^ associated type `unknown` not found error[E0220]: associated type `unknown` not found for `T` - --> $DIR/unknown-assoc-with-const-arg.rs:15:18 + --> $DIR/unknown-assoc-with-const-arg.rs:14:18 | LL | fn a() -> T::unknown<{}> {} | ^^^^^^^ associated type `unknown` not found -error[E0220]: associated type `unknown` not found for `T` - --> $DIR/unknown-assoc-with-const-arg.rs:4:21 - | -LL | fn a<T>() -> T::unknown<{}> {} - | ^^^^^^^ associated type `unknown` not found - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0220]: associated type `unknown` not found for `T` - --> $DIR/unknown-assoc-with-const-arg.rs:15:18 - | -LL | fn a() -> T::unknown<{}> {} - | ^^^^^^^ associated type `unknown` not found - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0433]: failed to resolve: use of undeclared type `NOT_EXIST` - --> $DIR/unknown-assoc-with-const-arg.rs:10:15 + --> $DIR/unknown-assoc-with-const-arg.rs:9:15 | LL | fn a() -> NOT_EXIST::unknown<{}> {} | ^^^^^^^^^ use of undeclared type `NOT_EXIST` -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0220, E0433. For more information about an error, try `rustc --explain E0220`. diff --git a/tests/ui/traits/const-traits/hir-const-check.rs b/tests/ui/traits/const-traits/hir-const-check.rs index ea1783b7c2c..c485fb12184 100644 --- a/tests/ui/traits/const-traits/hir-const-check.rs +++ b/tests/ui/traits/const-traits/hir-const-check.rs @@ -11,9 +11,9 @@ pub trait MyTrait { impl const MyTrait for () { fn method(&self) -> Option<()> { - Some(())?; //~ ERROR `?` is not allowed in a `const fn` - //~^ ERROR `?` cannot determine the branch of `Option<()>` in constant functions - //~| ERROR `?` cannot convert from residual of `Option<()>` in constant functions + Some(())?; + //~^ ERROR `?` is not allowed on + //~| ERROR `?` is not allowed on None } } diff --git a/tests/ui/traits/const-traits/hir-const-check.stderr b/tests/ui/traits/const-traits/hir-const-check.stderr index ef5dba0dc0e..d66a7ea3144 100644 --- a/tests/ui/traits/const-traits/hir-const-check.stderr +++ b/tests/ui/traits/const-traits/hir-const-check.stderr @@ -1,34 +1,19 @@ -error[E0658]: `?` is not allowed in a `const fn` +error[E0015]: `?` is not allowed on `Option<()>` in constant functions --> $DIR/hir-const-check.rs:14:9 | LL | Some(())?; | ^^^^^^^^^ | - = note: see issue #74935 <https://github.com/rust-lang/rust/issues/74935> for more information - = help: add `#![feature(const_try)]` 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[E0015]: `?` cannot determine the branch of `Option<()>` in constant functions - --> $DIR/hir-const-check.rs:14:9 - | -LL | Some(())?; - | ^^^^^^^^^ - | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/option.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0015]: `?` cannot convert from residual of `Option<()>` in constant functions +error[E0015]: `?` is not allowed on `Option<()>` in constant functions --> $DIR/hir-const-check.rs:14:9 | LL | Some(())?; | ^^^^^^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/option.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0658. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs index 9ce81031b27..3473be565c1 100644 --- a/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs +++ b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs @@ -18,8 +18,8 @@ impl const Try for TryMe { const fn t() -> TryMe { TryMe?; - //~^ ERROR `?` cannot determine the branch of `TryMe` in constant functions - //~| ERROR `?` cannot convert from residual of `TryMe` in constant functions + //~^ ERROR `?` is not allowed on + //~| ERROR `?` is not allowed on TryMe } diff --git a/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr index db047bfd94d..9bd493e5fdb 100644 --- a/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr +++ b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr @@ -33,7 +33,7 @@ LL | impl const Try for TryMe { = help: implement the missing item: `fn from_output(_: <Self as Try>::Output) -> Self { todo!() }` = help: implement the missing item: `fn branch(self) -> ControlFlow<<Self as Try>::Residual, <Self as Try>::Output> { todo!() }` -error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions +error[E0015]: `?` is not allowed on `TryMe` in constant functions --> $DIR/ice-126148-failed-to-normalize.rs:20:5 | LL | TryMe?; @@ -41,7 +41,7 @@ LL | TryMe?; | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions +error[E0015]: `?` is not allowed on `TryMe` in constant functions --> $DIR/ice-126148-failed-to-normalize.rs:20:5 | LL | TryMe?; diff --git a/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr b/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr new file mode 100644 index 00000000000..bd822970ad1 --- /dev/null +++ b/tests/ui/traits/const-traits/overlap-const-with-nonconst.min_spec.stderr @@ -0,0 +1,14 @@ +error[E0119]: conflicting implementations of trait `Foo` for type `(_,)` + --> $DIR/overlap-const-with-nonconst.rs:23:1 + | +LL | / impl<T> const Foo for T +LL | | where +LL | | T: ~const Bar, + | |__________________- first implementation here +... +LL | impl<T> Foo for (T,) { + | ^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(_,)` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs b/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs new file mode 100644 index 00000000000..eb66d03faa6 --- /dev/null +++ b/tests/ui/traits/const-traits/overlap-const-with-nonconst.rs @@ -0,0 +1,38 @@ +//@ revisions: spec min_spec + +#![feature(const_trait_impl)] +#![cfg_attr(spec, feature(specialization))] +//[spec]~^ WARN the feature `specialization` is incomplete +#![cfg_attr(min_spec, feature(min_specialization))] + +#[const_trait] +trait Bar {} +impl<T> const Bar for T {} + +#[const_trait] +trait Foo { + fn method(&self); +} +impl<T> const Foo for T +where + T: ~const Bar, +{ + default fn method(&self) {} +} +// specializing impl: +impl<T> Foo for (T,) { +//~^ ERROR conflicting implementations + fn method(&self) { + println!("hi"); + } +} + +const fn dispatch<T: ~const Bar + Copy>(t: T) { + t.method(); +} + +fn main() { + const { + dispatch(((),)); + } +} diff --git a/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr b/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr new file mode 100644 index 00000000000..cbdcb45f6be --- /dev/null +++ b/tests/ui/traits/const-traits/overlap-const-with-nonconst.spec.stderr @@ -0,0 +1,24 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/overlap-const-with-nonconst.rs:4:27 + | +LL | #![cfg_attr(spec, feature(specialization))] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0119]: conflicting implementations of trait `Foo` for type `(_,)` + --> $DIR/overlap-const-with-nonconst.rs:23:1 + | +LL | / impl<T> const Foo for T +LL | | where +LL | | T: ~const Bar, + | |__________________- first implementation here +... +LL | impl<T> Foo for (T,) { + | ^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(_,)` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr index bffc60c65fc..9166b8ca5d2 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr +++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr @@ -1,11 +1,31 @@ -error: cannot specialize on const impl with non-const impl +error[E0119]: conflicting implementations of trait `Bar` --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:1 | +LL | / impl<T> const Bar for T +LL | | where +LL | | T: ~const Foo, + | |__________________- first implementation here +... LL | / impl<T> Bar for T LL | | where LL | | T: Foo, //FIXME ~ ERROR missing `~const` qualifier LL | | T: Specialize, - | |__________________^ + | |__________________^ conflicting implementation + +error[E0119]: conflicting implementations of trait `Baz` + --> $DIR/const-default-bound-non-const-specialized-bound.rs:48:1 + | +LL | / impl<T> const Baz for T +LL | | where +LL | | T: ~const Foo, + | |__________________- first implementation here +... +LL | / impl<T> const Baz for T //FIXME ~ ERROR conflicting implementations of trait `Baz` +LL | | where +LL | | T: Foo, +LL | | T: Specialize, + | |__________________^ conflicting implementation -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr new file mode 100644 index 00000000000..38fc5ddfbef --- /dev/null +++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.min_spec.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Value` for type `FortyTwo` + --> $DIR/const-default-impl-non-const-specialized-impl.rs:22:1 + | +LL | impl<T> const Value for T { + | ------------------------- first implementation here +... +LL | impl Value for FortyTwo { + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `FortyTwo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs index a3bb9b3f93e..acf0a967a88 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs +++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.rs @@ -1,7 +1,10 @@ // Tests that specializing trait impls must be at least as const as the default impl. +//@ revisions: spec min_spec #![feature(const_trait_impl)] -#![feature(min_specialization)] +#![cfg_attr(spec, feature(specialization))] +//[spec]~^ WARN the feature `specialization` is incomplete +#![cfg_attr(min_spec, feature(min_specialization))] #[const_trait] trait Value { @@ -16,7 +19,8 @@ impl<T> const Value for T { struct FortyTwo; -impl Value for FortyTwo { //~ ERROR cannot specialize on const impl with non-const impl +impl Value for FortyTwo { + //~^ ERROR conflicting implementations fn value() -> u32 { println!("You can't do that (constly)"); 42 diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr new file mode 100644 index 00000000000..b59c42f5189 --- /dev/null +++ b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.spec.stderr @@ -0,0 +1,22 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/const-default-impl-non-const-specialized-impl.rs:5:27 + | +LL | #![cfg_attr(spec, feature(specialization))] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0119]: conflicting implementations of trait `Value` for type `FortyTwo` + --> $DIR/const-default-impl-non-const-specialized-impl.rs:22:1 + | +LL | impl<T> const Value for T { + | ------------------------- first implementation here +... +LL | impl Value for FortyTwo { + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `FortyTwo` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.stderr b/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.stderr deleted file mode 100644 index e356621ba47..00000000000 --- a/tests/ui/traits/const-traits/specialization/const-default-impl-non-const-specialized-impl.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: cannot specialize on const impl with non-const impl - --> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1 - | -LL | impl Value for FortyTwo { - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/traits/const-traits/specializing-constness.rs b/tests/ui/traits/const-traits/specializing-constness.rs index 632121924a6..94b6da7124d 100644 --- a/tests/ui/traits/const-traits/specializing-constness.rs +++ b/tests/ui/traits/const-traits/specializing-constness.rs @@ -21,8 +21,7 @@ impl<T: ~const Spec> const A for T { } impl<T: Spec + Sup> A for T { -//~^ ERROR: cannot specialize -//FIXME(const_trait_impl) ~| ERROR: missing `~const` qualifier + //~^ ERROR conflicting implementations of trait `A` fn a() -> u32 { 3 } diff --git a/tests/ui/traits/const-traits/specializing-constness.stderr b/tests/ui/traits/const-traits/specializing-constness.stderr index 21e21c2cb71..2ca70b53e4e 100644 --- a/tests/ui/traits/const-traits/specializing-constness.stderr +++ b/tests/ui/traits/const-traits/specializing-constness.stderr @@ -1,8 +1,12 @@ -error: cannot specialize on const impl with non-const impl +error[E0119]: conflicting implementations of trait `A` --> $DIR/specializing-constness.rs:23:1 | +LL | impl<T: ~const Spec> const A for T { + | ---------------------------------- first implementation here +... LL | impl<T: Spec + Sup> A for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/const-traits/trait-default-body-stability.stderr b/tests/ui/traits/const-traits/trait-default-body-stability.stderr index 5806b6d6fd2..b471cb81c3b 100644 --- a/tests/ui/traits/const-traits/trait-default-body-stability.stderr +++ b/tests/ui/traits/const-traits/trait-default-body-stability.stderr @@ -16,7 +16,7 @@ LL | impl const FromResidual for T { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0015]: `?` cannot determine the branch of `T` in constant functions +error[E0015]: `?` is not allowed on `T` in constant functions --> $DIR/trait-default-body-stability.rs:45:9 | LL | T? @@ -24,7 +24,7 @@ LL | T? | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0015]: `?` cannot convert from residual of `T` in constant functions +error[E0015]: `?` is not allowed on `T` in constant functions --> $DIR/trait-default-body-stability.rs:45:9 | LL | T? diff --git a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr index 03a4017b3d7..38e692521ca 100644 --- a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr +++ b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr @@ -23,29 +23,29 @@ LL | struct Struct {} | ---------------- not a trait error: function not found in this trait - --> $DIR/rustc_must_implement_one_of_misuse.rs:8:34 + --> $DIR/rustc_must_implement_one_of_misuse.rs:3:31 | LL | #[rustc_must_implement_one_of(a, b)] - | ^ - -error: the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args - --> $DIR/rustc_must_implement_one_of_misuse.rs:14:1 - | -LL | #[rustc_must_implement_one_of(a)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: function not found in this trait - --> $DIR/rustc_must_implement_one_of_misuse.rs:3:31 + --> $DIR/rustc_must_implement_one_of_misuse.rs:3:34 | LL | #[rustc_must_implement_one_of(a, b)] - | ^ + | ^ error: function not found in this trait - --> $DIR/rustc_must_implement_one_of_misuse.rs:3:34 + --> $DIR/rustc_must_implement_one_of_misuse.rs:8:34 | LL | #[rustc_must_implement_one_of(a, b)] | ^ +error: the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args + --> $DIR/rustc_must_implement_one_of_misuse.rs:14:1 + | +LL | #[rustc_must_implement_one_of(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: not a function --> $DIR/rustc_must_implement_one_of_misuse.rs:26:5 | diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs index e1bd234a275..8fe53d6773b 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.rs +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -18,6 +18,6 @@ impl<T> Overlap<T> for T {} impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} //~^ ERROR cannot find type `Missing` in this scope -//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied +//~| ERROR the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied fn main() {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index f6545c6ebf9..09162970d33 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -26,17 +26,16 @@ LL | trait ToUnit<'a> { | ^^^^^^^^^^^^^^^^ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } -error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied - --> $DIR/issue-118950-root-region.rs:19:17 +error[E0277]: the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied + --> $DIR/issue-118950-root-region.rs:19:47 | LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T` + | ^ the trait `Overlap<for<'a> fn(Assoc<'a, T>)>` is not implemented for `T` | -help: this trait has no implementations, consider adding one - --> $DIR/issue-118950-root-region.rs:8:1 +help: consider further restricting type parameter `T` | -LL | trait ToUnit<'a> { - | ^^^^^^^^^^^^^^^^ +LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T>, T: Overlap<for<'a> fn(Assoc<'a, T>)> {} + | ++++++++++++++++++++++++++++++++++++++ error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/traits/next-solver/normalize-in-implied_outlives_bounds.rs b/tests/ui/traits/next-solver/normalize-in-implied_outlives_bounds.rs new file mode 100644 index 00000000000..1dca19d28e9 --- /dev/null +++ b/tests/ui/traits/next-solver/normalize-in-implied_outlives_bounds.rs @@ -0,0 +1,46 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +// Minimized example from `rustc_type_ir` that demonstrates a missing deep normalization +// in the new solver when computing the implies outlives bounds of an impl. + +use std::marker::PhantomData; +use std::ops::Deref; + +pub struct SearchGraph<D: Delegate, X = <D as Delegate>::Cx> { + d: PhantomData<D>, + x: PhantomData<X>, +} + +pub trait Delegate { + type Cx; +} + +struct SearchGraphDelegate<D: SolverDelegate> { + _marker: PhantomData<D>, +} + +impl<D> Delegate for SearchGraphDelegate<D> +where + D: SolverDelegate, +{ + type Cx = D::Interner; +} + +pub trait SolverDelegate { + type Interner; +} + +struct EvalCtxt<'a, D, I> +where + D: SolverDelegate<Interner = I>, +{ + search_graph: &'a SearchGraph<SearchGraphDelegate<D>>, +} + +impl<'a, D, I> EvalCtxt<'a, D, <D as SolverDelegate>::Interner> +where + D: SolverDelegate<Interner = I> +{} + +fn main() {} diff --git a/tests/ui/traits/next-solver/typeck/structurally-resolve-in-probe_adt.rs b/tests/ui/traits/next-solver/typeck/structurally-resolve-in-probe_adt.rs new file mode 100644 index 00000000000..23915808279 --- /dev/null +++ b/tests/ui/traits/next-solver/typeck/structurally-resolve-in-probe_adt.rs @@ -0,0 +1,15 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +trait Mirror { + type Assoc; +} +impl<T> Mirror for T { + type Assoc = T; +} + +type Foo<T> = <Option<T> as Mirror>::Assoc; + +fn main() { + let x = Foo::<i32>::None; +} diff --git a/tests/ui/transmutability/uninhabited.rs b/tests/ui/transmutability/uninhabited.rs index 74f7a1a2e89..274104ffb39 100644 --- a/tests/ui/transmutability/uninhabited.rs +++ b/tests/ui/transmutability/uninhabited.rs @@ -91,3 +91,19 @@ fn distant_void() { assert::is_maybe_transmutable::<DistantVoid, &'static Void>(); assert::is_maybe_transmutable::<u128, DistantVoid>(); //~ ERROR: cannot be safely transmuted } + +fn issue_126267() { + pub enum ApiError {} + pub struct TokioError { + b: bool, + } + pub enum Error { + Api { source: ApiError }, // this variant is uninhabited + Ethereum, + Tokio { source: TokioError }, + } + + struct Src; + type Dst = Error; + assert::is_maybe_transmutable::<Src, Dst>(); //~ERROR: cannot be safely transmuted +} diff --git a/tests/ui/transmutability/uninhabited.stderr b/tests/ui/transmutability/uninhabited.stderr index 3fa02f0867c..f112d2fbe44 100644 --- a/tests/ui/transmutability/uninhabited.stderr +++ b/tests/ui/transmutability/uninhabited.stderr @@ -110,7 +110,29 @@ LL | | } LL | | }> | |__________^ required by this bound in `is_maybe_transmutable` -error: aborting due to 7 previous errors +error[E0277]: `Src` cannot be safely transmuted into `issue_126267::Error` + --> $DIR/uninhabited.rs:108:42 + | +LL | assert::is_maybe_transmutable::<Src, Dst>(); + | ^^^ the size of `Src` is smaller than the size of `issue_126267::Error` + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/uninhabited.rs:10:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this function +LL | where +LL | Dst: TransmuteFrom<Src, { + | ______________^ +LL | | Assume { +LL | | alignment: true, +LL | | lifetimes: true, +... | +LL | | } +LL | | }> + | |__________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to 8 previous errors Some errors have detailed explanations: E0080, E0277. For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs index 18cfb1c1f93..4b2ee344aa3 100644 --- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs @@ -3,7 +3,6 @@ #![feature(type_alias_impl_trait)] trait Trait<T> {} type Alias<'a, U> = impl Trait<U>; -//~^ ERROR unconstrained opaque type pub enum UninhabitedVariants { Tuple(Alias), diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr index cf366c55ea8..55df117d066 100644 --- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/bad-tait-no-substs.rs:9:11 + --> $DIR/bad-tait-no-substs.rs:8:11 | LL | Tuple(Alias), | ^^^^^ expected named lifetime parameter @@ -11,7 +11,7 @@ LL ~ Tuple(Alias<'a>), | error[E0107]: missing generics for type alias `Alias` - --> $DIR/bad-tait-no-substs.rs:9:11 + --> $DIR/bad-tait-no-substs.rs:8:11 | LL | Tuple(Alias), | ^^^^^ expected 1 generic argument @@ -27,7 +27,7 @@ LL | Tuple(Alias<U>), | +++ error[E0792]: non-defining opaque type use in defining scope - --> $DIR/bad-tait-no-substs.rs:9:11 + --> $DIR/bad-tait-no-substs.rs:8:11 | LL | Tuple(Alias), | ^^^^^ argument `'_` is not a generic parameter @@ -39,7 +39,7 @@ LL | type Alias<'a, U> = impl Trait<U>; | ^^^^^^^^^^^^^ error: item does not constrain `Alias::{opaque#0}`, but has it in its signature - --> $DIR/bad-tait-no-substs.rs:15:4 + --> $DIR/bad-tait-no-substs.rs:14:4 | LL | fn uwu(x: UninhabitedVariants) { | ^^^ @@ -51,22 +51,14 @@ note: this opaque type is in the signature LL | type Alias<'a, U> = impl Trait<U>; | ^^^^^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/bad-tait-no-substs.rs:5:21 - | -LL | type Alias<'a, U> = impl Trait<U>; - | ^^^^^^^^^^^^^ - | - = note: `Alias` must be used in combination with a concrete type within the same module - error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` not covered - --> $DIR/bad-tait-no-substs.rs:17:11 + --> $DIR/bad-tait-no-substs.rs:16:11 | LL | match x {} | ^ pattern `UninhabitedVariants::Tuple(_)` not covered | note: `UninhabitedVariants` defined here - --> $DIR/bad-tait-no-substs.rs:8:10 + --> $DIR/bad-tait-no-substs.rs:7:10 | LL | pub enum UninhabitedVariants { | ^^^^^^^^^^^^^^^^^^^ @@ -80,7 +72,7 @@ LL + UninhabitedVariants::Tuple(_) => todo!(), LL + } | -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0004, E0106, E0107, E0792. For more information about an error, try `rustc --explain E0004`. diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr index b7999a695e7..5b77bb6c2bc 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr +++ b/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr @@ -1,5 +1,5 @@ error: `Bar` is forbidden as the type of a const generic parameter - --> $DIR/const_generic_type.rs:8:24 + --> $DIR/const_generic_type.rs:7:24 | LL | async fn test<const N: crate::Bar>() { | ^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr index ec8a51b0818..8888f2d49df 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr +++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr @@ -1,5 +1,5 @@ error: `Bar` is forbidden as the type of a const generic parameter - --> $DIR/const_generic_type.rs:8:24 + --> $DIR/const_generic_type.rs:7:24 | LL | async fn test<const N: crate::Bar>() { | ^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | async fn test<const N: crate::Bar>() { = note: the only supported types are integers, `bool`, and `char` error: item does not constrain `Bar::{opaque#0}`, but has it in its signature - --> $DIR/const_generic_type.rs:8:10 + --> $DIR/const_generic_type.rs:7:10 | LL | async fn test<const N: crate::Bar>() { | ^^^^ @@ -20,7 +20,7 @@ LL | type Bar = impl std::fmt::Display; | ^^^^^^^^^^^^^^^^^^^^^^ error: item does not constrain `Bar::{opaque#0}`, but has it in its signature - --> $DIR/const_generic_type.rs:8:38 + --> $DIR/const_generic_type.rs:7:38 | LL | async fn test<const N: crate::Bar>() { | ______________________________________^ @@ -39,13 +39,5 @@ note: this opaque type is in the signature LL | type Bar = impl std::fmt::Display; | ^^^^^^^^^^^^^^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/const_generic_type.rs:5:12 - | -LL | type Bar = impl std::fmt::Display; - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `Bar` must be used in combination with a concrete type within the same module - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.rs b/tests/ui/type-alias-impl-trait/const_generic_type.rs index de493d04f81..7149370048b 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.rs +++ b/tests/ui/type-alias-impl-trait/const_generic_type.rs @@ -3,7 +3,6 @@ #![feature(type_alias_impl_trait)] type Bar = impl std::fmt::Display; -//[no_infer]~^ ERROR: unconstrained opaque type async fn test<const N: crate::Bar>() { //~^ ERROR: `Bar` is forbidden as the type of a const generic parameter diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs index 96c905ef3a9..fd06ea677c3 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs @@ -8,7 +8,6 @@ use std::future::Future; type FutNothing<'a> = impl 'a + Future<Output = ()>; -//~^ ERROR: unconstrained opaque type async fn operation(_: &mut ()) -> () { //~^ ERROR: concrete type differs from previous diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index 0c2772683a9..08ebc3208d7 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -1,5 +1,5 @@ error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signature - --> $DIR/hkl_forbidden4.rs:19:10 + --> $DIR/hkl_forbidden4.rs:18:10 | LL | async fn call<F>(_f: F) | ^^^^ @@ -12,7 +12,7 @@ LL | type FutNothing<'a> = impl 'a + Future<Output = ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signature - --> $DIR/hkl_forbidden4.rs:23:1 + --> $DIR/hkl_forbidden4.rs:22:1 | LL | / { LL | | @@ -27,16 +27,8 @@ note: this opaque type is in the signature LL | type FutNothing<'a> = impl 'a + Future<Output = ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/hkl_forbidden4.rs:10:23 - | -LL | type FutNothing<'a> = impl 'a + Future<Output = ()>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `FutNothing` must be used in combination with a concrete type within the same module - error[E0792]: expected generic lifetime parameter, found `'any` - --> $DIR/hkl_forbidden4.rs:15:5 + --> $DIR/hkl_forbidden4.rs:14:5 | LL | async fn operation(_: &mut ()) -> () { | - this generic parameter must be used with a generic lifetime parameter @@ -45,19 +37,19 @@ LL | call(operation).await | ^^^^^^^^^^^^^^^ error: concrete type differs from previous defining opaque type use - --> $DIR/hkl_forbidden4.rs:13:1 + --> $DIR/hkl_forbidden4.rs:12:1 | LL | async fn operation(_: &mut ()) -> () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `FutNothing<'_>`, got `{async fn body of operation()}` | note: previous use here - --> $DIR/hkl_forbidden4.rs:15:5 + --> $DIR/hkl_forbidden4.rs:14:5 | LL | call(operation).await | ^^^^^^^^^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'any` - --> $DIR/hkl_forbidden4.rs:23:1 + --> $DIR/hkl_forbidden4.rs:22:1 | LL | type FutNothing<'a> = impl 'a + Future<Output = ()>; | -- this generic parameter must be used with a generic lifetime parameter @@ -68,6 +60,6 @@ LL | | LL | | } | |_^ -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs index a7d824c5a6a..aaf2812532d 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs @@ -4,7 +4,6 @@ use std::fmt::Debug; type FooX = impl Debug; -//~^ ERROR unconstrained opaque type trait Foo<A> {} diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr index 9ccd9544896..969409ebc59 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr @@ -1,5 +1,5 @@ error: item does not constrain `FooX::{opaque#0}`, but has it in its signature - --> $DIR/nested-tait-inference3.rs:13:4 + --> $DIR/nested-tait-inference3.rs:12:4 | LL | fn foo() -> impl Foo<FooX> { | ^^^ @@ -11,13 +11,5 @@ note: this opaque type is in the signature LL | type FooX = impl Debug; | ^^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/nested-tait-inference3.rs:6:13 - | -LL | type FooX = impl Debug; - | ^^^^^^^^^^ - | - = note: `FooX` must be used in combination with a concrete type within the same module - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs index 3954672500b..41238c27351 100644 --- a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs +++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs @@ -5,7 +5,6 @@ mod foo { pub type Foo = impl Copy; - //~^ ERROR unconstrained opaque type // make compiler happy about using 'Foo' pub fn bar(x: Foo) -> Foo { diff --git a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr index d95a4a8a727..eed88c5df4f 100644 --- a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr +++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -1,5 +1,5 @@ error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/no_inferrable_concrete_type.rs:11:12 + --> $DIR/no_inferrable_concrete_type.rs:10:12 | LL | pub fn bar(x: Foo) -> Foo { | ^^^ @@ -11,13 +11,5 @@ note: this opaque type is in the signature LL | pub type Foo = impl Copy; | ^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/no_inferrable_concrete_type.rs:7:20 - | -LL | pub type Foo = impl Copy; - | ^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr index 98d71aa9a17..28f5d6728a9 100644 --- a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr +++ b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr @@ -1,8 +1,11 @@ -error: `Bar` cannot be used in patterns +error: opaque type `Bar` cannot be used in patterns --> $DIR/structural-match-no-leak.rs:16:9 | +LL | const LEAK_FREE: bar::Bar = bar::leak_free(); + | ------------------------- constant defined here +... LL | LEAK_FREE => (), - | ^^^^^^^^^ + | ^^^^^^^^^ opaque type can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/structural-match.stderr b/tests/ui/type-alias-impl-trait/structural-match.stderr index c7478b0a135..b06b31a060f 100644 --- a/tests/ui/type-alias-impl-trait/structural-match.stderr +++ b/tests/ui/type-alias-impl-trait/structural-match.stderr @@ -1,8 +1,11 @@ -error: `foo::Foo` cannot be used in patterns +error: opaque type `foo::Foo` cannot be used in patterns --> $DIR/structural-match.rs:18:9 | +LL | const VALUE: Foo = value(); + | ---------------- constant defined here +... LL | VALUE => (), - | ^^^^^ + | ^^^^^ opaque type can't be used in patterns error: aborting due to 1 previous error diff --git a/tests/ui/type/type-dependent-def-issue-49241.stderr b/tests/ui/type/type-dependent-def-issue-49241.stderr index cf372dc5968..4e55618e5cb 100644 --- a/tests/ui/type/type-dependent-def-issue-49241.stderr +++ b/tests/ui/type/type-dependent-def-issue-49241.stderr @@ -9,6 +9,12 @@ help: consider using `let` instead of `const` LL | let l: usize = v.count(); | ~~~ +note: erroneous constant encountered + --> $DIR/type-dependent-def-issue-49241.rs:4:18 + | +LL | let s: [u32; l] = v.into_iter().collect(); + | ^ + error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0435`. diff --git a/tests/ui/union/union-const-pat.stderr b/tests/ui/union/union-const-pat.stderr index e9dbb275944..59dc89c77a4 100644 --- a/tests/ui/union/union-const-pat.stderr +++ b/tests/ui/union/union-const-pat.stderr @@ -1,8 +1,11 @@ error: cannot use unions in constant patterns --> $DIR/union-const-pat.rs:10:9 | +LL | const C: U = U { a: 10 }; + | ---------- constant defined here +... LL | C => {} - | ^ + | ^ can't use a `union` here error: aborting due to 1 previous error diff --git a/triagebot.toml b/triagebot.toml index 47b96824098..4d6806711fb 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -996,7 +996,6 @@ warn_non_default_branch = true contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" users_on_vacation = [ "jyn514", - "oli-obk", ] [assign.adhoc_groups] |
