diff --git a/Cargo.lock b/Cargo.lock index c0d1337ef93a..1018eac13ff1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -284,6 +284,21 @@ dependencies = [ "nom", ] +[[package]] +name = "assert_cmd" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8" +dependencies = [ + "anstyle", + "bstr", + "doc-comment", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -1095,6 +1110,12 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + [[package]] name = "digest" version = "0.10.7" @@ -1197,6 +1218,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "either" version = "1.12.0" @@ -2337,6 +2364,33 @@ dependencies = [ "topological-sort", ] +[[package]] +name = "mdbook-trpl-listing" +version = "0.1.0" +dependencies = [ + "assert_cmd", + "clap", + "mdbook", + "pulldown-cmark 0.10.3", + "pulldown-cmark-to-cmark", + "serde_json", + "thiserror", + "toml 0.8.13", + "xmlparser", +] + +[[package]] +name = "mdbook-trpl-note" +version = "1.0.0" +dependencies = [ + "assert_cmd", + "clap", + "mdbook", + "pulldown-cmark 0.10.3", + "pulldown-cmark-to-cmark", + "serde_json", +] + [[package]] name = "measureme" version = "11.0.1" @@ -2949,6 +3003,33 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "predicates" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" +dependencies = [ + "anstyle", + "difflib", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" + +[[package]] +name = "predicates-tree" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +dependencies = [ + "predicates-core", + "termtree", +] + [[package]] name = "prettydiff" version = "0.6.4" @@ -3018,6 +3099,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" dependencies = [ "bitflags 2.5.0", + "getopts", "memchr", "pulldown-cmark-escape", "unicase", @@ -3029,6 +3111,15 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" +[[package]] +name = "pulldown-cmark-to-cmark" +version = "13.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f609795c8d835f79dcfcf768415b9fb57ef1b74891e99f86e73f43a7a257163b" +dependencies = [ + "pulldown-cmark 0.10.3", +] + [[package]] name = "punycode" version = "0.4.1" @@ -3276,6 +3367,8 @@ dependencies = [ "clap", "env_logger", "mdbook", + "mdbook-trpl-listing", + "mdbook-trpl-note", ] [[package]] @@ -5386,6 +5479,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + [[package]] name = "test" version = "0.0.0" @@ -5558,7 +5657,19 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.13", ] [[package]] @@ -5580,7 +5691,20 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.8", ] [[package]] @@ -5990,6 +6114,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -6302,6 +6435,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +dependencies = [ + "memchr", +] + [[package]] name = "writeable" version = "0.5.4" @@ -6319,6 +6461,12 @@ dependencies = [ "rustix", ] +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + [[package]] name = "xz2" version = "0.1.7" diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7e59b4492993..7a45d909d077 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -167,7 +167,7 @@ impl PathSegment { } } -/// The arguments of a path segment. +/// The generic arguments and associated item constraints of a path segment. /// /// E.g., `` as in `Foo` or `(A, B)` as in `Foo(A, B)`. #[derive(Clone, Encodable, Decodable, Debug)] @@ -221,14 +221,13 @@ pub struct AngleBracketedArgs { pub args: ThinVec, } -/// Either an argument for a parameter e.g., `'a`, `Vec`, `0`, -/// or a constraint on an associated item, e.g., `Item = String` or `Item: Bound`. +/// Either an argument for a generic parameter or a constraint on an associated item. #[derive(Clone, Encodable, Decodable, Debug)] pub enum AngleBracketedArg { - /// Argument for a generic parameter. + /// A generic argument for a generic parameter. Arg(GenericArg), - /// Constraint for an associated item. - Constraint(AssocConstraint), + /// A constraint on an associated item. + Constraint(AssocItemConstraint), } impl AngleBracketedArg { @@ -418,7 +417,7 @@ impl Default for WhereClause { /// A single predicate in a where-clause. #[derive(Clone, Encodable, Decodable, Debug)] pub enum WherePredicate { - /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`). + /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). BoundPredicate(WhereBoundPredicate), /// A lifetime predicate (e.g., `'a: 'b + 'c`). RegionPredicate(WhereRegionPredicate), @@ -2034,18 +2033,25 @@ impl UintTy { } } -/// A constraint on an associated type (e.g., `A = Bar` in `Foo` or -/// `A: TraitA + TraitB` in `Foo`). +/// A constraint on an associated item. +/// +/// ### Examples +/// +/// * the `A = Ty` and `B = Ty` in `Trait` +/// * the `G = Ty` in `Trait = Ty>` +/// * the `A: Bound` in `Trait` +/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy` +/// * the `C = { Ct }` in `Trait` (feature `associated_const_equality`) +/// * the `f(): Bound` in `Trait` (feature `return_type_notation`) #[derive(Clone, Encodable, Decodable, Debug)] -pub struct AssocConstraint { +pub struct AssocItemConstraint { pub id: NodeId, pub ident: Ident, pub gen_args: Option, - pub kind: AssocConstraintKind, + pub kind: AssocItemConstraintKind, pub span: Span, } -/// The kinds of an `AssocConstraint`. #[derive(Clone, Encodable, Decodable, Debug)] pub enum Term { Ty(P), @@ -2064,12 +2070,17 @@ impl From for Term { } } -/// The kinds of an `AssocConstraint`. +/// The kind of [associated item constraint][AssocItemConstraint]. #[derive(Clone, Encodable, Decodable, Debug)] -pub enum AssocConstraintKind { - /// E.g., `A = Bar`, `A = 3` in `Foo` where A is an associated type. +pub enum AssocItemConstraintKind { + /// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait`). + /// + /// Also known as an *associated item binding* (we *bind* an associated item to a term). + /// + /// Furthermore, associated type equality constraints can also be referred to as *associated type + /// bindings*. Similarly with associated const equality constraints and *associated const bindings*. Equality { term: Term }, - /// E.g. `A: TraitA + TraitB` in `Foo`. + /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait`). Bound { bounds: GenericBounds }, } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index ede0dd70b305..5c581c270e49 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -175,8 +175,8 @@ pub trait MutVisitor: Sized { noop_visit_lifetime(l, self); } - fn visit_constraint(&mut self, t: &mut AssocConstraint) { - noop_visit_constraint(t, self); + fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) { + noop_visit_assoc_item_constraint(c, self); } fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) { @@ -463,8 +463,8 @@ pub fn noop_flat_map_arm(mut arm: Arm, vis: &mut T) -> SmallVec<[ smallvec![arm] } -fn noop_visit_constraint( - AssocConstraint { id, ident, gen_args, kind, span }: &mut AssocConstraint, +fn noop_visit_assoc_item_constraint( + AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint, vis: &mut T, ) { vis.visit_id(id); @@ -473,11 +473,11 @@ fn noop_visit_constraint( vis.visit_generic_args(gen_args); } match kind { - AssocConstraintKind::Equality { term } => match term { + AssocItemConstraintKind::Equality { term } => match term { Term::Ty(ty) => vis.visit_ty(ty), Term::Const(c) => vis.visit_anon_const(c), }, - AssocConstraintKind::Bound { bounds } => visit_bounds(bounds, vis), + AssocItemConstraintKind::Bound { bounds } => visit_bounds(bounds, vis), } vis.visit_span(span); } @@ -607,7 +607,7 @@ fn noop_visit_angle_bracketed_parameter_data( let AngleBracketedArgs { args, span } = data; visit_thin_vec(args, |arg| match arg { AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg), - AngleBracketedArg::Constraint(constraint) => vis.visit_constraint(constraint), + AngleBracketedArg::Constraint(constraint) => vis.visit_assoc_item_constraint(constraint), }); vis.visit_span(span); } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 6382eb6861c7..b2f3b27c77e9 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -246,8 +246,11 @@ pub trait Visitor<'ast>: Sized { fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result { walk_generic_arg(self, generic_arg) } - fn visit_assoc_constraint(&mut self, constraint: &'ast AssocConstraint) -> Self::Result { - walk_assoc_constraint(self, constraint) + fn visit_assoc_item_constraint( + &mut self, + constraint: &'ast AssocItemConstraint, + ) -> Self::Result { + walk_assoc_item_constraint(self, constraint) } fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result { walk_attribute(self, attr) @@ -558,7 +561,7 @@ where match arg { AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)), AngleBracketedArg::Constraint(c) => { - try_visit!(visitor.visit_assoc_constraint(c)) + try_visit!(visitor.visit_assoc_item_constraint(c)) } } } @@ -582,18 +585,18 @@ where } } -pub fn walk_assoc_constraint<'a, V: Visitor<'a>>( +pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>( visitor: &mut V, - constraint: &'a AssocConstraint, + constraint: &'a AssocItemConstraint, ) -> V::Result { try_visit!(visitor.visit_ident(constraint.ident)); visit_opt!(visitor, visit_generic_args, &constraint.gen_args); match &constraint.kind { - AssocConstraintKind::Equality { term } => match term { + AssocItemConstraintKind::Equality { term } => match term { Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)), Term::Const(c) => try_visit!(visitor.visit_anon_const(c)), }, - AssocConstraintKind::Bound { bounds } => { + AssocItemConstraintKind::Bound { bounds } => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } } diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index eef6e8280afb..e821a08bf181 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -76,7 +76,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { StmtKind::Empty => {} StmtKind::MacCall(..) => panic!("shouldn't exist here"), } - ast_stmts = &ast_stmts[1..]; + ast_stmts = tail; } (self.arena.alloc_from_iter(stmts), expr) } diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index ed3046400f60..741a44eb0c52 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -325,10 +325,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { }); } - fn visit_assoc_type_binding(&mut self, type_binding: &'hir TypeBinding<'hir>) { - self.insert(type_binding.span, type_binding.hir_id, Node::TypeBinding(type_binding)); - self.with_parent(type_binding.hir_id, |this| { - intravisit::walk_assoc_type_binding(this, type_binding) + fn visit_assoc_item_constraint(&mut self, constraint: &'hir AssocItemConstraint<'hir>) { + self.insert(constraint.span, constraint.hir_id, Node::AssocItemConstraint(constraint)); + self.with_parent(constraint.hir_id, |this| { + intravisit::walk_assoc_item_constraint(this, constraint) }) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 278049d1347b..5a80fa803f84 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -967,24 +967,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() } } - /// Given an associated type constraint like one of these: - /// - /// ```ignore (illustrative) - /// T: Iterator - /// ^^^^^^^^^^^ - /// T: Iterator - /// ^^^^^^^^^^^^ - /// ``` - /// - /// returns a `hir::TypeBinding` representing `Item`. - #[instrument(level = "debug", skip(self))] - fn lower_assoc_ty_constraint( + /// Lower an associated item constraint. + #[instrument(level = "debug", skip_all)] + fn lower_assoc_item_constraint( &mut self, - constraint: &AssocConstraint, + constraint: &AssocItemConstraint, itctx: ImplTraitContext, - ) -> hir::TypeBinding<'hir> { - debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx); - // lower generic arguments of identifier in constraint + ) -> hir::AssocItemConstraint<'hir> { + debug!(?constraint, ?itctx); + // Lower the generic arguments for the associated item. let gen_args = if let Some(gen_args) = &constraint.gen_args { let gen_args_ctor = match gen_args { GenericArgs::AngleBracketed(data) => { @@ -1000,7 +991,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; GenericArgsCtor { args: Default::default(), - bindings: &[], + constraints: &[], parenthesized, span: data.inputs_span, } @@ -1030,7 +1021,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { err.emit(); GenericArgsCtor { args: Default::default(), - bindings: &[], + constraints: &[], parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation, span: data.span, } @@ -1052,14 +1043,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(hir::GenericArgs::none()) }; let kind = match &constraint.kind { - AssocConstraintKind::Equality { term } => { + AssocItemConstraintKind::Equality { term } => { let term = match term { Term::Ty(ty) => self.lower_ty(ty, itctx).into(), Term::Const(c) => self.lower_anon_const(c).into(), }; - hir::TypeBindingKind::Equality { term } + hir::AssocItemConstraintKind::Equality { term } } - AssocConstraintKind::Bound { bounds } => { + AssocItemConstraintKind::Bound { bounds } => { // Disallow ATB in dyn types if self.is_in_dyn_type { let suggestion = match itctx { @@ -1083,18 +1074,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }); let err_ty = &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar))); - hir::TypeBindingKind::Equality { term: err_ty.into() } + hir::AssocItemConstraintKind::Equality { term: err_ty.into() } } else { - // Desugar `AssocTy: Bounds` into a type binding where the + // Desugar `AssocTy: Bounds` into an assoc type binding where the // later desugars into a trait predicate. let bounds = self.lower_param_bounds(bounds, itctx); - hir::TypeBindingKind::Constraint { bounds } + hir::AssocItemConstraintKind::Bound { bounds } } } }; - hir::TypeBinding { + hir::AssocItemConstraint { hir_id: self.lower_node_id(constraint.id), ident: self.lower_ident(constraint.ident), gen_args, @@ -2014,7 +2005,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let bound_args = self.arena.alloc(hir::GenericArgs { args: &[], - bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)], + constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)], parenthesized: hir::GenericArgsParentheses::No, span_ext: DUMMY_SP, }); @@ -2587,10 +2578,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } -/// Helper struct for delayed construction of GenericArgs. +/// Helper struct for the delayed construction of [`hir::GenericArgs`]. struct GenericArgsCtor<'hir> { args: SmallVec<[hir::GenericArg<'hir>; 4]>, - bindings: &'hir [hir::TypeBinding<'hir>], + constraints: &'hir [hir::AssocItemConstraint<'hir>], parenthesized: hir::GenericArgsParentheses, span: Span, } @@ -2670,14 +2661,14 @@ impl<'hir> GenericArgsCtor<'hir> { fn is_empty(&self) -> bool { self.args.is_empty() - && self.bindings.is_empty() + && self.constraints.is_empty() && self.parenthesized == hir::GenericArgsParentheses::No } fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> { let ga = hir::GenericArgs { args: this.arena.alloc_from_iter(self.args), - bindings: self.bindings, + constraints: self.constraints, parenthesized: self.parenthesized, span_ext: this.lower_span(self.span), }; diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 7679424dceb9..9d38e1e67847 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -281,7 +281,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ( GenericArgsCtor { args: Default::default(), - bindings: &[], + constraints: &[], parenthesized: hir::GenericArgsParentheses::No, span: path_span.shrink_to_hi(), }, @@ -390,13 +390,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { AngleBracketedArg::Constraint(_) => None, }) .collect(); - let bindings = self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg { - AngleBracketedArg::Constraint(c) => Some(self.lower_assoc_ty_constraint(c, itctx)), - AngleBracketedArg::Arg(_) => None, - })); + let constraints = + self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg { + AngleBracketedArg::Constraint(c) => { + Some(self.lower_assoc_item_constraint(c, itctx)) + } + AngleBracketedArg::Arg(_) => None, + })); let ctor = GenericArgsCtor { args, - bindings, + constraints, parenthesized: hir::GenericArgsParentheses::No, span: data.span, }; @@ -454,12 +457,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Some(bound_modifier_allowed_features), ); } - let binding = self.assoc_ty_binding(sym::Output, output_span, output_ty); + let constraint = self.assoc_ty_binding(sym::Output, output_span, output_ty); ( GenericArgsCtor { args, - bindings: arena_vec![self; binding], + constraints: arena_vec![self; constraint], parenthesized: hir::GenericArgsParentheses::ParenSugar, span: data.inputs_span, }, @@ -467,24 +470,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } - /// An associated type binding `$assoc_ty_name = $ty`. + /// An associated type binding (i.e., associated type equality constraint). pub(crate) fn assoc_ty_binding( &mut self, assoc_ty_name: rustc_span::Symbol, span: Span, ty: &'hir hir::Ty<'hir>, - ) -> hir::TypeBinding<'hir> { + ) -> hir::AssocItemConstraint<'hir> { let ident = Ident::with_dummy_span(assoc_ty_name); - let kind = hir::TypeBindingKind::Equality { term: ty.into() }; + let kind = hir::AssocItemConstraintKind::Equality { term: ty.into() }; let args = arena_vec![self;]; - let bindings = arena_vec![self;]; + let constraints = arena_vec![self;]; let gen_args = self.arena.alloc(hir::GenericArgs { args, - bindings, + constraints, parenthesized: hir::GenericArgsParentheses::No, span_ext: DUMMY_SP, }); - hir::TypeBinding { + hir::AssocItemConstraint { hir_id: self.next_id(), gen_args, span: self.lower_span(span), diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 598a3ec2d3c3..435b0b6a9565 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -671,7 +671,7 @@ impl<'a> AstValidator<'a> { let constraint_sugg = data.args.iter().filter_map(|a| match a { AngleBracketedArg::Arg(_) => None, AngleBracketedArg::Constraint(c) => { - Some(pprust::to_string(|s| s.print_assoc_constraint(c))) + Some(pprust::to_string(|s| s.print_assoc_item_constraint(c))) } }); format!( @@ -1199,11 +1199,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> { for arg in &data.args { match arg { AngleBracketedArg::Arg(arg) => self.visit_generic_arg(arg), - // Type bindings such as `Item = impl Debug` in `Iterator` - // are allowed to contain nested `impl Trait`. + // Associated type bindings such as `Item = impl Debug` in + // `Iterator` are allowed to contain nested `impl Trait`. AngleBracketedArg::Constraint(constraint) => { self.with_impl_trait(None, |this| { - this.visit_assoc_constraint(constraint); + this.visit_assoc_item_constraint(constraint); }); } } @@ -1363,7 +1363,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - // The lowered form of parenthesized generic args contains a type binding. + // The lowered form of parenthesized generic args contains an associated type binding. Some(ast::GenericArgs::Parenthesized(args)) => { self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation { span: args.span, @@ -1589,11 +1589,13 @@ fn deny_equality_constraints( let len = assoc_path.segments.len() - 1; let gen_args = args.as_deref().cloned(); // Build ``. - let arg = AngleBracketedArg::Constraint(AssocConstraint { + let arg = AngleBracketedArg::Constraint(AssocItemConstraint { id: rustc_ast::node_id::DUMMY_NODE_ID, ident: *ident, gen_args, - kind: AssocConstraintKind::Equality { term: predicate.rhs_ty.clone().into() }, + kind: AssocItemConstraintKind::Equality { + term: predicate.rhs_ty.clone().into(), + }, span: ident.span, }); // Add `` to `Foo`. diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index a522f04b21db..a9dca9b6a293 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -1,6 +1,6 @@ use rustc_ast as ast; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; -use rustc_ast::{attr, AssocConstraint, AssocConstraintKind, NodeId}; +use rustc_ast::{attr, AssocItemConstraint, AssocItemConstraintKind, NodeId}; use rustc_ast::{token, PatKind}; use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP}; use rustc_session::parse::{feature_err, feature_err_issue, feature_warn}; @@ -344,7 +344,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { for predicate in &g.where_clause.predicates { match predicate { ast::WherePredicate::BoundPredicate(bound_pred) => { - // A type binding, eg `for<'c> Foo: Send+Clone+'c` + // A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params); } _ => {} @@ -445,21 +445,21 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_fn(self, fn_kind) } - fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) { - if let AssocConstraintKind::Bound { .. } = constraint.kind { - if let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref() - && args.inputs.is_empty() - && matches!(args.output, ast::FnRetTy::Default(..)) - { - gate!( - &self, - return_type_notation, - constraint.span, - "return type notation is experimental" - ); - } + fn visit_assoc_item_constraint(&mut self, constraint: &'a AssocItemConstraint) { + if let AssocItemConstraintKind::Bound { .. } = constraint.kind + && let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref() + && args.inputs.is_empty() + && let ast::FnRetTy::Default(..) = args.output + { + gate!( + &self, + return_type_notation, + constraint.span, + "return type notation is experimental" + ); } - visit::walk_assoc_constraint(self, constraint) + + visit::walk_assoc_item_constraint(self, constraint) } fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs index 2128acba0bab..c61640de6f79 100644 --- a/compiler/rustc_ast_passes/src/node_count.rs +++ b/compiler/rustc_ast_passes/src/node_count.rs @@ -119,9 +119,9 @@ impl<'ast> Visitor<'ast> for NodeCounter { self.count += 1; walk_generic_args(self, generic_args) } - fn visit_assoc_constraint(&mut self, constraint: &AssocConstraint) { + fn visit_assoc_item_constraint(&mut self, constraint: &AssocItemConstraint) { self.count += 1; - walk_assoc_constraint(self, constraint) + walk_assoc_item_constraint(self, constraint) } fn visit_attribute(&mut self, _attr: &Attribute) { self.count += 1; diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index f02fe4cf0a72..4c29ca0ca465 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1045,7 +1045,7 @@ impl<'a> PrintState<'a> for State<'a> { self.word("<"); self.commasep(Inconsistent, &data.args, |s, arg| match arg { ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a), - ast::AngleBracketedArg::Constraint(c) => s.print_assoc_constraint(c), + ast::AngleBracketedArg::Constraint(c) => s.print_assoc_item_constraint(c), }); self.word(">") } @@ -1097,21 +1097,21 @@ impl<'a> State<'a> { } } - pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocConstraint) { + pub fn print_assoc_item_constraint(&mut self, constraint: &ast::AssocItemConstraint) { self.print_ident(constraint.ident); if let Some(args) = constraint.gen_args.as_ref() { self.print_generic_args(args, false) } self.space(); match &constraint.kind { - ast::AssocConstraintKind::Equality { term } => { + ast::AssocItemConstraintKind::Equality { term } => { self.word_space("="); match term { Term::Ty(ty) => self.print_type(ty), Term::Const(c) => self.print_expr_anon_const(c, &[]), } } - ast::AssocConstraintKind::Bound { bounds } => { + ast::AssocItemConstraintKind::Bound { bounds } => { if !bounds.is_empty() { self.word_nbsp(":"); self.print_type_bounds(bounds); diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2f1b2ce9c4c7..821a90366547 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -399,8 +399,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } let hir = self.infcx.tcx.hir(); - if let Some(body_id) = hir.maybe_body_owned_by(self.mir_def_id()) { - let expr = hir.body(body_id).value; + if let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) { + let expr = body.value; let place = &self.move_data.move_paths[mpi].place; let span = place.as_local().map(|local| self.body.local_decls[local].source_info.span); let mut finder = ExpressionFinder { @@ -556,11 +556,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // We use the statements were the binding was initialized, and inspect the HIR to look // for the branching codepaths that aren't covered, to point at them. let map = self.infcx.tcx.hir(); - let body_id = map.body_owned_by(self.mir_def_id()); - let body = map.body(body_id); + let body = map.body_owned_by(self.mir_def_id()); let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] }; - visitor.visit_body(body); + visitor.visit_body(&body); let mut show_assign_sugg = false; let isnt_initialized = if let InitializationRequiringAction::PartialAssignment @@ -665,7 +664,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } let mut visitor = LetVisitor { decl_span, sugg_span: None }; - visitor.visit_body(body); + visitor.visit_body(&body); if let Some(span) = visitor.sugg_span { self.suggest_assign_value(&mut err, moved_place, span); } @@ -1348,7 +1347,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return; }; // Try to find predicates on *generic params* that would allow copying `ty` - let ocx = ObligationCtxt::new(self.infcx); + let ocx = ObligationCtxt::new_with_diagnostics(self.infcx); let cause = ObligationCause::misc(span, self.mir_def_id()); ocx.register_bound(cause, self.param_env, ty, def_id); @@ -1362,7 +1361,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { match *predicate.self_ty().kind() { ty::Param(param_ty) => Ok(( generics.type_param(param_ty, tcx), - predicate.trait_ref.print_only_trait_path().to_string(), + predicate.trait_ref.print_trait_sugared().to_string(), )), _ => Err(()), } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 88172c62a3b2..1eb67ea367c2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -11,7 +11,7 @@ use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::CoroutineKind; use rustc_index::IndexSlice; use rustc_infer::infer::BoundRegionConversionTime; -use rustc_infer::traits::{FulfillmentErrorCode, SelectionError}; +use rustc_infer::traits::SelectionError; use rustc_middle::bug; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ @@ -29,7 +29,9 @@ use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP}; use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions; +use rustc_trait_selection::traits::{ + type_known_to_meet_bound_modulo_regions, FulfillmentErrorCode, +}; use crate::fluent_generated as fluent; diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 79b485085852..df1a1411cf5f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -6,7 +6,6 @@ use hir::{ExprKind, Param}; use rustc_errors::{Applicability, Diag}; use rustc_hir::intravisit::Visitor; use rustc_hir::{self as hir, BindingMode, ByRef, Node}; -use rustc_infer::traits; use rustc_middle::bug; use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem}; use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt, Upcast}; @@ -18,6 +17,7 @@ use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, BytePos, DesugaringKind, Span}; use rustc_target::abi::FieldIdx; use rustc_trait_selection::infer::InferCtxtExt; +use rustc_trait_selection::traits; use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; use crate::diagnostics::BorrowedContentSource; @@ -647,8 +647,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let hir_map = self.infcx.tcx.hir(); let def_id = self.body.source.def_id(); let Some(local_def_id) = def_id.as_local() else { return }; - let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) else { return }; - let body = self.infcx.tcx.hir().body(body_id); + let Some(body) = hir_map.maybe_body_owned_by(local_def_id) else { return }; let mut v = SuggestIndexOperatorAlternativeVisitor { assign_span: span, @@ -656,7 +655,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ty, suggested: false, }; - v.visit_body(body); + v.visit_body(&body); if !v.suggested { err.help(format!( "to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API", @@ -746,9 +745,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)` let def_id = self.body.source.def_id(); if let Some(local_def_id) = def_id.as_local() - && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) - && let body = self.infcx.tcx.hir().body(body_id) - && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(body).break_value() + && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) + && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(&body).break_value() && let node = self.infcx.tcx.hir_node(hir_id) && let hir::Node::LetStmt(hir::LetStmt { pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, @@ -867,8 +865,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } } - if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id()) - && let Block(block, _) = hir_map.body(body_id).value.kind + if let Some(body) = hir_map.maybe_body_owned_by(self.mir_def_id()) + && let Block(block, _) = body.value.kind { // `span` corresponds to the expression being iterated, find the `for`-loop desugared // expression with that span in order to identify potential fixes when encountering a @@ -1189,10 +1187,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { Some((false, err_label_span, message, _)) => { let def_id = self.body.source.def_id(); let hir_id = if let Some(local_def_id) = def_id.as_local() - && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) + && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) { - let body = self.infcx.tcx.hir().body(body_id); - BindingFinder { span: err_label_span }.visit_body(body).break_value() + BindingFinder { span: err_label_span }.visit_body(&body).break_value() } else { None }; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index e11e4a7247c2..15a8764aab3c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1183,8 +1183,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) { let map = self.infcx.tcx.hir(); - let body_id = map.body_owned_by(self.mir_def_id()); - let expr = &map.body(body_id).value.peel_blocks(); + let body = map.body_owned_by(self.mir_def_id()); + let expr = &body.value.peel_blocks(); let mut closure_span = None::; match expr.kind { hir::ExprKind::MethodCall(.., args, _) => { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index c2db64e77025..2cf548e28b18 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -12,7 +12,7 @@ use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; use rustc_middle::{bug, span_bug}; -use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use crate::{universal_regions::DefiningTy, MirBorrowckCtxt}; @@ -843,13 +843,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { }) = opaque_ty.kind && let Some(segment) = trait_ref.trait_ref.path.segments.last() && let Some(args) = segment.args - && let [ - hir::TypeBinding { - ident: Ident { name: sym::Output, .. }, - kind: hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) }, - .. - }, - ] = args.bindings + && let [constraint] = args.constraints + && constraint.ident.name == sym::Output + && let Some(ty) = constraint.ty() { ty } else { diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 49f50babdcb9..5d7ce548469f 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -125,8 +125,8 @@ pub(crate) fn compute_regions<'cx, 'tcx>( placeholder_indices, placeholder_index_to_region: _, liveness_constraints, - outlives_constraints, - member_constraints, + mut outlives_constraints, + mut member_constraints, universe_causes, type_tests, } = constraints; @@ -144,6 +144,16 @@ pub(crate) fn compute_regions<'cx, 'tcx>( &universal_region_relations, ); + if let Some(guar) = universal_regions.tainted_by_errors() { + // Suppress unhelpful extra errors in `infer_opaque_types` by clearing out all + // outlives bounds that we may end up checking. + outlives_constraints = Default::default(); + member_constraints = Default::default(); + + // Also taint the entire scope. + infcx.set_tainted_by_errors(guar); + } + let mut regioncx = RegionInferenceContext::new( infcx, var_origins, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index f601a9d70739..06adb686ed48 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -340,7 +340,7 @@ fn check_opaque_type_well_formed<'tcx>( .with_next_trait_solver(next_trait_solver) .with_opaque_type_inference(parent_def_id) .build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let identity_args = GenericArgs::identity_for_item(tcx, def_id); // Require that the hidden type actually fulfills all the bounds of the opaque type, even without diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index b23ad2e15842..0cb4b15b1271 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -10,9 +10,9 @@ use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_span::Span; -use rustc_trait_selection::solve::deeply_normalize; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; +use rustc_trait_selection::traits::ScrubbedTraitError; use crate::{ constraints::OutlivesConstraint, @@ -282,11 +282,12 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { ) -> Ty<'tcx> { let result = CustomTypeOp::new( |ocx| { - deeply_normalize( - ocx.infcx.at(&ObligationCause::dummy_with_span(self.span), self.param_env), + ocx.deeply_normalize( + &ObligationCause::dummy_with_span(self.span), + self.param_env, ty, ) - .map_err(|_| NoSolution) + .map_err(|_: Vec>| NoSolution) }, "normalize type outlives obligation", ) diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index 38ec9f7678eb..8b863efad6ca 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -14,7 +14,6 @@ use std::rc::Rc; use crate::{ constraints::OutlivesConstraintSet, facts::{AllFacts, AllFactsExt}, - location::LocationTable, region_infer::values::LivenessValues, universal_regions::UniversalRegions, }; @@ -39,7 +38,6 @@ pub(super) fn generate<'mir, 'tcx>( elements: &Rc, flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, move_data: &MoveData<'tcx>, - location_table: &LocationTable, use_polonius: bool, ) { debug!("liveness::generate"); @@ -53,11 +51,9 @@ pub(super) fn generate<'mir, 'tcx>( compute_relevant_live_locals(typeck.tcx(), &free_regions, body); let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx()); - let polonius_drop_used = facts_enabled.then(|| { - let mut drop_used = Vec::new(); - polonius::populate_access_facts(typeck, body, location_table, move_data, &mut drop_used); - drop_used - }); + if facts_enabled { + polonius::populate_access_facts(typeck, body, move_data); + }; trace::trace( typeck, @@ -67,7 +63,6 @@ pub(super) fn generate<'mir, 'tcx>( move_data, relevant_live_locals, boring_locals, - polonius_drop_used, ); // Mark regions that should be live where they appear within rvalues or within a call: like diff --git a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs index ccfa9f12ef45..d8f03a07a63c 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs @@ -85,13 +85,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UseFactsExtractor<'a, 'tcx> { pub(super) fn populate_access_facts<'a, 'tcx>( typeck: &mut TypeChecker<'a, 'tcx>, body: &Body<'tcx>, - location_table: &LocationTable, move_data: &MoveData<'tcx>, - //FIXME: this is not mutated, but expected to be modified as - // out param, bug? - dropped_at: &mut Vec<(Local, Location)>, ) { debug!("populate_access_facts()"); + let location_table = typeck.borrowck_context.location_table; if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() { let mut extractor = UseFactsExtractor { @@ -104,10 +101,6 @@ pub(super) fn populate_access_facts<'a, 'tcx>( }; extractor.visit_body(body); - facts.var_dropped_at.extend( - dropped_at.iter().map(|&(local, location)| (local, location_table.mid_index(location))), - ); - for (local, local_decl) in body.local_decls.iter_enumerated() { debug!( "add use_of_var_derefs_origin facts - local={:?}, type={:?}", diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 6cc0e67c0f80..50843c602cc8 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -16,6 +16,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex}; use rustc_mir_dataflow::ResultsCursor; +use crate::location::RichLocation; use crate::{ region_infer::values::{self, LiveLoans}, type_check::liveness::local_use_map::LocalUseMap, @@ -46,7 +47,6 @@ pub(super) fn trace<'mir, 'tcx>( move_data: &MoveData<'tcx>, relevant_live_locals: Vec, boring_locals: Vec, - polonius_drop_used: Option>, ) { let local_use_map = &LocalUseMap::build(&relevant_live_locals, elements, body); @@ -93,9 +93,7 @@ pub(super) fn trace<'mir, 'tcx>( let mut results = LivenessResults::new(cx); - if let Some(drop_used) = polonius_drop_used { - results.add_extra_drop_facts(drop_used, relevant_live_locals.iter().copied().collect()) - } + results.add_extra_drop_facts(&relevant_live_locals); results.compute_for_all_locals(relevant_live_locals); @@ -218,21 +216,38 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> { /// /// Add facts for all locals with free regions, since regions may outlive /// the function body only at certain nodes in the CFG. - fn add_extra_drop_facts( - &mut self, - drop_used: Vec<(Local, Location)>, - relevant_live_locals: FxIndexSet, - ) { + fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) -> Option<()> { + let drop_used = self + .cx + .typeck + .borrowck_context + .all_facts + .as_ref() + .map(|facts| facts.var_dropped_at.clone())?; + + let relevant_live_locals: FxIndexSet<_> = relevant_live_locals.iter().copied().collect(); + let locations = IntervalSet::new(self.cx.elements.num_points()); - for (local, location) in drop_used { + for (local, location_index) in drop_used { if !relevant_live_locals.contains(&local) { let local_ty = self.cx.body.local_decls[local].ty; if local_ty.has_free_regions() { + let location = match self + .cx + .typeck + .borrowck_context + .location_table + .to_location(location_index) + { + RichLocation::Start(l) => l, + RichLocation::Mid(l) => l, + }; self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations); } } } + Some(()) } /// Clear the value of fields that are "per local variable". diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 4e46a0c62c7c..291d2782c32c 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -27,8 +27,9 @@ use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{ - self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic, - OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, + self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt, + Dynamic, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, + UserTypeAnnotationIndex, }; use rustc_middle::ty::{GenericArgsRef, UserArgs}; use rustc_middle::{bug, span_bug}; @@ -188,15 +189,7 @@ pub(crate) fn type_check<'mir, 'tcx>( checker.equate_inputs_and_outputs(body, universal_regions, &normalized_inputs_and_output); checker.check_signature_annotation(body); - liveness::generate( - &mut checker, - body, - elements, - flow_inits, - move_data, - location_table, - use_polonius, - ); + liveness::generate(&mut checker, body, elements, flow_inits, move_data, use_polonius); translate_outlives_facts(&mut checker); let opaque_type_values = infcx.take_opaque_types(); diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index f8123535e2d0..9f5fb59e46c5 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -29,7 +29,8 @@ use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, T use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{kw, sym}; -use rustc_span::Symbol; +use rustc_span::{ErrorGuaranteed, Symbol}; +use std::cell::Cell; use std::iter; use crate::renumber::RegionCtxt; @@ -186,6 +187,10 @@ struct UniversalRegionIndices<'tcx> { /// The vid assigned to `'static`. Used only for diagnostics. pub fr_static: RegionVid, + + /// Whether we've encountered an error region. If we have, cancel all + /// outlives errors, as they are likely bogus. + pub tainted_by_errors: Cell>, } #[derive(Debug, PartialEq)] @@ -408,6 +413,10 @@ impl<'tcx> UniversalRegions<'tcx> { } } } + + pub fn tainted_by_errors(&self) -> Option { + self.indices.tainted_by_errors.get() + } } struct UniversalRegionsBuilder<'cx, 'tcx> { @@ -663,7 +672,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var())); - UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), fr_static } + UniversalRegionIndices { + indices: global_mapping.chain(arg_mapping).collect(), + fr_static, + tainted_by_errors: Cell::new(None), + } } fn compute_inputs_and_output( @@ -868,7 +881,8 @@ impl<'tcx> UniversalRegionIndices<'tcx> { pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { if let ty::ReVar(..) = *r { r.as_var() - } else if r.is_error() { + } else if let ty::ReError(guar) = *r { + self.tainted_by_errors.set(Some(guar)); // We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the // `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if // errors are being emitted and 2) it leaves the happy path unaffected. diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 394c810176ab..dcafac21bc74 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -288,6 +288,29 @@ fn produce_final_output_artifacts( } } + if sess.opts.json_artifact_notifications { + if codegen_results.modules.len() == 1 { + codegen_results.modules[0].for_each_output(|_path, ty| { + if sess.opts.output_types.contains_key(&ty) { + let descr = ty.shorthand(); + // for single cgu file is renamed to drop cgu specific suffix + // so we regenerate it the same way + let path = crate_output.path(ty); + sess.dcx().emit_artifact_notification(path.as_path(), descr); + } + }); + } else { + for module in &codegen_results.modules { + module.for_each_output(|path, ty| { + if sess.opts.output_types.contains_key(&ty) { + let descr = ty.shorthand(); + sess.dcx().emit_artifact_notification(&path, descr); + } + }); + } + } + } + // We leave the following files around by default: // - #crate#.o // - #crate#.crate.metadata.o diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 2155cabe171c..a88d50cb4340 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeM use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, CoroutineArgsExt, Ty, TypeVisitableExt}; use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; use rustc_target::abi::{ self, Abi, Align, FieldsShape, Float, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs index 12a846a49ec1..584d033d6bdd 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs @@ -118,7 +118,7 @@ pub mod mcdc { #[derive(Clone, Copy, Debug, Default)] pub struct DecisionParameters { bitmap_idx: u32, - conditions_num: u16, + num_conditions: u16, } // ConditionId in llvm is `unsigned int` at 18 while `int16_t` at [19](https://github.com/llvm/llvm-project/pull/81257) @@ -177,8 +177,9 @@ pub mod mcdc { } impl From for DecisionParameters { - fn from(value: DecisionInfo) -> Self { - Self { bitmap_idx: value.bitmap_idx, conditions_num: value.conditions_num } + fn from(info: DecisionInfo) -> Self { + let DecisionInfo { bitmap_idx, num_conditions } = info; + Self { bitmap_idx, num_conditions } } } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 10d3c0d0e744..a543ccbde0ed 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -31,7 +31,8 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{ - self, AdtKind, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, Visibility, + self, AdtKind, CoroutineArgsExt, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, + Visibility, }; use rustc_session::config::{self, DebugInfo, Lto}; use rustc_span::symbol::Symbol; 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 4edef14422e5..12f98eef97d4 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 @@ -12,7 +12,7 @@ use rustc_middle::{ ty::{ self, layout::{LayoutOf, TyAndLayout}, - AdtDef, CoroutineArgs, Ty, + AdtDef, CoroutineArgs, CoroutineArgsExt, Ty, }, }; use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants}; 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 bacd74f430f7..2b00bb14593e 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -10,7 +10,7 @@ use rustc_middle::{ ty::{ self, layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout}, - AdtDef, CoroutineArgs, Ty, VariantDef, + AdtDef, CoroutineArgs, CoroutineArgsExt, Ty, VariantDef, }, }; use rustc_span::Symbol; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 3d2ce550b238..39bbf87bea7b 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -482,8 +482,60 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { } _ if name.as_str().starts_with("simd_") => { + // Unpack non-power-of-2 #[repr(packed, simd)] arguments. + // This gives them the expected layout of a regular #[repr(simd)] vector. + let mut loaded_args = Vec::new(); + for (ty, arg) in arg_tys.iter().zip(args) { + loaded_args.push( + // #[repr(packed, simd)] vectors are passed like arrays (as references, + // with reduced alignment and no padding) rather than as immediates. + // We can use a vector load to fix the layout and turn the argument + // into an immediate. + if ty.is_simd() + && let OperandValue::Ref(place) = arg.val + { + let (size, elem_ty) = ty.simd_size_and_type(self.tcx()); + let elem_ll_ty = match elem_ty.kind() { + ty::Float(f) => self.type_float_from_ty(*f), + ty::Int(i) => self.type_int_from_ty(*i), + ty::Uint(u) => self.type_uint_from_ty(*u), + ty::RawPtr(_, _) => self.type_ptr(), + _ => unreachable!(), + }; + let loaded = + self.load_from_place(self.type_vector(elem_ll_ty, size), place); + OperandRef::from_immediate_or_packed_pair(self, loaded, arg.layout) + } else { + *arg + }, + ); + } + + let llret_ty = if ret_ty.is_simd() + && let abi::Abi::Aggregate { .. } = self.layout_of(ret_ty).layout.abi + { + let (size, elem_ty) = ret_ty.simd_size_and_type(self.tcx()); + let elem_ll_ty = match elem_ty.kind() { + ty::Float(f) => self.type_float_from_ty(*f), + ty::Int(i) => self.type_int_from_ty(*i), + ty::Uint(u) => self.type_uint_from_ty(*u), + ty::RawPtr(_, _) => self.type_ptr(), + _ => unreachable!(), + }; + self.type_vector(elem_ll_ty, size) + } else { + llret_ty + }; + match generic_simd_intrinsic( - self, name, callee_ty, fn_args, args, ret_ty, llret_ty, span, + self, + name, + callee_ty, + fn_args, + &loaded_args, + ret_ty, + llret_ty, + span, ) { Ok(llval) => llval, Err(()) => return Ok(()), diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 011d8ab57c75..7be941ed7498 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -4,7 +4,7 @@ use rustc_codegen_ssa::traits::*; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; -use rustc_middle::ty::{self, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, CoroutineArgsExt, Ty, TypeVisitableExt}; use rustc_target::abi::{Abi, Align, FieldsShape}; use rustc_target::abi::{Float, Int, Pointer}; use rustc_target::abi::{Scalar, Size, Variants}; diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index d57f4ddf8aae..dec87db0fc5c 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -717,6 +717,29 @@ fn produce_final_output_artifacts( } } + if sess.opts.json_artifact_notifications { + if compiled_modules.modules.len() == 1 { + compiled_modules.modules[0].for_each_output(|_path, ty| { + if sess.opts.output_types.contains_key(&ty) { + let descr = ty.shorthand(); + // for single cgu file is renamed to drop cgu specific suffix + // so we regenerate it the same way + let path = crate_output.path(ty); + sess.dcx().emit_artifact_notification(path.as_path(), descr); + } + }); + } else { + for module in &compiled_modules.modules { + module.for_each_output(|path, ty| { + if sess.opts.output_types.contains_key(&ty) { + let descr = ty.shorthand(); + sess.dcx().emit_artifact_notification(&path, descr); + } + }); + } + } + } + // We leave the following files around by default: // - #crate#.o // - #crate#.crate.metadata.o diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 07473ee476ba..2360cce55a99 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -263,7 +263,7 @@ fn push_debuginfo_type_name<'tcx>( let ExistentialProjection { def_id: item_def_id, term, .. } = tcx.instantiate_bound_regions_with_erased(bound); // FIXME(associated_const_equality): allow for consts here - (item_def_id, term.ty().unwrap()) + (item_def_id, term.expect_type()) }) .collect(); diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 1668104d7e22..3b1921d40e6b 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -106,6 +106,24 @@ pub struct CompiledModule { pub llvm_ir: Option, // --emit=llvm-ir, llvm-bc is in bytecode } +impl CompiledModule { + /// Call `emit` function with every artifact type currently compiled + pub fn for_each_output(&self, mut emit: impl FnMut(&Path, OutputType)) { + if let Some(path) = self.object.as_deref() { + emit(path, OutputType::Object); + } + if let Some(path) = self.bytecode.as_deref() { + emit(path, OutputType::Bitcode); + } + if let Some(path) = self.llvm_ir.as_deref() { + emit(path, OutputType::LlvmAssembly); + } + if let Some(path) = self.assembly.as_deref() { + emit(path, OutputType::Assembly); + } + } +} + pub struct CachedModuleCodegen { pub name: String, pub source: WorkProduct, diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 5fbf5b41109f..9e01c59a96f9 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -735,7 +735,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // which path expressions are getting called on and which path expressions are only used // as function pointers. This is required for correctness. let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args); let cause = ObligationCause::new( diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 90b622cae656..feab5b929acb 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -113,7 +113,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { if let Some(generics) = tcx.hir_node_by_def_id(caller).generics() { let constraint = with_no_trimmed_paths!(format!( "~const {}", - trait_ref.print_only_trait_path() + trait_ref.print_trait_sugared(), )); suggest_constraining_type_param( tcx, diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index 224d17dbf52b..67fbf9642bf0 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -3,7 +3,7 @@ use rustc_middle::mir; use rustc_middle::span_bug; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt}; -use rustc_middle::ty::{self, ScalarInt, Ty}; +use rustc_middle::ty::{self, CoroutineArgsExt, ScalarInt, Ty}; use rustc_target::abi::{self, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; use tracing::{instrument, trace}; diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index 30e240cf85b8..d1d2de670b82 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -93,7 +93,7 @@ fn dominators_impl(graph: &G) -> Inner { // These are all done here rather than through one of the 'standard' // graph traversals to help make this fast. 'recurse: while let Some(frame) = stack.last_mut() { - while let Some(successor) = frame.iter.next() { + for successor in frame.iter.by_ref() { if real_to_pre_order[successor].is_none() { let pre_order_idx = pre_order_to_real.push(successor); real_to_pre_order[successor] = Some(pre_order_idx); diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index 78d05a6e1951..6fca57d32f77 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -48,7 +48,7 @@ fn post_order_walk( let node = frame.node; visited[node] = true; - while let Some(successor) = frame.iter.next() { + for successor in frame.iter.by_ref() { if !visited[successor] { stack.push(PostOrderFrame { node: successor, iter: graph.successors(successor) }); continue 'recurse; @@ -112,7 +112,7 @@ where /// This is equivalent to just invoke `next` repeatedly until /// you get a `None` result. pub fn complete_search(&mut self) { - while let Some(_) = self.next() {} + for _ in self.by_ref() {} } /// Returns true if node has been visited thus far. diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 914a6a16348c..7f36e4ca16df 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -40,7 +40,7 @@ pub struct SccData { } impl Sccs { - pub fn new(graph: &(impl DirectedGraph + Successors)) -> Self { + pub fn new(graph: &impl Successors) -> Self { SccsConstruction::construct(graph) } diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index c6d51a5d6b4f..240f2671c3b2 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -562,7 +562,7 @@ impl SelfProfiler { // ASLR is disabled and the heap is otherwise deterministic. let pid: u32 = process::id(); let filename = format!("{crate_name}-{pid:07}.rustc_profile"); - let path = output_directory.join(&filename); + let path = output_directory.join(filename); let profiler = Profiler::with_counter(&path, measureme::counters::Counter::by_name(counter_name)?)?; diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index 21d7c91ec482..885f023122ab 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -125,13 +125,13 @@ impl SortedMap { /// Iterate over the keys, sorted #[inline] - pub fn keys(&self) -> impl Iterator + ExactSizeIterator + DoubleEndedIterator { + pub fn keys(&self) -> impl ExactSizeIterator + DoubleEndedIterator { self.data.iter().map(|(k, _)| k) } /// Iterate over values, sorted by key #[inline] - pub fn values(&self) -> impl Iterator + ExactSizeIterator + DoubleEndedIterator { + pub fn values(&self) -> impl ExactSizeIterator + DoubleEndedIterator { self.data.iter().map(|(_, v)| v) } diff --git a/compiler/rustc_data_structures/src/sync/lock.rs b/compiler/rustc_data_structures/src/sync/lock.rs index 756984642c74..780be7739458 100644 --- a/compiler/rustc_data_structures/src/sync/lock.rs +++ b/compiler/rustc_data_structures/src/sync/lock.rs @@ -69,7 +69,7 @@ mod maybe_sync { match self.mode { Mode::NoSync => { let cell = unsafe { &self.lock.mode_union.no_sync }; - debug_assert_eq!(cell.get(), true); + debug_assert!(cell.get()); cell.set(false); } // SAFETY (unlock): We know that the lock is locked as this type is a proof of that. diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 08b97b4953e9..627fd74c8d77 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -814,13 +814,17 @@ fn print_crate_info( match expected_values { ExpectedValues::Any => check_cfgs.push(format!("{name}=any()")), ExpectedValues::Some(values) => { - check_cfgs.extend(values.iter().map(|value| { - if let Some(value) = value { - format!("{name}=\"{value}\"") - } else { - name.to_string() - } - })) + if !values.is_empty() { + check_cfgs.extend(values.iter().map(|value| { + if let Some(value) = value { + format!("{name}=\"{value}\"") + } else { + name.to_string() + } + })) + } else { + check_cfgs.push(format!("{name}=")) + } } } } diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index fe426b8111cc..31de0a747b24 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -3,7 +3,6 @@ use rustc_ast as ast; use rustc_ast_pretty::pprust as pprust_ast; use rustc_errors::FatalError; -use rustc_hir as hir; use rustc_hir_pretty as pprust_hir; use rustc_middle::bug; use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty}; @@ -70,11 +69,7 @@ struct HirIdentifiedAnn<'tcx> { impl<'tcx> pprust_hir::PpAnn for HirIdentifiedAnn<'tcx> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { - pprust_hir::PpAnn::nested( - &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>), - state, - nested, - ) + self.tcx.nested(state, nested) } fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { @@ -152,8 +147,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> { if let pprust_hir::Nested::Body(id) = nested { self.maybe_typeck_results.set(Some(self.tcx.typeck_body(id))); } - let pp_ann = &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>); - pprust_hir::PpAnn::nested(pp_ann, state, nested); + self.tcx.nested(state, nested); self.maybe_typeck_results.set(old_maybe_typeck_results); } @@ -169,7 +163,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> { self.tcx .hir() .maybe_body_owned_by(expr.hir_id.owner.def_id) - .map(|body_id| self.tcx.typeck_body(body_id)) + .map(|body_id| self.tcx.typeck_body(body_id.id())) }); if let Some(typeck_results) = typeck_results { diff --git a/compiler/rustc_error_codes/src/error_codes/E0229.md b/compiler/rustc_error_codes/src/error_codes/E0229.md index a8fab057d43a..f4a983cb9efc 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0229.md +++ b/compiler/rustc_error_codes/src/error_codes/E0229.md @@ -1,5 +1,4 @@ -An associated type binding was done outside of the type parameter declaration -and `where` clause. +An associated item constraint was written in an unexpected context. Erroneous code example: @@ -16,12 +15,12 @@ impl Foo for isize { fn boo(&self) -> usize { 42 } } -fn baz(x: &>::A) {} -// error: associated type bindings are not allowed here +fn baz(x: &>::A) {} +// error: associated item constraint are not allowed here ``` -To solve this error, please move the type bindings in the type parameter -declaration: +To solve this error, please move the associated item constraints to the type +parameter declaration: ``` # struct Bar; @@ -29,7 +28,7 @@ declaration: fn baz>(x: &::A) {} // ok! ``` -Or in the `where` clause: +Or into the where-clause: ``` # struct Bar; diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index bb6a54fae707..7c76392858cd 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -138,6 +138,8 @@ declare_features! ( (accepted, copy_closures, "1.26.0", Some(44490)), /// Allows `crate` in paths. (accepted, crate_in_paths, "1.30.0", Some(45477)), + /// Allows users to provide classes for fenced code block using `class:classname`. + (accepted, custom_code_classes_in_docs, "CURRENT_RUSTC_VERSION", Some(79483)), /// Allows using `#[debugger_visualizer]` attribute. (accepted, debugger_visualizer, "1.71.0", Some(95939)), /// Allows rustc to inject a default alloc_error_handler diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 0b4a871dd50c..8b7e93fd5558 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -578,6 +578,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \ through unstable paths" ), + rustc_attr!( + rustc_deprecated_safe_2024, Normal, template!(Word), WarnFollowing, + EncodeCrossCrate::Yes, + "rustc_deprecated_safe_2024 is supposed to be used in libstd only", + ), + // ========================================================================== // Internal attributes: Type system related: diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index dc4807bab2d3..8de2cdefa81c 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -177,8 +177,6 @@ declare_features! ( /// Allows using the `unadjusted` ABI; perma-unstable. (internal, abi_unadjusted, "1.16.0", None), - /// Allows using the `vectorcall` ABI. - (unstable, abi_vectorcall, "1.7.0", None), /// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`. (internal, allocator_internals, "1.20.0", None), /// Allows using `#[allow_internal_unsafe]`. This is an @@ -243,6 +241,8 @@ declare_features! ( // feature-group-start: internal feature gates // ------------------------------------------------------------------------- + /// Allows using the `vectorcall` ABI. + (unstable, abi_vectorcall, "1.7.0", Some(124485)), /// Allows features specific to auto traits. /// Renamed from `optin_builtin_traits`. (unstable, auto_traits, "1.50.0", Some(13231)), @@ -424,8 +424,6 @@ declare_features! ( /// Allows function attribute `#[coverage(on/off)]`, to control coverage /// instrumentation of that function. (unstable, coverage_attribute, "1.74.0", Some(84605)), - /// Allows users to provide classes for fenced code block using `class:classname`. - (unstable, custom_code_classes_in_docs, "1.74.0", Some(79483)), /// Allows non-builtin attributes in inner attribute position. (unstable, custom_inner_attributes, "1.30.0", Some(54726)), /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e64f7aeb11b3..e971d0e3c143 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -300,23 +300,30 @@ impl GenericArg<'_> { } } +/// The generic arguments and associated item constraints of a path segment. #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct GenericArgs<'hir> { /// The generic arguments for this path segment. pub args: &'hir [GenericArg<'hir>], - /// Bindings (equality constraints) on associated types, if present. - /// E.g., `Foo`. - pub bindings: &'hir [TypeBinding<'hir>], - /// Were arguments written in parenthesized form `Fn(T) -> U`? + /// The associated item constraints for this path segment. + pub constraints: &'hir [AssocItemConstraint<'hir>], + /// Whether the arguments were written in parenthesized form (e.g., `Fn(T) -> U`). + /// /// This is required mostly for pretty-printing and diagnostics, /// but also for changing lifetime elision rules to be "function-like". pub parenthesized: GenericArgsParentheses, - /// The span encompassing arguments and the surrounding brackets `<>` or `()` + /// The span encompassing the arguments, constraints and the surrounding brackets (`<>` or `()`). + /// + /// For example: + /// + /// ```ignore (illustrative) /// Foo Fn(T, U, V) -> W /// ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ + /// ``` + /// /// Note that this may be: /// - empty, if there are no generic brackets (but there may be hidden lifetimes) - /// - dummy, if this was generated while desugaring + /// - dummy, if this was generated during desugaring pub span_ext: Span, } @@ -324,39 +331,63 @@ impl<'hir> GenericArgs<'hir> { pub const fn none() -> Self { Self { args: &[], - bindings: &[], + constraints: &[], parenthesized: GenericArgsParentheses::No, span_ext: DUMMY_SP, } } - pub fn inputs(&self) -> &[Ty<'hir>] { - if self.parenthesized == GenericArgsParentheses::ParenSugar { - for arg in self.args { - match arg { - GenericArg::Lifetime(_) => {} - GenericArg::Type(ref ty) => { - if let TyKind::Tup(ref tys) = ty.kind { - return tys; - } - break; - } - GenericArg::Const(_) => {} - GenericArg::Infer(_) => {} - } - } + /// Obtain the list of input types and the output type if the generic arguments are parenthesized. + /// + /// Returns the `Ty0, Ty1, ...` and the `RetTy` in `Trait(Ty0, Ty1, ...) -> RetTy`. + /// Panics if the parenthesized arguments have an incorrect form (this shouldn't happen). + pub fn paren_sugar_inputs_output(&self) -> Option<(&[Ty<'hir>], &Ty<'hir>)> { + if self.parenthesized != GenericArgsParentheses::ParenSugar { + return None; } - panic!("GenericArgs::inputs: not a `Fn(T) -> U`"); + + let inputs = self + .args + .iter() + .find_map(|arg| { + let GenericArg::Type(ty) = arg else { return None }; + let TyKind::Tup(tys) = &ty.kind else { return None }; + Some(tys) + }) + .unwrap(); + + Some((inputs, self.paren_sugar_output_inner())) } - pub fn has_err(&self) -> bool { - self.args.iter().any(|arg| match arg { - GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err(_)), - _ => false, - }) || self.bindings.iter().any(|arg| match arg.kind { - TypeBindingKind::Equality { term: Term::Ty(ty) } => matches!(ty.kind, TyKind::Err(_)), - _ => false, - }) + /// Obtain the output type if the generic arguments are parenthesized. + /// + /// Returns the `RetTy` in `Trait(Ty0, Ty1, ...) -> RetTy`. + /// Panics if the parenthesized arguments have an incorrect form (this shouldn't happen). + pub fn paren_sugar_output(&self) -> Option<&Ty<'hir>> { + (self.parenthesized == GenericArgsParentheses::ParenSugar) + .then(|| self.paren_sugar_output_inner()) + } + + fn paren_sugar_output_inner(&self) -> &Ty<'hir> { + let [constraint] = self.constraints.try_into().unwrap(); + debug_assert_eq!(constraint.ident.name, sym::Output); + constraint.ty().unwrap() + } + + pub fn has_err(&self) -> Option { + self.args + .iter() + .find_map(|arg| { + let GenericArg::Type(ty) = arg else { return None }; + let TyKind::Err(guar) = ty.kind else { return None }; + Some(guar) + }) + .or_else(|| { + self.constraints.iter().find_map(|constraint| { + let TyKind::Err(guar) = constraint.ty()?.kind else { return None }; + Some(guar) + }) + }) } #[inline] @@ -383,9 +414,11 @@ impl<'hir> GenericArgs<'hir> { .count() } - /// The span encompassing the text inside the surrounding brackets. - /// It will also include bindings if they aren't in the form `-> Ret` - /// Returns `None` if the span is empty (e.g. no brackets) or dummy + /// The span encompassing the arguments and constraints[^1] inside the surrounding brackets. + /// + /// Returns `None` if the span is empty (i.e., no brackets) or dummy. + /// + /// [^1]: Unless of the form `-> Ty` (see [`GenericArgsParentheses`]). pub fn span(&self) -> Option { let span_ext = self.span_ext()?; Some(span_ext.with_lo(span_ext.lo() + BytePos(1)).with_hi(span_ext.hi() - BytePos(1))) @@ -660,9 +693,7 @@ impl<'hir> Generics<'hir> { |bound| { let span_for_parentheses = if let Some(trait_ref) = bound.trait_ref() && let [.., segment] = trait_ref.path.segments - && segment.args().parenthesized == GenericArgsParentheses::ParenSugar - && let [binding] = segment.args().bindings - && let TypeBindingKind::Equality { term: Term::Ty(ret_ty) } = binding.kind + && let Some(ret_ty) = segment.args().paren_sugar_output() && let ret_ty = ret_ty.peel_refs() && let TyKind::TraitObject( _, @@ -748,7 +779,7 @@ impl<'hir> Generics<'hir> { /// A single predicate in a where-clause. #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum WherePredicate<'hir> { - /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`). + /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). BoundPredicate(WhereBoundPredicate<'hir>), /// A lifetime predicate (e.g., `'a: 'b + 'c`). RegionPredicate(WhereRegionPredicate<'hir>), @@ -2356,24 +2387,43 @@ pub enum ImplItemKind<'hir> { Type(&'hir Ty<'hir>), } -/// An associated item binding. +/// A constraint on an associated item. /// /// ### Examples /// -/// * `Trait` -/// * `Trait = Ty>` -/// * `Trait` -/// * `Trait` (under feature `associated_const_equality`) -/// * `Trait` (under feature `return_type_notation`) +/// * the `A = Ty` and `B = Ty` in `Trait` +/// * the `G = Ty` in `Trait = Ty>` +/// * the `A: Bound` in `Trait` +/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy` +/// * the `C = { Ct }` in `Trait` (feature `associated_const_equality`) +/// * the `f(): Bound` in `Trait` (feature `return_type_notation`) #[derive(Debug, Clone, Copy, HashStable_Generic)] -pub struct TypeBinding<'hir> { +pub struct AssocItemConstraint<'hir> { pub hir_id: HirId, pub ident: Ident, pub gen_args: &'hir GenericArgs<'hir>, - pub kind: TypeBindingKind<'hir>, + pub kind: AssocItemConstraintKind<'hir>, pub span: Span, } +impl<'hir> AssocItemConstraint<'hir> { + /// Obtain the type on the RHS of an assoc ty equality constraint if applicable. + pub fn ty(self) -> Option<&'hir Ty<'hir>> { + match self.kind { + AssocItemConstraintKind::Equality { term: Term::Ty(ty) } => Some(ty), + _ => None, + } + } + + /// Obtain the const on the RHS of an assoc const equality constraint if applicable. + pub fn ct(self) -> Option<&'hir AnonConst> { + match self.kind { + AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct), + _ => None, + } + } +} + #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum Term<'hir> { Ty(&'hir Ty<'hir>), @@ -2392,28 +2442,18 @@ impl<'hir> From<&'hir AnonConst> for Term<'hir> { } } -// Represents the two kinds of type bindings. +/// The kind of [associated item constraint][AssocItemConstraint]. #[derive(Debug, Clone, Copy, HashStable_Generic)] -pub enum TypeBindingKind<'hir> { - /// E.g., `Foo`. - Constraint { bounds: &'hir [GenericBound<'hir>] }, - /// E.g., `Foo`. +pub enum AssocItemConstraintKind<'hir> { + /// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait`). + /// + /// Also known as an *associated item binding* (we *bind* an associated item to a term). + /// + /// Furthermore, associated type equality constraints can also be referred to as *associated type + /// bindings*. Similarly with associated const equality constraints and *associated const bindings*. Equality { term: Term<'hir> }, -} - -impl TypeBinding<'_> { - pub fn ty(&self) -> &Ty<'_> { - match self.kind { - TypeBindingKind::Equality { term: Term::Ty(ref ty) } => ty, - _ => panic!("expected equality type binding for parenthesized generic args"), - } - } - pub fn opt_const(&self) -> Option<&'_ AnonConst> { - match self.kind { - TypeBindingKind::Equality { term: Term::Const(ref c) } => Some(c), - _ => None, - } - } + /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait`). + Bound { bounds: &'hir [GenericBound<'hir>] }, } #[derive(Debug, Clone, Copy, HashStable_Generic)] @@ -3609,7 +3649,7 @@ pub enum Node<'hir> { Stmt(&'hir Stmt<'hir>), PathSegment(&'hir PathSegment<'hir>), Ty(&'hir Ty<'hir>), - TypeBinding(&'hir TypeBinding<'hir>), + AssocItemConstraint(&'hir AssocItemConstraint<'hir>), TraitRef(&'hir TraitRef<'hir>), Pat(&'hir Pat<'hir>), PatField(&'hir PatField<'hir>), @@ -3658,7 +3698,7 @@ impl<'hir> Node<'hir> { | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident), Node::Lifetime(lt) => Some(lt.ident), Node::GenericParam(p) => Some(p.name.ident()), - Node::TypeBinding(b) => Some(b.ident), + Node::AssocItemConstraint(c) => Some(c.ident), Node::PatField(f) => Some(f.ident), Node::ExprField(f) => Some(f.ident), Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident), @@ -3834,7 +3874,7 @@ impl<'hir> Node<'hir> { expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n; expect_path_segment, &'hir PathSegment<'hir>, Node::PathSegment(n), n; expect_ty, &'hir Ty<'hir>, Node::Ty(n), n; - expect_type_binding, &'hir TypeBinding<'hir>, Node::TypeBinding(n), n; + expect_assoc_item_constraint, &'hir AssocItemConstraint<'hir>, Node::AssocItemConstraint(n), n; expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n; expect_pat, &'hir Pat<'hir>, Node::Pat(n), n; expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n; diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index aba0532f0d1e..9bc2bbe0c647 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -299,7 +299,7 @@ pub trait Visitor<'v>: Sized { walk_item(self, i) } - fn visit_body(&mut self, b: &'v Body<'v>) -> Self::Result { + fn visit_body(&mut self, b: &Body<'v>) -> Self::Result { walk_body(self, b) } @@ -453,8 +453,11 @@ pub trait Visitor<'v>: Sized { fn visit_generic_args(&mut self, generic_args: &'v GenericArgs<'v>) -> Self::Result { walk_generic_args(self, generic_args) } - fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding<'v>) -> Self::Result { - walk_assoc_type_binding(self, type_binding) + fn visit_assoc_item_constraint( + &mut self, + constraint: &'v AssocItemConstraint<'v>, + ) -> Self::Result { + walk_assoc_item_constraint(self, constraint) } fn visit_attribute(&mut self, _attr: &'v Attribute) -> Self::Result { Self::Result::output() @@ -578,7 +581,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: V::Result::output() } -pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) -> V::Result { +pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &Body<'v>) -> V::Result { walk_list!(visitor, visit_param, body.params); visitor.visit_expr(body.value) } @@ -1248,23 +1251,25 @@ pub fn walk_generic_args<'v, V: Visitor<'v>>( generic_args: &'v GenericArgs<'v>, ) -> V::Result { walk_list!(visitor, visit_generic_arg, generic_args.args); - walk_list!(visitor, visit_assoc_type_binding, generic_args.bindings); + walk_list!(visitor, visit_assoc_item_constraint, generic_args.constraints); V::Result::output() } -pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>( +pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>( visitor: &mut V, - type_binding: &'v TypeBinding<'v>, + constraint: &'v AssocItemConstraint<'v>, ) -> V::Result { - try_visit!(visitor.visit_id(type_binding.hir_id)); - try_visit!(visitor.visit_ident(type_binding.ident)); - try_visit!(visitor.visit_generic_args(type_binding.gen_args)); - match type_binding.kind { - TypeBindingKind::Equality { ref term } => match term { + try_visit!(visitor.visit_id(constraint.hir_id)); + try_visit!(visitor.visit_ident(constraint.ident)); + try_visit!(visitor.visit_generic_args(constraint.gen_args)); + match constraint.kind { + AssocItemConstraintKind::Equality { ref term } => match term { Term::Ty(ref ty) => try_visit!(visitor.visit_ty(ty)), Term::Const(ref c) => try_visit!(visitor.visit_anon_const(c)), }, - TypeBindingKind::Constraint { bounds } => walk_list!(visitor, visit_param_bound, bounds), + AssocItemConstraintKind::Bound { bounds } => { + walk_list!(visitor, visit_param_bound, bounds) + } } V::Result::output() } diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index f5f7bae11b20..c3ccba487ede 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -176,6 +176,7 @@ language_item_table! { AsyncDropSlice, sym::async_drop_slice, async_drop_slice_fn, Target::Fn, GenericRequirement::Exact(1); AsyncDropChain, sym::async_drop_chain, async_drop_chain_fn, Target::Fn, GenericRequirement::Exact(2); AsyncDropNoop, sym::async_drop_noop, async_drop_noop_fn, Target::Fn, GenericRequirement::Exact(0); + AsyncDropDeferredDropInPlace, sym::async_drop_deferred_drop_in_place, async_drop_deferred_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1); AsyncDropFuse, sym::async_drop_fuse, async_drop_fuse_fn, Target::Fn, GenericRequirement::Exact(1); AsyncDropDefer, sym::async_drop_defer, async_drop_defer_fn, Target::Fn, GenericRequirement::Exact(1); AsyncDropEither, sym::async_drop_either, async_drop_either_fn, Target::Fn, GenericRequirement::Exact(3); diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index cf492a2a3fee..67959d9dfede 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -4,6 +4,10 @@ hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_ hir_analysis_ambiguous_lifetime_bound = ambiguous lifetime bound, explicit lifetime bound required +hir_analysis_assoc_item_constraints_not_allowed_here = + associated item constraints are not allowed here + .label = associated item constraint not allowed here + hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$ty_param_name}` hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named -> @@ -24,10 +28,6 @@ hir_analysis_assoc_kind_mismatch = expected {$expected}, found {$got} hir_analysis_assoc_kind_mismatch_wrap_in_braces_sugg = consider adding braces here -hir_analysis_assoc_type_binding_not_allowed = - associated type bindings are not allowed here - .label = associated type not allowed here - hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the associated type of a trait with uninferred generic parameters .suggestion = use a fully qualified path with inferred lifetimes diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 3904f14b0f6e..76b6cbd6e531 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -342,7 +342,7 @@ fn check_opaque_meets_bounds<'tcx>( let param_env = tcx.param_env(defining_use_anchor); let infcx = tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let args = match *origin { hir::OpaqueTyOrigin::FnReturn(parent) @@ -1727,7 +1727,7 @@ pub(super) fn check_coroutine_obligations( .with_opaque_type_inference(def_id) .build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); for (predicate, cause) in &typeck_results.coroutine_stalled_predicates { ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, *predicate)); } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 8928711253cd..74dcd672578e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -10,7 +10,7 @@ use rustc_hir::intravisit; use rustc_hir::{GenericParamKind, ImplItemKind}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; -use rustc_infer::traits::{util, FulfillmentError}; +use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::util::ExplicitSelf; @@ -25,7 +25,7 @@ use rustc_trait_selection::regions::InferCtxtRegionExt; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{ - self, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal, + self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal, }; use std::borrow::Cow; use std::iter; @@ -225,7 +225,7 @@ fn compare_method_predicate_entailment<'tcx>( let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); let infcx = &tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(infcx); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds()); @@ -493,7 +493,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( ); let infcx = &tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(infcx); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); // Normalize the impl signature with fresh variables for lifetime inference. let misc_cause = ObligationCause::misc(return_span, impl_m_def_id); @@ -764,17 +764,20 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( Ok(&*tcx.arena.alloc(remapped_types)) } -struct ImplTraitInTraitCollector<'a, 'tcx> { - ocx: &'a ObligationCtxt<'a, 'tcx>, +struct ImplTraitInTraitCollector<'a, 'tcx, E> { + ocx: &'a ObligationCtxt<'a, 'tcx, E>, types: FxIndexMap, ty::GenericArgsRef<'tcx>)>, span: Span, param_env: ty::ParamEnv<'tcx>, body_id: LocalDefId, } -impl<'a, 'tcx> ImplTraitInTraitCollector<'a, 'tcx> { +impl<'a, 'tcx, E> ImplTraitInTraitCollector<'a, 'tcx, E> +where + E: 'tcx, +{ fn new( - ocx: &'a ObligationCtxt<'a, 'tcx>, + ocx: &'a ObligationCtxt<'a, 'tcx, E>, span: Span, param_env: ty::ParamEnv<'tcx>, body_id: LocalDefId, @@ -783,7 +786,10 @@ impl<'a, 'tcx> ImplTraitInTraitCollector<'a, 'tcx> { } } -impl<'tcx> TypeFolder> for ImplTraitInTraitCollector<'_, 'tcx> { +impl<'tcx, E> TypeFolder> for ImplTraitInTraitCollector<'_, 'tcx, E> +where + E: 'tcx, +{ fn interner(&self) -> TyCtxt<'tcx> { self.ocx.infcx.tcx } @@ -1777,7 +1783,7 @@ fn compare_const_predicate_entailment<'tcx>( ); let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let impl_ct_own_bounds = impl_ct_predicates.instantiate_own(tcx, impl_args); for (predicate, span) in impl_ct_own_bounds { @@ -1910,7 +1916,7 @@ fn compare_type_predicate_entailment<'tcx>( let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds()); @@ -1977,7 +1983,7 @@ pub(super) fn check_type_bounds<'tcx>( let rebased_args = impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args); let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); // A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the // span for an impl's associated type. Instead, for these, use the def_span for the synthesized @@ -2026,10 +2032,19 @@ pub(super) fn check_type_bounds<'tcx>( // to its definition type. This should be the param-env we use to *prove* the // predicate too, but we don't do that because of performance issues. // See . + let trait_projection_ty = Ty::new_projection(tcx, trait_ty.def_id, rebased_args); + let impl_identity_ty = tcx.type_of(impl_ty.def_id).instantiate_identity(); let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref); for mut obligation in util::elaborate(tcx, obligations) { - let normalized_predicate = - ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate); + let normalized_predicate = if infcx.next_trait_solver() { + obligation.predicate.fold_with(&mut ReplaceTy { + tcx, + from: trait_projection_ty, + to: impl_identity_ty, + }) + } else { + ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate) + }; debug!("compare_projection_bounds: normalized predicate = {:?}", normalized_predicate); obligation.predicate = normalized_predicate; @@ -2050,6 +2065,22 @@ pub(super) fn check_type_bounds<'tcx>( ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env) } +struct ReplaceTy<'tcx> { + tcx: TyCtxt<'tcx>, + from: Ty<'tcx>, + to: Ty<'tcx>, +} + +impl<'tcx> TypeFolder> for ReplaceTy<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if self.from == ty { self.to } else { ty.super_fold_with(self) } + } +} + /// Install projection predicates that allow GATs to project to their own /// definition types. This is not allowed in general in cases of default /// associated types in trait definitions, or when specialization is involved, @@ -2250,7 +2281,7 @@ fn try_report_async_mismatch<'tcx>( && let Some(proj) = proj.no_bound_vars() && infcx.can_eq( error.root_obligation.param_env, - proj.term.ty().unwrap(), + proj.term.expect_type(), impl_sig.output(), ) { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index ca08eeea2275..10b097a1060f 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -267,7 +267,7 @@ fn report_mismatched_rpitit_signature<'tcx>( .explicit_item_bounds(future_ty.def_id) .iter_instantiated_copied(tcx, future_ty.args) .find_map(|(clause, _)| match clause.kind().no_bound_vars()? { - ty::ClauseKind::Projection(proj) => proj.term.ty(), + ty::ClauseKind::Projection(proj) => proj.term.as_type(), _ => None, }) else { diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index be412dde9680..8ec6dd12a78d 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -123,7 +123,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( adt_to_impl_args: GenericArgsRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); // Take the param-env of the adt and instantiate the args that show up in // the implementation's self type. This gives us the assumptions that the diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index 25ac31c16c7c..cc52a7658020 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -133,7 +133,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { main_diagnostics_def_id, ObligationCauseCode::MainFunctionType, ); - let ocx = traits::ObligationCtxt::new(&infcx); + let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx); let norm_return_ty = ocx.normalize(&cause, param_env, return_ty); ocx.register_bound(cause, param_env, norm_return_ty, term_did); let errors = ocx.select_all_or_error(); diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 0083da2a1e44..4d1b96d9c1ba 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -112,6 +112,7 @@ pub fn provide(providers: &mut Providers) { wfcheck::provide(providers); *providers = Providers { adt_destructor, + adt_async_destructor, region_scope_tree, collect_return_position_impl_trait_in_trait_tys, compare_impl_const: compare_impl_item::compare_impl_const_raw, @@ -124,6 +125,10 @@ fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option tcx.calculate_dtor(def_id.to_def_id(), dropck::check_drop_impl) } +fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { + tcx.calculate_async_dtor(def_id.to_def_id(), dropck::check_drop_impl) +} + /// Given a `DefId` for an opaque type in return position, find its parent item's return /// expressions. fn get_owner_return_paths( @@ -436,7 +441,9 @@ fn fn_sig_suggestion<'tcx>( output = if let ty::Alias(_, alias_ty) = *output.kind() { tcx.explicit_item_super_predicates(alias_ty.def_id) .iter_instantiated_copied(tcx, alias_ty.args) - .find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty()) + .find_map(|(bound, _)| { + bound.as_projection_clause()?.no_bound_vars()?.term.as_type() + }) .unwrap_or_else(|| { span_bug!( ident.span, @@ -594,7 +601,7 @@ pub fn check_function_signature<'tcx>( let param_env = ty::ParamEnv::empty(); let infcx = &tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(infcx); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); let actual_sig = tcx.fn_sig(fn_id).instantiate_identity(); diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 8b0adebfaf46..30b03b43872a 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -818,7 +818,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { resolve_block(self, b); } - fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) { + fn visit_body(&mut self, body: &hir::Body<'tcx>) { let body_id = body.id(); let owner_id = self.tcx.hir().body_owner_def_id(body_id); @@ -896,7 +896,7 @@ pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { return tcx.region_scope_tree(typeck_root_def_id); } - let scope_tree = if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) { + let scope_tree = if let Some(body) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) { let mut visitor = RegionResolutionVisitor { tcx, scope_tree: ScopeTree::default(), @@ -907,9 +907,8 @@ pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { fixup_scopes: vec![], }; - let body = tcx.hir().body(body_id); visitor.scope_tree.root_body = Some(body.value.hir_id); - visitor.visit_body(body); + visitor.visit_body(&body); visitor.scope_tree } else { ScopeTree::default() diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 81e3d8c7ece2..b206d8046ee9 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -37,7 +37,7 @@ use rustc_trait_selection::traits::misc::{ use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::{ - self, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc, + self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc, }; use rustc_type_ir::TypeFlags; @@ -45,13 +45,13 @@ use std::cell::LazyCell; use std::ops::{ControlFlow, Deref}; pub(super) struct WfCheckingCtxt<'a, 'tcx> { - pub(super) ocx: ObligationCtxt<'a, 'tcx>, + pub(super) ocx: ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>, span: Span, body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, } impl<'a, 'tcx> Deref for WfCheckingCtxt<'a, 'tcx> { - type Target = ObligationCtxt<'a, 'tcx>; + type Target = ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>; fn deref(&self) -> &Self::Target { &self.ocx } @@ -106,7 +106,7 @@ where { let param_env = tcx.param_env(body_def_id); let infcx = &tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(infcx); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); let mut wfcx = WfCheckingCtxt { ocx, span, body_def_id, param_env }; @@ -881,7 +881,7 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem _ => {} } if !trait_should_be_self.is_empty() { - if tcx.check_is_object_safe(trait_def_id) { + if tcx.is_object_safe(trait_def_id) { return; } let sugg = trait_should_be_self.iter().map(|span| (*span, "Self".to_string())).collect(); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 8f0aba1c38c1..61adb7a3cbae 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -267,7 +267,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() .join(", "), })); } else { - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); for field in coerced_fields { ocx.register_obligation(Obligation::new( tcx, @@ -480,7 +480,7 @@ pub fn coerce_unsized_info<'tcx>( }; // Register an obligation for `A: Trait`. - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let cause = traits::ObligationCause::misc(span, impl_did); let obligation = Obligation::new( tcx, @@ -554,7 +554,7 @@ fn infringing_fields_error( if let ty::Param(_) = ty.kind() { bounds.push(( format!("{ty}"), - trait_ref.print_only_trait_path().to_string(), + trait_ref.print_trait_sugared().to_string(), Some(trait_ref.def_id), )); } diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 054a3af212a5..eae41d28e897 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -12,7 +12,6 @@ use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_session::parse::feature_err; use rustc_span::{sym, ErrorGuaranteed}; -use rustc_trait_selection::traits; mod builtin; mod inherent_impls; @@ -192,14 +191,14 @@ fn check_object_overlap<'tcx>( }); for component_def_id in component_def_ids { - if !tcx.check_is_object_safe(component_def_id) { + if !tcx.is_object_safe(component_def_id) { // Without the 'object_safe_for_dispatch' feature this is an error // which will be reported by wfcheck. Ignore it here. // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`. // With the feature enabled, the trait is not implemented automatically, // so this is valid. } else { - let mut supertrait_def_ids = traits::supertrait_def_ids(tcx, component_def_id); + let mut supertrait_def_ids = tcx.supertrait_def_ids(component_def_id); if supertrait_def_ids.any(|d| d == trait_def_id) { let span = tcx.def_span(impl_def_id); return Err(struct_span_code_err!( diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index bdac0d9b0b40..61ac4af01519 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -14,7 +14,6 @@ use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_trait_selection::traits::{self, IsFirstInputType, UncoveredTyParams}; use rustc_trait_selection::traits::{OrphanCheckErr, OrphanCheckMode}; -use rustc_trait_selection::traits::{StructurallyNormalizeExt, TraitEngineExt}; #[instrument(level = "debug", skip(tcx))] pub(crate) fn orphan_check_impl( @@ -317,12 +316,12 @@ fn orphan_check<'tcx>( } let ty = if infcx.next_trait_solver() { - let mut fulfill_cx = >::new(&infcx); - infcx - .at(&cause, ty::ParamEnv::empty()) - .structurally_normalize(ty, &mut *fulfill_cx) - .map(|ty| infcx.resolve_vars_if_possible(ty)) - .unwrap_or(ty) + ocx.structurally_normalize( + &cause, + ty::ParamEnv::empty(), + infcx.resolve_vars_if_possible(ty), + ) + .unwrap_or(ty) } else { ty }; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 5c7733065c61..c1850f78f2fb 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1468,12 +1468,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { depth: usize, generic_args: &'tcx hir::GenericArgs<'tcx>, ) { - if generic_args.parenthesized == hir::GenericArgsParentheses::ParenSugar { - self.visit_fn_like_elision( - generic_args.inputs(), - Some(generic_args.bindings[0].ty()), - false, - ); + if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() { + self.visit_fn_like_elision(inputs, Some(output), false); return; } @@ -1608,8 +1604,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } } - // Hack: when resolving the type `XX` in binding like `dyn - // Foo<'b, Item = XX>`, the current object-lifetime default + // Hack: When resolving the type `XX` in an assoc ty binding like + // `dyn Foo<'b, Item = XX>`, the current object-lifetime default // would be to examine the trait `Foo` to check whether it has // a lifetime bound declared on `Item`. e.g., if `Foo` is // declared like so, then the default object lifetime bound in @@ -1637,7 +1633,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // Resolve lifetimes found in the bindings, so either in the type `XX` in `Item = XX` or // in the trait ref `YY<...>` in `Item: YY<...>`. - for binding in generic_args.bindings { + for constraint in generic_args.constraints { let scope = Scope::ObjectLifetimeDefault { lifetime: if has_lifetime_parameter { None @@ -1646,7 +1642,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { }, s: self.scope, }; - // If the binding is parenthesized, then this must be `feature(return_type_notation)`. + // If the args are parenthesized, then this must be `feature(return_type_notation)`. // In that case, introduce a binder over all of the function's early and late bound vars. // // For example, given @@ -1659,13 +1655,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // `for<'a> T::Trait<'a, x(): for<'b> Other<'b>>` // this is going to expand to something like: // `for<'a> for<'r, T> >::x::<'r, T>::{opaque#0}: for<'b> Other<'b>`. - if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation { + if constraint.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation + { let bound_vars = if let Some(type_def_id) = type_def_id && self.tcx.def_kind(type_def_id) == DefKind::Trait && let Some((mut bound_vars, assoc_fn)) = BoundVarContext::supertrait_hrtb_vars( self.tcx, type_def_id, - binding.ident, + constraint.ident, ty::AssocKind::Fn, ) { bound_vars.extend(self.tcx.generics_of(assoc_fn.def_id).own_params.iter().map( @@ -1686,22 +1683,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } else { self.tcx .dcx() - .span_delayed_bug(binding.ident.span, "bad return type notation here"); + .span_delayed_bug(constraint.ident.span, "bad return type notation here"); vec![] }; self.with(scope, |this| { let scope = Scope::Supertrait { bound_vars, s: this.scope }; this.with(scope, |this| { let (bound_vars, _) = this.poly_trait_ref_binder_info(); - this.record_late_bound_vars(binding.hir_id, bound_vars); - this.visit_assoc_type_binding(binding) + this.record_late_bound_vars(constraint.hir_id, bound_vars); + this.visit_assoc_item_constraint(constraint) }); }); } else if let Some(type_def_id) = type_def_id { let bound_vars = BoundVarContext::supertrait_hrtb_vars( self.tcx, type_def_id, - binding.ident, + constraint.ident, ty::AssocKind::Type, ) .map(|(bound_vars, _)| bound_vars); @@ -1710,10 +1707,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { bound_vars: bound_vars.unwrap_or_default(), s: this.scope, }; - this.with(scope, |this| this.visit_assoc_type_binding(binding)); + this.with(scope, |this| this.visit_assoc_item_constraint(constraint)); }); } else { - self.with(scope, |this| this.visit_assoc_type_binding(binding)); + self.with(scope, |this| this.visit_assoc_item_constraint(constraint)); } } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index d497617f6449..71b08e293769 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -220,9 +220,10 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { .position(|arg| arg.hir_id() == hir_id) .map(|index| (index, seg)) .or_else(|| { - args.bindings + args.constraints .iter() - .filter_map(TypeBinding::opt_const) + .copied() + .filter_map(AssocItemConstraint::ct) .position(|ct| ct.hir_id == hir_id) .map(|idx| (idx, seg)) }) @@ -501,7 +502,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ bug!("unexpected sort of node in type_of(): {:?}", x); } }; - if let Err(e) = icx.check_tainted_by_errors() { + if let Err(e) = icx.check_tainted_by_errors() + && !output.references_error() + { ty::EarlyBinder::bind(Ty::new_error(tcx, e)) } else { ty::EarlyBinder::bind(output) diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 1c99713b3ae1..8a9d4cd4ac70 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -290,8 +290,8 @@ pub struct AmbiguousLifetimeBound { } #[derive(Diagnostic)] -#[diag(hir_analysis_assoc_type_binding_not_allowed, code = E0229)] -pub struct AssocTypeBindingNotAllowed { +#[diag(hir_analysis_assoc_item_constraints_not_allowed_here, code = E0229)] +pub struct AssocItemConstraintsNotAllowedHere { #[primary_span] #[label] pub span: 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 b0ae73fcc4be..b6a1799c03f1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -230,32 +230,34 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bounds } - /// Lower an associated item binding from HIR into `bounds`. + /// Lower an associated item constraint from the HIR into `bounds`. /// /// ### A Note on Binders /// /// Given something like `T: for<'a> Iterator`, /// the `trait_ref` here will be `for<'a> T: Iterator`. - /// The `binding` data however is from *inside* the binder + /// The `constraint` data however is from *inside* the binder /// (e.g., `&'a u32`) and hence may reference bound regions. - #[instrument(level = "debug", skip(self, bounds, dup_bindings, path_span))] - pub(super) fn lower_assoc_item_binding( + #[instrument(level = "debug", skip(self, bounds, duplicates, path_span))] + pub(super) fn lower_assoc_item_constraint( &self, hir_ref_id: hir::HirId, trait_ref: ty::PolyTraitRef<'tcx>, - binding: &hir::TypeBinding<'tcx>, + constraint: &hir::AssocItemConstraint<'tcx>, bounds: &mut Bounds<'tcx>, - dup_bindings: &mut FxIndexMap, + duplicates: &mut FxIndexMap, path_span: Span, only_self_bounds: OnlySelfBounds, ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx(); - let assoc_kind = if binding.gen_args.parenthesized + let assoc_kind = if constraint.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation { ty::AssocKind::Fn - } else if let hir::TypeBindingKind::Equality { term: hir::Term::Const(_) } = binding.kind { + } else if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(_) } = + constraint.kind + { ty::AssocKind::Const } else { ty::AssocKind::Type @@ -272,7 +274,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let candidate = if self.probe_trait_that_defines_assoc_item( trait_ref.def_id(), assoc_kind, - binding.ident, + constraint.ident, ) { // Simple case: The assoc item is defined in the current trait. trait_ref @@ -284,14 +286,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_ref.skip_binder().print_only_trait_name(), None, assoc_kind, - binding.ident, + constraint.ident, path_span, - Some(binding), + Some(constraint), )? }; let (assoc_ident, def_scope) = - tcx.adjust_ident_and_get_scope(binding.ident, candidate.def_id(), hir_ref_id); + tcx.adjust_ident_and_get_scope(constraint.ident, candidate.def_id(), hir_ref_id); // We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()` // instead of calling `filter_by_name_and_kind` which would needlessly normalize the @@ -306,26 +308,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let reported = tcx .dcx() .struct_span_err( - binding.span, - format!("{} `{}` is private", assoc_item.kind, binding.ident), + constraint.span, + format!("{} `{}` is private", assoc_item.kind, constraint.ident), ) - .with_span_label(binding.span, format!("private {}", assoc_item.kind)) + .with_span_label(constraint.span, format!("private {}", assoc_item.kind)) .emit(); self.set_tainted_by_errors(reported); } - tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None); + tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), constraint.span, None); - dup_bindings + duplicates .entry(assoc_item.def_id) .and_modify(|prev_span| { tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified { - span: binding.span, + span: constraint.span, prev_span: *prev_span, - item_name: binding.ident, + item_name: constraint.ident, def_path: tcx.def_path_str(assoc_item.container_id(tcx)), }); }) - .or_insert(binding.span); + .or_insert(constraint.span); let projection_term = if let ty::AssocKind::Fn = assoc_kind { let mut emitted_bad_param_err = None; @@ -384,7 +386,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { alias_ty.into() } else { return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit { - span: binding.span, + span: constraint.span, ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output), fn_span: tcx.hir().span_if_local(assoc_item.def_id), note: (), @@ -398,19 +400,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output); let instantiation_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args); - let bound_vars = tcx.late_bound_vars(binding.hir_id); + let bound_vars = tcx.late_bound_vars(constraint.hir_id); ty::Binder::bind_with_vars(instantiation_output, bound_vars) } else { // Create the generic arguments for the associated type or constant by joining the // parent arguments (the arguments of the trait) and the own arguments (the ones of // the associated item itself) and construct an alias type using them. let alias_ty = candidate.map_bound(|trait_ref| { - let ident = Ident::new(assoc_item.name, binding.ident.span); + let ident = Ident::new(assoc_item.name, constraint.ident.span); let item_segment = hir::PathSegment { ident, - hir_id: binding.hir_id, + hir_id: constraint.hir_id, res: Res::Err, - args: Some(binding.gen_args), + args: Some(constraint.gen_args), infer_args: false, }; @@ -426,26 +428,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }); // Provide the resolved type of the associated constant to `type_of(AnonConst)`. - if let hir::TypeBindingKind::Equality { term: hir::Term::Const(anon_const) } = - binding.kind + if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(anon_const) } = + constraint.kind { let ty = alias_ty.map_bound(|ty| tcx.type_of(ty.def_id).instantiate(tcx, ty.args)); - let ty = check_assoc_const_binding_type(tcx, assoc_ident, ty, binding.hir_id); + let ty = check_assoc_const_binding_type(tcx, assoc_ident, ty, constraint.hir_id); tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty)); } alias_ty }; - match binding.kind { - hir::TypeBindingKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => { + match constraint.kind { + hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => { return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound { - span: binding.span, + span: constraint.span, })); } // Lower an equality constraint like `Item = u32` as found in HIR bound `T: Iterator` // to a projection predicate: `::Item = u32`. - hir::TypeBindingKind::Equality { term } => { + hir::AssocItemConstraintKind::Equality { term } => { let term = match term { hir::Term::Ty(ty) => self.lower_ty(ty).into(), hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(), @@ -469,18 +471,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // struct S1 Fn(&i32, &i32) -> &'a i32>(F); // ---- ---- ^^^^^^^ // NOTE(associated_const_equality): This error should be impossible to trigger - // with associated const equality bounds. + // with associated const equality constraints. self.validate_late_bound_regions( late_bound_in_projection_ty, late_bound_in_term, |br_name| { struct_span_code_err!( tcx.dcx(), - binding.span, + constraint.span, E0582, "binding for associated type `{}` references {}, \ - which does not appear in the trait input types", - binding.ident, + which does not appear in the trait input types", + constraint.ident, br_name ) }, @@ -492,12 +494,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { projection_term, term, }), - binding.span, + constraint.span, ); } // Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator` // to a bound involving a projection: `::Item: Debug`. - hir::TypeBindingKind::Constraint { bounds: hir_bounds } => { + hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => { // NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into // a trait predicate, since we only want to add predicates for the `Self` type. if !only_self_bounds.0 { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 9c687d3282bd..3a9ef244fd3f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1,5 +1,5 @@ use crate::errors::{ - self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams, + self, AssocItemConstraintsNotAllowedHere, ManualImplementation, MissingTypeParams, ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits, }; use crate::fluent_generated as fluent; @@ -15,7 +15,6 @@ use rustc_errors::{ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_infer::traits::FulfillmentError; use rustc_middle::bug; use rustc_middle::query::Key; use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _}; @@ -28,6 +27,7 @@ use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::BytePos; use rustc_span::{Span, Symbol, DUMMY_SP}; +use rustc_trait_selection::traits::FulfillmentError; use rustc_trait_selection::traits::{ object_safety_violations_for_assoc_item, TraitAliasExpansionInfo, }; @@ -121,7 +121,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_kind: ty::AssocKind, assoc_name: Ident, span: Span, - binding: Option<&hir::TypeBinding<'tcx>>, + constraint: Option<&hir::AssocItemConstraint<'tcx>>, ) -> ErrorGuaranteed where I: Iterator>, @@ -135,7 +135,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .find(|item| tcx.hygienic_eq(assoc_name, item.ident(tcx), r.def_id())) }) { return self.complain_about_assoc_kind_mismatch( - assoc_item, assoc_kind, assoc_name, span, binding, + assoc_item, assoc_kind, assoc_name, span, constraint, ); } @@ -300,18 +300,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_kind: ty::AssocKind, ident: Ident, span: Span, - binding: Option<&hir::TypeBinding<'tcx>>, + constraint: Option<&hir::AssocItemConstraint<'tcx>>, ) -> ErrorGuaranteed { let tcx = self.tcx(); let bound_on_assoc_const_label = if let ty::AssocKind::Const = assoc_item.kind - && let Some(binding) = binding - && let hir::TypeBindingKind::Constraint { .. } = binding.kind + && let Some(constraint) = constraint + && let hir::AssocItemConstraintKind::Bound { .. } = constraint.kind { - let lo = if binding.gen_args.span_ext.is_dummy() { + let lo = if constraint.gen_args.span_ext.is_dummy() { ident.span } else { - binding.gen_args.span_ext + constraint.gen_args.span_ext }; Some(lo.between(span.shrink_to_hi())) } else { @@ -319,8 +319,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; // FIXME(associated_const_equality): This has quite a few false positives and negatives. - let wrap_in_braces_sugg = if let Some(binding) = binding - && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind + let wrap_in_braces_sugg = if let Some(constraint) = constraint + && let Some(hir_ty) = constraint.ty() && let ty = self.lower_ty(hir_ty) && (ty.is_enum() || ty.references_error()) && tcx.features().associated_const_equality @@ -333,10 +333,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { None }; - // For equality bounds, we want to blame the term (RHS) instead of the item (LHS) since + // For equality constraints, we want to blame the term (RHS) instead of the item (LHS) since // one can argue that that's more “intuitive” to the user. - let (span, expected_because_label, expected, got) = if let Some(binding) = binding - && let hir::TypeBindingKind::Equality { term } = binding.kind + let (span, expected_because_label, expected, got) = if let Some(constraint) = constraint + && let hir::AssocItemConstraintKind::Equality { term } = constraint.kind { let span = match term { hir::Term::Ty(ty) => ty.span, @@ -702,7 +702,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { pub(crate) fn complain_about_missing_assoc_tys( &self, associated_types: FxIndexMap>, - potential_assoc_types: Vec, + potential_assoc_types: Vec, trait_bounds: &[hir::PolyTraitRef<'_>], ) { if associated_types.values().all(|v| v.is_empty()) { @@ -791,8 +791,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let path = poly_trait_ref.trait_ref.path.segments.last()?; let args = path.args?; - Some(args.bindings.iter().filter_map(|binding| { - let ident = binding.ident; + Some(args.constraints.iter().filter_map(|constraint| { + let ident = constraint.ident; let trait_def = path.res.def_id(); let assoc_item = tcx.associated_items(trait_def).find_by_name_and_kind( tcx, @@ -1192,14 +1192,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } -/// Emits an error regarding forbidden type binding associations -pub fn prohibit_assoc_item_binding( +/// Emit an error for the given associated item constraint. +pub fn prohibit_assoc_item_constraint( tcx: TyCtxt<'_>, - binding: &hir::TypeBinding<'_>, + constraint: &hir::AssocItemConstraint<'_>, segment: Option<(DefId, &hir::PathSegment<'_>, Span)>, ) -> ErrorGuaranteed { - let mut err = tcx.dcx().create_err(AssocTypeBindingNotAllowed { - span: binding.span, + let mut err = tcx.dcx().create_err(AssocItemConstraintsNotAllowedHere { + span: constraint.span, fn_trait_expansion: if let Some((_, segment, span)) = segment && segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar { @@ -1217,13 +1217,12 @@ pub fn prohibit_assoc_item_binding( // otherwise suggest the removal of the binding. if let Some((def_id, segment, _)) = segment && segment.args().parenthesized == hir::GenericArgsParentheses::No - && let hir::TypeBindingKind::Equality { term } = binding.kind + && let hir::AssocItemConstraintKind::Equality { term } = constraint.kind { // Suggests removal of the offending binding let suggest_removal = |e: &mut Diag<'_>| { - let bindings = segment.args().bindings; + let constraints = segment.args().constraints; let args = segment.args().args; - let binding_span = binding.span; // Compute the span to remove based on the position // of the binding. We do that as follows: @@ -1236,26 +1235,21 @@ pub fn prohibit_assoc_item_binding( // the start of the next span or will simply be the // span encomassing everything within the generics brackets - let Some(binding_index) = bindings.iter().position(|b| b.hir_id == binding.hir_id) - else { + let Some(index) = constraints.iter().position(|b| b.hir_id == constraint.hir_id) else { bug!("a type binding exists but its HIR ID not found in generics"); }; - let preceding_span = if binding_index > 0 { - Some(bindings[binding_index - 1].span) + let preceding_span = if index > 0 { + Some(constraints[index - 1].span) } else { args.last().map(|a| a.span()) }; - let next_span = if binding_index < bindings.len() - 1 { - Some(bindings[binding_index + 1].span) - } else { - None - }; + let next_span = constraints.get(index + 1).map(|constraint| constraint.span); let removal_span = match (preceding_span, next_span) { - (Some(prec), _) => binding_span.with_lo(prec.hi()), - (None, Some(next)) => binding_span.with_hi(next.lo()), + (Some(prec), _) => constraint.span.with_lo(prec.hi()), + (None, Some(next)) => constraint.span.with_hi(next.lo()), (None, None) => { let Some(generics_span) = segment.args().span_ext() else { bug!("a type binding exists but generic span is empty"); @@ -1269,7 +1263,7 @@ pub fn prohibit_assoc_item_binding( if let Ok(suggestion) = tcx.sess.source_map().span_to_snippet(removal_span) { e.span_suggestion_verbose( removal_span, - "consider removing this type binding", + "consider removing this associated item binding", suggestion, Applicability::MaybeIncorrect, ); @@ -1281,7 +1275,7 @@ pub fn prohibit_assoc_item_binding( let suggest_direct_use = |e: &mut Diag<'_>, sp: Span| { if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(sp) { e.span_suggestion_verbose( - binding.span, + constraint.span, format!("to use `{snippet}` as a generic argument specify it directly"), snippet, Applicability::MaybeIncorrect, @@ -1289,11 +1283,11 @@ pub fn prohibit_assoc_item_binding( } }; - // Check if the type has a generic param with the - // same name as the assoc type name in type binding + // Check if the type has a generic param with the same name + // as the assoc type name in the associated item binding. let generics = tcx.generics_of(def_id); let matching_param = - generics.own_params.iter().find(|p| p.name.as_str() == binding.ident.as_str()); + generics.own_params.iter().find(|p| p.name.as_str() == constraint.ident.as_str()); // Now emit the appropriate suggestion if let Some(matching_param) = matching_param { @@ -1322,8 +1316,7 @@ pub(crate) fn fn_trait_to_string( ) -> String { let args = trait_segment .args - .as_ref() - .and_then(|args| args.args.get(0)) + .and_then(|args| args.args.first()) .and_then(|arg| match arg { hir::GenericArg::Type(ty) => match ty.kind { hir::TyKind::Tup(t) => t @@ -1334,7 +1327,7 @@ pub(crate) fn fn_trait_to_string( _ => tcx.sess.source_map().span_to_snippet(ty.span), } .map(|s| { - // `s.empty()` checks to see if the type is the unit tuple, if so we don't want a comma + // `is_empty()` checks to see if the type is the unit tuple, if so we don't want a comma if parenthesized || s.is_empty() { format!("({s})") } else { format!("({s},)") } }) .ok(), @@ -1344,20 +1337,17 @@ pub(crate) fn fn_trait_to_string( let ret = trait_segment .args() - .bindings + .constraints .iter() - .find_map(|b| match (b.ident.name == sym::Output, &b.kind) { - (true, hir::TypeBindingKind::Equality { term }) => { - let span = match term { - hir::Term::Ty(ty) => ty.span, - hir::Term::Const(c) => tcx.hir().span(c.hir_id), - }; - - (span != tcx.hir().span(trait_segment.hir_id)) - .then_some(tcx.sess.source_map().span_to_snippet(span).ok()) - .flatten() + .find_map(|c| { + if c.ident.name == sym::Output + && let Some(ty) = c.ty() + && ty.span != tcx.hir().span(trait_segment.hir_id) + { + tcx.sess.source_map().span_to_snippet(ty.span).ok() + } else { + None } - _ => None, }) .unwrap_or_else(|| "()".to_string()); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 7b67030836d1..26cabb69d25c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -1,6 +1,6 @@ use super::IsMethodCall; use crate::hir_ty_lowering::{ - errors::prohibit_assoc_item_binding, ExplicitLateBound, GenericArgCountMismatch, + errors::prohibit_assoc_item_constraint, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition, GenericArgsLowerer, }; use crate::structured_errors::{GenericArgsInfo, StructuredDiag, WrongNumberOfGenericArgs}; @@ -214,10 +214,11 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( if let Some(¶m) = params.peek() { if param.index == 0 { if let GenericParamDefKind::Type { .. } = param.kind { + assert_eq!(&args[..], &[]); args.push( self_ty .map(|ty| ty.into()) - .unwrap_or_else(|| ctx.inferred_kind(None, param, true)), + .unwrap_or_else(|| ctx.inferred_kind(&args, param, true)), ); params.next(); } @@ -267,7 +268,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( // Since this is a const impl, we need to insert a host arg at the end of // `PartialEq`'s generics, but this errors since `Rhs` isn't specified. // To work around this, we infer all arguments until we reach the host param. - args.push(ctx.inferred_kind(Some(&args), param, infer_args)); + args.push(ctx.inferred_kind(&args, param, infer_args)); params.next(); } (GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _) @@ -281,7 +282,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( GenericParamDefKind::Const { .. }, _, ) => { - args.push(ctx.provided_kind(param, arg)); + args.push(ctx.provided_kind(&args, param, arg)); args_iter.next(); params.next(); } @@ -292,7 +293,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( ) => { // We expected a lifetime argument, but got a type or const // argument. That means we're inferring the lifetimes. - args.push(ctx.inferred_kind(None, param, infer_args)); + args.push(ctx.inferred_kind(&args, param, infer_args)); force_infer_lt = Some((arg, param)); params.next(); } @@ -388,7 +389,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( (None, Some(¶m)) => { // If there are fewer arguments than parameters, it means // we're inferring the remaining arguments. - args.push(ctx.inferred_kind(Some(&args), param, infer_args)); + args.push(ctx.inferred_kind(&args, param, infer_args)); params.next(); } @@ -452,9 +453,9 @@ pub(crate) fn check_generic_arg_count( (gen_pos != GenericArgPosition::Type || seg.infer_args) && !gen_args.has_lifetime_params(); if gen_pos != GenericArgPosition::Type - && let Some(b) = gen_args.bindings.first() + && let Some(c) = gen_args.constraints.first() { - prohibit_assoc_item_binding(tcx, b, None); + prohibit_assoc_item_constraint(tcx, c, None); } let explicit_late_bound = @@ -474,16 +475,9 @@ pub(crate) fn check_generic_arg_count( return Ok(()); } - if provided_args > max_expected_args { - invalid_args.extend( - gen_args.args[max_expected_args..provided_args].iter().map(|arg| arg.span()), - ); - }; + invalid_args.extend(min_expected_args..provided_args); let gen_args_info = if provided_args > min_expected_args { - invalid_args.extend( - gen_args.args[min_expected_args..provided_args].iter().map(|arg| arg.span()), - ); let num_redundant_args = provided_args - min_expected_args; GenericArgsInfo::ExcessLifetimes { num_redundant_args } } else { @@ -538,11 +532,7 @@ pub(crate) fn check_generic_arg_count( let num_default_params = expected_max - expected_min; let gen_args_info = if provided > expected_max { - invalid_args.extend( - gen_args.args[args_offset + expected_max..args_offset + provided] - .iter() - .map(|arg| arg.span()), - ); + invalid_args.extend((expected_max..provided).map(|i| i + args_offset)); let num_redundant_args = provided - expected_max; // Provide extra note if synthetic arguments like `impl Trait` are specified. @@ -566,17 +556,19 @@ pub(crate) fn check_generic_arg_count( debug!(?gen_args_info); - let reported = WrongNumberOfGenericArgs::new( - tcx, - gen_args_info, - seg, - gen_params, - params_offset, - gen_args, - def_id, - ) - .diagnostic() - .emit_unless(gen_args.has_err()); + let reported = gen_args.has_err().unwrap_or_else(|| { + WrongNumberOfGenericArgs::new( + tcx, + gen_args_info, + seg, + gen_params, + params_offset, + gen_args, + def_id, + ) + .diagnostic() + .emit() + }); Err(reported) }; @@ -608,7 +600,7 @@ pub(crate) fn check_generic_arg_count( explicit_late_bound, correct: lifetimes_correct .and(args_correct) - .map_err(|reported| GenericArgCountMismatch { reported: Some(reported), invalid_args }), + .map_err(|reported| GenericArgCountMismatch { reported, invalid_args }), } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 997db338a43f..240a749de96a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -182,7 +182,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // For recursive traits, don't downgrade the error. (#119652) is_downgradable = false; } - tcx.check_is_object_safe(id) + tcx.is_object_safe(id) } _ => false, }) @@ -268,8 +268,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) { let mut parents = self.tcx().hir().parent_iter(self_ty.hir_id); - if let Some((_, hir::Node::TypeBinding(binding))) = parents.next() - && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(obj_ty) } = binding.kind + if let Some((_, hir::Node::AssocItemConstraint(constraint))) = parents.next() + && let Some(obj_ty) = constraint.ty() { if let Some((_, hir::Node::TraitRef(..))) = parents.next() && let Some((_, hir::Node::Ty(ty))) = parents.next() @@ -279,10 +279,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { return; } - let lo = if binding.gen_args.span_ext.is_dummy() { - binding.ident.span + let lo = if constraint.gen_args.span_ext.is_dummy() { + constraint.ident.span } else { - binding.gen_args.span_ext + constraint.gen_args.span_ext }; let hi = obj_ty.span; 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 3f66f971b171..2f54349d267a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -22,7 +22,7 @@ mod object_safety; use crate::bounds::Bounds; use crate::collect::HirPlaceholderCollector; use crate::errors::{AmbiguousLifetimeBound, WildPatTy}; -use crate::hir_ty_lowering::errors::{prohibit_assoc_item_binding, GenericsArgsErrExtend}; +use crate::hir_ty_lowering::errors::{prohibit_assoc_item_constraint, GenericsArgsErrExtend}; use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args}; use crate::middle::resolve_bound_vars as rbv; use crate::require_c_abi_if_c_variadic; @@ -215,12 +215,11 @@ pub(crate) enum GenericArgPosition { /// A marker denoting that the generic arguments that were /// provided did not match the respective generic parameters. -#[derive(Clone, Default, Debug)] +#[derive(Clone, Debug)] pub struct GenericArgCountMismatch { - /// Indicates whether a fatal error was reported (`Some`), or just a lint (`None`). - pub reported: Option, - /// A list of spans of arguments provided that were not valid. - pub invalid_args: Vec, + pub reported: ErrorGuaranteed, + /// A list of indices of arguments provided that were not valid. + pub invalid_args: Vec, } /// Decorates the result of a generic argument count mismatch @@ -240,13 +239,14 @@ pub trait GenericArgsLowerer<'a, 'tcx> { fn provided_kind( &mut self, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx>; fn inferred_kind( &mut self, - args: Option<&[ty::GenericArg<'tcx>]>, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, infer_args: bool, ) -> ty::GenericArg<'tcx>; @@ -324,8 +324,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { None, ty::BoundConstness::NotConst, ); - if let Some(b) = item_segment.args().bindings.first() { - prohibit_assoc_item_binding(self.tcx(), b, Some((def_id, item_segment, span))); + if let Some(c) = item_segment.args().constraints.first() { + prohibit_assoc_item_constraint(self.tcx(), c, Some((def_id, item_segment, span))); } args } @@ -335,7 +335,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// If this is a trait reference, you also need to pass the self type `self_ty`. /// The lowering process may involve applying defaulted type parameters. /// - /// Associated item bindings are not handled here! + /// Associated item constraints are not handled here! They are either lowered via + /// `lower_assoc_item_constraint` or rejected via `prohibit_assoc_item_constraint`. /// /// ### Example /// @@ -349,7 +350,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// which will have been resolved to a `def_id` /// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type /// parameters are returned in the `GenericArgsRef` - /// 4. Associated type bindings like `Output = u32` are contained in `generic_args.bindings`. + /// 4. Associated item constraints like `Output = u32` are contained in `generic_args.constraints`. /// /// Note that the type listing given here is *exactly* what the user provided. /// @@ -403,16 +404,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self_ty.is_some(), ); - if let Err(err) = &arg_count.correct - && let Some(reported) = err.reported - { - self.set_tainted_by_errors(reported); + if let Err(err) = &arg_count.correct { + self.set_tainted_by_errors(err.reported); } // Skip processing if type has no generic parameters. // Traits always have `Self` as a generic parameter, which means they will not return early - // here and so associated type bindings will be handled regardless of whether there are any - // non-`Self` generic parameters. + // here and so associated item constraints will be handled regardless of whether there are + // any non-`Self` generic parameters. if generics.is_own_empty() { return (tcx.mk_args(parent_args), arg_count); } @@ -424,6 +423,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, inferred_params: Vec, infer_args: bool, + incorrect_args: &'a Result<(), GenericArgCountMismatch>, } impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> { @@ -438,11 +438,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn provided_kind( &mut self, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { let tcx = self.lowerer.tcx(); + if let Err(incorrect) = self.incorrect_args { + if incorrect.invalid_args.contains(&(param.index as usize)) { + return param.to_error(tcx, preceding_args); + } + } + let mut handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| { if has_default { tcx.check_optional_stability( @@ -505,11 +512,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn inferred_kind( &mut self, - args: Option<&[ty::GenericArg<'tcx>]>, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, infer_args: bool, ) -> ty::GenericArg<'tcx> { let tcx = self.lowerer.tcx(); + + if let Err(incorrect) = self.incorrect_args { + if incorrect.invalid_args.contains(&(param.index as usize)) { + return param.to_error(tcx, preceding_args); + } + } match param.kind { GenericParamDefKind::Lifetime => self .lowerer @@ -528,15 +541,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { GenericParamDefKind::Type { has_default, .. } => { if !infer_args && has_default { // No type parameter provided, but a default exists. - let args = args.unwrap(); - if args.iter().any(|arg| match arg.unpack() { - GenericArgKind::Type(ty) => ty.references_error(), - _ => false, - }) { + if let Some(prev) = + preceding_args.iter().find_map(|arg| match arg.unpack() { + GenericArgKind::Type(ty) => ty.error_reported().err(), + _ => None, + }) + { // Avoid ICE #86756 when type error recovery goes awry. - return Ty::new_misc_error(tcx).into(); + return Ty::new_error(tcx, prev).into(); } - tcx.at(self.span).type_of(param.def_id).instantiate(tcx, args).into() + tcx.at(self.span) + .type_of(param.def_id) + .instantiate(tcx, preceding_args) + .into() } else if infer_args { self.lowerer.ty_infer(Some(param), self.span).into() } else { @@ -556,7 +573,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // FIXME(effects) see if we should special case effect params here if !infer_args && has_default { tcx.const_param_default(param.def_id) - .instantiate(tcx, args.unwrap()) + .instantiate(tcx, preceding_args) .into() } else { if infer_args { @@ -570,6 +587,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } } + if let ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst = constness + && generics.has_self + && !tcx.has_attr(def_id, sym::const_trait) + { + let reported = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { + span, + modifier: constness.as_str(), + }); + self.set_tainted_by_errors(reported); + arg_count.correct = Err(GenericArgCountMismatch { reported, invalid_args: vec![] }); + } let mut args_ctx = GenericArgsCtxt { lowerer: self, @@ -578,19 +606,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { generic_args: segment.args(), inferred_params: vec![], infer_args: segment.infer_args, + incorrect_args: &arg_count.correct, }; - if let ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst = constness - && generics.has_self - && !tcx.has_attr(def_id, sym::const_trait) - { - let e = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { - span, - modifier: constness.as_str(), - }); - self.set_tainted_by_errors(e); - arg_count.correct = - Err(GenericArgCountMismatch { reported: Some(e), invalid_args: vec![] }); - } let args = lower_generic_args( tcx, def_id, @@ -621,8 +638,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { None, ty::BoundConstness::NotConst, ); - if let Some(b) = item_segment.args().bindings.first() { - prohibit_assoc_item_binding(self.tcx(), b, Some((item_def_id, item_segment, span))); + if let Some(c) = item_segment.args().constraints.first() { + prohibit_assoc_item_constraint(self.tcx(), c, Some((item_def_id, item_segment, span))); } args } @@ -654,13 +671,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// *Polymorphic* in the sense that it may bind late-bound vars. /// - /// This may generate auxiliary bounds if the trait reference contains associated item bindings. + /// This may generate auxiliary bounds iff the trait reference contains associated item constraints. /// /// ### Example /// /// Given the trait ref `Iterator` and the self type `Ty`, this will add the /// - /// 1. *trait predicate* `` (known as `Foo: Iterator` in surface syntax) and the + /// 1. *trait predicate* `` (known as `Ty: Iterator` in the surface syntax) and the /// 2. *projection predicate* `::Item = u32` /// /// to `bounds`. @@ -714,27 +731,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(?poly_trait_ref); bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); - let mut dup_bindings = FxIndexMap::default(); - for binding in trait_segment.args().bindings { - // Don't register additional associated type bounds for negative bounds, - // since we should have emitten an error for them earlier, and they will - // not be well-formed! + let mut dup_constraints = FxIndexMap::default(); + for constraint in trait_segment.args().constraints { + // Don't register any associated item constraints for negative bounds, + // since we should have emitted an error for them earlier, and they + // would not be well-formed! if polarity != ty::PredicatePolarity::Positive { assert!( self.tcx().dcx().has_errors().is_some(), - "negative trait bounds should not have bindings", + "negative trait bounds should not have assoc item constraints", ); continue; } // Specify type to assert that error was already reported in `Err` case. - let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_binding( + let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_constraint( trait_ref.hir_ref_id, poly_trait_ref, - binding, + constraint, bounds, - &mut dup_bindings, - binding.span, + &mut dup_constraints, + constraint.span, only_self_bounds, ); // Okay to ignore `Err` because of `ErrorGuaranteed` (see above). @@ -766,8 +783,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Some(self_ty), constness, ); - if let Some(b) = trait_segment.args().bindings.first() { - prohibit_assoc_item_binding(self.tcx(), b, Some((trait_def_id, trait_segment, span))); + if let Some(c) = trait_segment.args().constraints.first() { + prohibit_assoc_item_constraint( + self.tcx(), + c, + Some((trait_def_id, trait_segment, span)), + ); } ty::TraitRef::new(self.tcx(), trait_def_id, generic_args) } @@ -849,7 +870,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// This fails if there is no such bound in the list of candidates or if there are multiple /// candidates in which case it reports ambiguity. - #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, binding), ret)] + #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, constraint), ret)] fn probe_single_bound_for_assoc_item( &self, all_candidates: impl Fn() -> I, @@ -858,7 +879,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_kind: ty::AssocKind, assoc_name: Ident, span: Span, - binding: Option<&hir::TypeBinding<'tcx>>, + constraint: Option<&hir::AssocItemConstraint<'tcx>>, ) -> Result, ErrorGuaranteed> where I: Iterator>, @@ -877,7 +898,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_kind, assoc_name, span, - binding, + constraint, ); self.set_tainted_by_errors(reported); return Err(reported); @@ -897,8 +918,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }); // Provide a more specific error code index entry for equality bindings. err.code( - if let Some(binding) = binding - && let hir::TypeBindingKind::Equality { .. } = binding.kind + if let Some(constraint) = constraint + && let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind { E0222 } else { @@ -906,7 +927,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }, ); - // FIXME(#97583): Resugar equality bounds to type/const bindings. + // FIXME(#97583): Print associated item bindings properly (i.e., not as equality predicates!). // FIXME: Turn this into a structured, translateable & more actionable suggestion. let mut where_bounds = vec![]; for bound in [bound, bound2].into_iter().chain(matching_candidates) { @@ -921,9 +942,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bound_span, format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),), ); - if let Some(binding) = binding { - match binding.kind { - hir::TypeBindingKind::Equality { term } => { + if let Some(constraint) = constraint { + match constraint.kind { + hir::AssocItemConstraintKind::Equality { term } => { let term: ty::Term<'_> = match term { hir::Term::Ty(ty) => self.lower_ty(ty).into(), hir::Term::Const(ct) => { @@ -937,7 +958,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { )); } // FIXME: Provide a suggestion. - hir::TypeBindingKind::Constraint { bounds: _ } => {} + hir::AssocItemConstraintKind::Bound { bounds: _ } => {} } } else { err.span_suggestion_verbose( @@ -1293,7 +1314,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .copied() .filter(|&(impl_, _)| { infcx.probe(|_| { - let ocx = ObligationCtxt::new(infcx); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); let self_ty = ocx.normalize(&ObligationCause::dummy(), param_env, self_ty); let impl_args = infcx.fresh_args_for_item(span, impl_); @@ -1540,8 +1561,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { for segment in segments { // Only emit the first error to avoid overloading the user with error messages. - if let Some(b) = segment.args().bindings.first() { - return Err(prohibit_assoc_item_binding(self.tcx(), b, None)); + if let Some(c) = segment.args().constraints.first() { + return Err(prohibit_assoc_item_constraint(self.tcx(), c, None)); } } diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 10101aa046e5..3e15fddf559f 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -67,7 +67,7 @@ fn diagnostic_hir_wf_check<'tcx>( impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { let infcx = self.tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let tcx_ty = self.icx.lower_ty(ty); // This visitor can walk into binders, resulting in the `tcx_ty` to diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 002be61196aa..5cc1ec71757b 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -86,6 +86,8 @@ fn enforce_impl_params_are_constrained( let impl_predicates = tcx.predicates_of(impl_def_id); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity); + impl_trait_ref.error_reported()?; + let mut input_parameters = cgp::parameters_for_impl(tcx, impl_self_ty, impl_trait_ref); cgp::identify_constrained_generic_params( tcx, 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 6967cb4d9d0b..f3ce3ab66553 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 @@ -196,7 +196,7 @@ fn get_impl_args( impl2_node: Node, ) -> Result<(GenericArgsRef<'_>, GenericArgsRef<'_>), ErrorGuaranteed> { let infcx = &tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(infcx); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); let param_env = tcx.param_env(impl1_def_id); let impl1_span = tcx.def_span(impl1_def_id); let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?; diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 9ddba7a6e7a9..5d435a8edf9f 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -489,7 +489,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { .in_definition_order() .filter(|item| item.kind == AssocKind::Type) .filter(|item| { - !self.gen_args.bindings.iter().any(|binding| binding.ident.name == item.name) + !self + .gen_args + .constraints + .iter() + .any(|constraint| constraint.ident.name == item.name) }) .map(|item| item.name.to_ident_string()) .collect() @@ -679,11 +683,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { (last_lt.span().shrink_to_hi(), false) }; let has_non_lt_args = self.num_provided_type_or_const_args() != 0; - let has_bindings = !self.gen_args.bindings.is_empty(); + let has_constraints = !self.gen_args.constraints.is_empty(); let sugg_prefix = if is_first { "" } else { ", " }; let sugg_suffix = - if is_first && (has_non_lt_args || has_bindings) { ", " } else { "" }; + if is_first && (has_non_lt_args || has_constraints) { ", " } else { "" }; let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}"); debug!("sugg: {:?}", sugg); @@ -741,7 +745,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let sugg_prefix = if is_first { "" } else { ", " }; let sugg_suffix = - if is_first && !self.gen_args.bindings.is_empty() { ", " } else { "" }; + if is_first && !self.gen_args.constraints.is_empty() { ", " } else { "" }; let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}"); debug!("sugg: {:?}", sugg); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 62abdf0afabf..a8e0b3fc0793 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -89,7 +89,7 @@ impl<'a> State<'a> { Node::Stmt(a) => self.print_stmt(a), Node::PathSegment(a) => self.print_path_segment(a), Node::Ty(a) => self.print_type(a), - Node::TypeBinding(a) => self.print_type_binding(a), + Node::AssocItemConstraint(a) => self.print_assoc_item_constraint(a), Node::TraitRef(a) => self.print_trait_ref(a), Node::Pat(a) => self.print_pat(a), Node::PatField(a) => self.print_patfield(a), @@ -1135,7 +1135,7 @@ impl<'a> State<'a> { self.print_ident(segment.ident); let generic_args = segment.args(); - if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() { + if !generic_args.args.is_empty() || !generic_args.constraints.is_empty() { self.print_generic_args(generic_args, true); } @@ -1676,9 +1676,9 @@ impl<'a> State<'a> { }); } - for binding in generic_args.bindings { + for constraint in generic_args.constraints { start_or_comma(self); - self.print_type_binding(binding); + self.print_assoc_item_constraint(constraint); } if !empty.get() { @@ -1686,13 +1686,15 @@ impl<'a> State<'a> { } } hir::GenericArgsParentheses::ParenSugar => { + let (inputs, output) = generic_args.paren_sugar_inputs_output().unwrap(); + self.word("("); - self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(ty)); + self.commasep(Inconsistent, inputs, |s, ty| s.print_type(ty)); self.word(")"); self.space_if_not_bol(); self.word_space("->"); - self.print_type(generic_args.bindings[0].ty()); + self.print_type(output); } hir::GenericArgsParentheses::ReturnTypeNotation => { self.word("(..)"); @@ -1700,19 +1702,19 @@ impl<'a> State<'a> { } } - fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) { - self.print_ident(binding.ident); - self.print_generic_args(binding.gen_args, false); + fn print_assoc_item_constraint(&mut self, constraint: &hir::AssocItemConstraint<'_>) { + self.print_ident(constraint.ident); + self.print_generic_args(constraint.gen_args, false); self.space(); - match binding.kind { - hir::TypeBindingKind::Equality { ref term } => { + match constraint.kind { + hir::AssocItemConstraintKind::Equality { ref term } => { self.word_space("="); match term { Term::Ty(ty) => self.print_type(ty), Term::Const(ref c) => self.print_anon_const(c), } } - hir::TypeBindingKind::Constraint { bounds } => { + hir::AssocItemConstraintKind::Bound { bounds } => { self.print_bounds(":", bounds); } } diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index c2e62e4c0035..a599e8d05fd3 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -207,10 +207,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let hir = self.tcx.hir(); // First, check that we're actually in the tail of a function. - let Some(body_id) = hir.maybe_body_owned_by(self.body_id) else { + let Some(body) = hir.maybe_body_owned_by(self.body_id) else { return; }; - let body = hir.body(body_id); let hir::ExprKind::Block(block, _) = body.value.kind else { return; }; diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 14a6177141c9..ac7ed3e26f97 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -485,7 +485,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Since this is a return parameter type it is safe to unwrap. - let ret_param_ty = projection.skip_binder().term.ty().unwrap(); + let ret_param_ty = projection.skip_binder().term.expect_type(); let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty); debug!(?ret_param_ty); @@ -956,7 +956,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let output_ty = self.resolve_vars_if_possible(predicate.term); debug!("deduce_future_output_from_projection: output_ty={:?}", output_ty); // This is a projection on a Fn trait so will always be a type. - Some(output_ty.ty().unwrap()) + Some(output_ty.expect_type()) } /// Converts the types that the user supplied, in case that doing diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 7916366ef089..fa147f9bfcfe 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -327,8 +327,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut expr_finder = FindExprs { hir_id: local_hir_id, uses: init.into_iter().collect() }; - let body = - hir.body(hir.maybe_body_owned_by(self.body_id).expect("expected item to have body")); + let body = hir.body_owned_by(self.body_id); expr_finder.visit_expr(body.value); // Replaces all of the variables in the given type with a fresh inference variable. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 364f0fec202a..3d88c4255245 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -909,8 +909,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the first place. assert_ne!(encl_item_id.def_id, encl_body_owner_id); - let encl_body_id = self.tcx.hir().body_owned_by(encl_body_owner_id); - let encl_body = self.tcx.hir().body(encl_body_id); + let encl_body = self.tcx.hir().body_owned_by(encl_body_owner_id); err.encl_body_span = Some(encl_body.value.span); err.encl_fn_span = Some(*encl_fn_span); @@ -1348,6 +1347,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(rcvr), rcvr_t, segment.ident, + expr.hir_id, SelfSource::MethodCall(rcvr), error, Some(args), @@ -3049,7 +3049,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.commit_if_ok(|snapshot| { let outer_universe = self.universe(); - let ocx = ObligationCtxt::new(self); + let ocx = ObligationCtxt::new_with_diagnostics(self); let impl_args = self.fresh_args_for_item(base_expr.span, impl_def_id); let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(self.tcx, impl_args); diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index e8533c68c793..7d6fdc9392ea 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -544,9 +544,8 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( root_ctxt: &'a TypeckRootCtxt<'tcx>, body_id: LocalDefId, ) -> UnordMap { - let body_id = + let body = root_ctxt.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); - let body = root_ctxt.tcx.hir().body(body_id); let mut res = UnordMap::default(); struct UnsafeInferVarsVisitor<'a, 'tcx, 'r> { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index b40bb74d7be1..58eb0c281798 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -832,6 +832,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None, ty.normalized, item_name, + hir_id, SelfSource::QPath(qself), error, args, @@ -1117,7 +1118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // to add defaults. If the user provided *too many* types, that's // a problem. - let mut infer_args_for_err = FxHashSet::default(); + let mut infer_args_for_err = None; let mut explicit_late_bound = ExplicitLateBound::No; for &GenericPathSegment(def_id, index) in &generic_segments { @@ -1135,9 +1136,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { explicit_late_bound = ExplicitLateBound::Yes; } - if let Err(GenericArgCountMismatch { reported: Some(e), .. }) = arg_count.correct { - infer_args_for_err.insert(index); - self.set_tainted_by_errors(e); // See issue #53251. + if let Err(GenericArgCountMismatch { reported, .. }) = arg_count.correct { + infer_args_for_err + .get_or_insert_with(|| (reported, FxHashSet::default())) + .1 + .insert(index); + self.set_tainted_by_errors(reported); // See issue #53251. } } @@ -1231,15 +1235,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let def_id = res.def_id(); - let arg_count = GenericArgCountResult { - explicit_late_bound, - correct: if infer_args_for_err.is_empty() { - Ok(()) - } else { - Err(GenericArgCountMismatch::default()) - }, + let (correct, infer_args_for_err) = match infer_args_for_err { + Some((reported, args)) => { + (Err(GenericArgCountMismatch { reported, invalid_args: vec![] }), args) + } + None => (Ok(()), Default::default()), }; + let arg_count = GenericArgCountResult { explicit_late_bound, correct }; + struct CtorGenericArgsCtxt<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, span: Span, @@ -1271,6 +1275,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn provided_kind( &mut self, + _preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { @@ -1313,7 +1318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn inferred_kind( &mut self, - args: Option<&[ty::GenericArg<'tcx>]>, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, infer_args: bool, ) -> ty::GenericArg<'tcx> { @@ -1327,7 +1332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If we have a default, then it doesn't matter that we're not // inferring the type arguments: we provide the default where any // is missing. - tcx.type_of(param.def_id).instantiate(tcx, args.unwrap()).into() + tcx.type_of(param.def_id).instantiate(tcx, preceding_args).into() } else { // If no type arguments were provided, we have to infer them. // This case also occurs as a result of some malformed input, e.g. @@ -1352,7 +1357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if !infer_args { return tcx .const_param_default(param.def_id) - .instantiate(tcx, args.unwrap()) + .instantiate(tcx, preceding_args) .into(); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 0d7f59c48715..caaf4142f7d1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -22,7 +22,6 @@ use rustc_hir::{ }; use rustc_hir_analysis::collect::suggest_impl_trait; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; -use rustc_infer::traits; use rustc_middle::lint::in_external_macro; use rustc_middle::middle::stability::EvalResult; use rustc_middle::span_bug; @@ -36,6 +35,7 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt; +use rustc_trait_selection::traits; use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; use rustc_trait_selection::traits::error_reporting::DefIdOrName; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; @@ -848,19 +848,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds && let Some(hir::PathSegment { args: Some(generic_args), .. }) = trait_ref.trait_ref.path.segments.last() - && let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args - && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } = - ty_binding.kind + && let [constraint] = generic_args.constraints + && let Some(ty) = constraint.ty() { // Check if async function's return type was omitted. // Don't emit suggestions if the found type is `impl Future<...>`. debug!(?found); if found.is_suggestable(self.tcx, false) { - if term.span.is_empty() { + if ty.span.is_empty() { err.subdiagnostic( self.dcx(), errors::AddReturnTypeSuggestion::Add { - span: term.span, + span: ty.span, found: found.to_string(), }, ); @@ -868,10 +867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { err.subdiagnostic( self.dcx(), - errors::ExpectedReturnTypeLabel::Other { - span: term.span, - expected, - }, + errors::ExpectedReturnTypeLabel::Other { span: ty.span, expected }, ); } } @@ -1973,8 +1969,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { *expr } else { let body_def_id = hir.enclosing_body_owner(expr.hir_id); - let body_id = hir.body_owned_by(body_def_id); - let body = hir.body(body_id); + let body = hir.body_owned_by(body_def_id); // Get tail expr of the body match body.value.kind { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 9c64f9475cf1..0825e6613730 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -383,6 +383,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn provided_kind( &mut self, + _preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { @@ -419,7 +420,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn inferred_kind( &mut self, - _args: Option<&[ty::GenericArg<'tcx>]>, + _preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, _infer_args: bool, ) -> ty::GenericArg<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 97a74b55c535..12ced49f92ff 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1390,7 +1390,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let mut result = ProbeResult::Match; let cause = &self.misc(self.span); - let ocx = ObligationCtxt::new(self); + let ocx = ObligationCtxt::new_with_diagnostics(self); let mut trait_predicate = None; let (mut xform_self_ty, mut xform_ret_ty); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 54af8354c4c7..daaaf630f2c4 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -191,6 +191,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_opt: Option<&'tcx hir::Expr<'tcx>>, rcvr_ty: Ty<'tcx>, item_name: Ident, + expr_id: hir::HirId, source: SelfSource<'tcx>, error: MethodError<'tcx>, args: Option<&'tcx [hir::Expr<'tcx>]>, @@ -216,6 +217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_opt, rcvr_ty, item_name, + expr_id, source, args, sugg_span, @@ -505,9 +507,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::def::Res::Local(recv_id) = path.res && let Some(segment) = path.segments.first() { - let map = self.infcx.tcx.hir(); - let body_id = self.tcx.hir().body_owned_by(self.body_id); - let body = map.body(body_id); + let body = self.tcx.hir().body_owned_by(self.body_id); if let Node::Expr(call_expr) = self.tcx.parent_hir_node(rcvr.hir_id) { let mut let_visitor = LetVisitor { @@ -518,7 +518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method_name, sugg_let: None, }; - let_visitor.visit_body(body); + let_visitor.visit_body(&body); if let Some(sugg_let) = let_visitor.sugg_let && let Some(self_ty) = self.node_ty_opt(sugg_let.init_hir_id) { @@ -551,6 +551,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_opt: Option<&'tcx hir::Expr<'tcx>>, rcvr_ty: Ty<'tcx>, item_name: Ident, + expr_id: hir::HirId, source: SelfSource<'tcx>, args: Option<&'tcx [hir::Expr<'tcx>]>, sugg_span: Span, @@ -683,7 +684,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if matches!(source, SelfSource::QPath(_)) && args.is_some() { - self.find_builder_fn(&mut err, rcvr_ty); + self.find_builder_fn(&mut err, rcvr_ty, expr_id); } if tcx.ty_is_opaque_future(rcvr_ty) && item_name.name == sym::poll { @@ -1944,7 +1945,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Look at all the associated functions without receivers in the type's inherent impls /// to look for builders that return `Self`, `Option` or `Result`. - fn find_builder_fn(&self, err: &mut Diag<'_>, rcvr_ty: Ty<'tcx>) { + fn find_builder_fn(&self, err: &mut Diag<'_>, rcvr_ty: Ty<'tcx>, expr_id: hir::HirId) { let ty::Adt(adt_def, _) = rcvr_ty.kind() else { return; }; @@ -1953,8 +1954,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut items = impls .iter() .flat_map(|i| self.tcx.associated_items(i).in_definition_order()) - // Only assoc fn with no receivers. - .filter(|item| matches!(item.kind, ty::AssocKind::Fn) && !item.fn_has_self_parameter) + // Only assoc fn with no receivers and only if + // they are resolvable + .filter(|item| { + matches!(item.kind, ty::AssocKind::Fn) + && !item.fn_has_self_parameter + && self + .probe_for_name( + Mode::Path, + item.ident(self.tcx), + None, + IsSuggestion(true), + rcvr_ty, + expr_id, + ProbeScope::TraitsInScope, + ) + .is_ok() + }) .filter_map(|item| { // Only assoc fns that return `Self`, `Option` or `Result`. let ret_ty = self @@ -2429,9 +2445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { seg1.ident.span, StashKey::CallAssocMethod, |err| { - let map = self.infcx.tcx.hir(); - let body_id = self.tcx.hir().body_owned_by(self.body_id); - let body = map.body(body_id); + let body = self.tcx.hir().body_owned_by(self.body_id); struct LetVisitor { ident_name: Symbol, } @@ -2453,7 +2467,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Node::Expr(call_expr) = self.tcx.parent_hir_node(seg1.hir_id) && let ControlFlow::Break(Some(expr)) = - (LetVisitor { ident_name: seg1.ident.name }).visit_body(body) + (LetVisitor { ident_name: seg1.ident.name }).visit_body(&body) && let Some(self_ty) = self.node_ty_opt(expr.hir_id) { let probe = self.lookup_probe_for_diagnostic( diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 25b74dca12fc..d774ae2146aa 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -928,7 +928,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (obligation, _) = self.obligation_for_method(cause, trait_did, lhs_ty, Some(input_types)); // FIXME: This should potentially just add the obligation to the `FnCtxt` - let ocx = ObligationCtxt::new(&self.infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&self.infcx); ocx.register_obligation(obligation); Err(ocx.select_all_or_error()) } diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index 19d6481cc1b8..28745af3a530 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -11,7 +11,9 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::LocalDefIdMap; use rustc_span::Span; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; -use rustc_trait_selection::traits::{self, PredicateObligation, TraitEngine, TraitEngineExt as _}; +use rustc_trait_selection::traits::{ + self, FulfillmentError, PredicateObligation, TraitEngine, TraitEngineExt as _, +}; use std::cell::RefCell; use std::ops::Deref; @@ -34,7 +36,7 @@ pub(crate) struct TypeckRootCtxt<'tcx> { pub(super) locals: RefCell>>, - pub(super) fulfillment_cx: RefCell>>, + pub(super) fulfillment_cx: RefCell>>>, /// Some additional `Sized` obligations badly affect type inference. /// These obligations are added in a later stage of typeck. @@ -83,7 +85,7 @@ impl<'tcx> TypeckRootCtxt<'tcx> { TypeckRootCtxt { typeck_results, - fulfillment_cx: RefCell::new(>::new(&infcx)), + fulfillment_cx: RefCell::new(>::new(&infcx)), infcx, locals: RefCell::new(Default::default()), deferred_sized_obligations: RefCell::new(Vec::new()), @@ -158,7 +160,7 @@ impl<'tcx> TypeckRootCtxt<'tcx> { { // If the projection predicate (Foo::Bar == X) has X as a non-TyVid, // we need to make it into one. - if let Some(vid) = predicate.term.ty().and_then(|ty| ty.ty_vid()) { + if let Some(vid) = predicate.term.as_type().and_then(|ty| ty.ty_vid()) { debug!("infer_var_info: {:?}.output = true", vid); infer_var_info.entry(vid).or_default().output = true; } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 31caa52d2671..e337105f0110 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -865,6 +865,7 @@ impl<'cx, 'tcx> TypeFolder> for Resolver<'cx, 'tcx> { self.handle_term(ct, ty::Const::outer_exclusive_binder, |tcx, guar| { ty::Const::new_error(tcx, guar, ct.ty()) }) + .super_fold_with(self) } fn fold_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 1732913e1915..d7dd6a1e7cf5 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -16,7 +16,7 @@ use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult}; use crate::traits::query::NoSolution; use crate::traits::{Obligation, ObligationCause, PredicateObligation}; -use crate::traits::{TraitEngine, TraitEngineExt}; +use crate::traits::{ScrubbedTraitError, TraitEngine}; use rustc_data_structures::captures::Captures; use rustc_index::Idx; use rustc_index::IndexVec; @@ -54,7 +54,7 @@ impl<'tcx> InferCtxt<'tcx> { &self, inference_vars: CanonicalVarValues<'tcx>, answer: T, - fulfill_cx: &mut dyn TraitEngine<'tcx>, + fulfill_cx: &mut dyn TraitEngine<'tcx, ScrubbedTraitError<'tcx>>, ) -> Result, NoSolution> where T: Debug + TypeFoldable>, @@ -101,7 +101,7 @@ impl<'tcx> InferCtxt<'tcx> { &self, inference_vars: CanonicalVarValues<'tcx>, answer: T, - fulfill_cx: &mut dyn TraitEngine<'tcx>, + fulfill_cx: &mut dyn TraitEngine<'tcx, ScrubbedTraitError<'tcx>>, ) -> Result, NoSolution> where T: Debug + TypeFoldable>, @@ -109,19 +109,13 @@ impl<'tcx> InferCtxt<'tcx> { let tcx = self.tcx; // Select everything, returning errors. - let true_errors = fulfill_cx.select_where_possible(self); - debug!("true_errors = {:#?}", true_errors); + let errors = fulfill_cx.select_all_or_error(self); - if !true_errors.is_empty() { - // FIXME -- we don't indicate *why* we failed to solve - debug!("make_query_response: true_errors={:#?}", true_errors); + // True error! + if errors.iter().any(|e| e.is_true_error()) { return Err(NoSolution); } - // Anything left unselected *now* must be an ambiguity. - let ambig_errors = fulfill_cx.select_all_or_error(self); - debug!("ambig_errors = {:#?}", ambig_errors); - let region_obligations = self.take_registered_region_obligations(); debug!(?region_obligations); let region_constraints = self.with_region_constraints(|region_constraints| { @@ -135,8 +129,7 @@ impl<'tcx> InferCtxt<'tcx> { }); debug!(?region_constraints); - let certainty = - if ambig_errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous }; + let certainty = if errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous }; let opaque_types = self.take_opaque_types_for_query_response(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 95fbc1e66cea..fe0a246abbc6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -425,7 +425,7 @@ impl<'tcx> InferCtxt<'tcx> { ty::ClauseKind::Projection(projection_predicate) if projection_predicate.projection_term.def_id == item_def_id => { - projection_predicate.term.ty() + projection_predicate.term.as_type() } _ => None, }) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 98fd7906e700..fb8c843f3095 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -457,10 +457,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, arg); - if let Some(body_id) = self.tcx.hir().maybe_body_owned_by( + if let Some(body) = self.tcx.hir().maybe_body_owned_by( self.tcx.typeck_root_def_id(body_def_id.to_def_id()).expect_local(), ) { - let expr = self.tcx.hir().body(body_id).value; + let expr = body.value; local_visitor.visit_expr(expr); } @@ -1163,7 +1163,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { /// For closures, we first visit the parameters and then the content, /// as we prefer those. - fn visit_body(&mut self, body: &'tcx Body<'tcx>) { + fn visit_body(&mut self, body: &Body<'tcx>) { for param in body.params { debug!( "param: span {:?}, ty_span {:?}, pat.span {:?}", diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 5f3f1081ca8f..83145e4f7b27 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -62,14 +62,13 @@ pub fn find_param_with_region<'tcx>( _ => {} } - let body_id = hir.maybe_body_owned_by(def_id)?; + let body = hir.maybe_body_owned_by(def_id)?; - let owner_id = hir.body_owner(body_id); + let owner_id = hir.body_owner(body.id()); let fn_decl = hir.fn_decl_by_hir_id(owner_id)?; let poly_fn_sig = tcx.fn_sig(id).instantiate_identity(); let fn_sig = tcx.liberate_late_bound_regions(id, poly_fn_sig); - let body = hir.body(body_id); body.params .iter() .take(if fn_sig.c_variadic { diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index f4514c235084..19ef2d61fca3 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -182,7 +182,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag.span_label(p_span, format!("{expected}this type parameter")); } diag.help("type parameters must be constrained to match other types"); - if tcx.sess.teach(diag.code.unwrap()) { + if diag.code.is_some_and(|code| tcx.sess.teach(code)) { diag.help( "given a type parameter `T` and a method `foo`: ``` @@ -663,7 +663,7 @@ impl Trait for X { https://doc.rust-lang.org/book/ch19-03-advanced-traits.html", ); } - if tcx.sess.teach(diag.code.unwrap()) { + if diag.code.is_some_and(|code| tcx.sess.teach(code)) { diag.help( "given an associated type `T` and a method `foo`: ``` diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 75479decebcd..17fb760295ae 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -578,16 +578,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { walk_stmt(self, ex) } } - - fn visit_body(&mut self, body: &'v hir::Body<'v>) -> Self::Result { - hir::intravisit::walk_body(self, body) - } } - self.tcx.hir().maybe_body_owned_by(cause.body_id).and_then(|body_id| { - let body = self.tcx.hir().body(body_id); + self.tcx.hir().maybe_body_owned_by(cause.body_id).and_then(|body| { IfVisitor { err_span: span, found_if: false } - .visit_body(body) + .visit_body(&body) .is_break() .then(|| TypeErrorAdditionalDiags::AddLetForLetChains { span: span.shrink_to_lo() }) }) diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index b2d89523ea84..a3c8d5f4251e 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -33,7 +33,6 @@ use super::InferCtxt; use rustc_data_structures::fx::FxHashMap; use rustc_middle::bug; -use rustc_middle::infer::unify_key::ToType; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt}; use std::collections::hash_map::Entry; @@ -204,22 +203,27 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { ty::IntVar(v) => { let mut inner = self.infcx.inner.borrow_mut(); - let input = inner - .int_unification_table() - .probe_value(v) - .map(|v| v.to_type(self.infcx.tcx)) - .ok_or_else(|| ty::IntVar(inner.int_unification_table().find(v))); + let value = inner.int_unification_table().probe_value(v); + let input = match value { + ty::IntVarValue::IntType(ty) => Ok(Ty::new_int(self.infcx.tcx, ty)), + ty::IntVarValue::UintType(ty) => Ok(Ty::new_uint(self.infcx.tcx, ty)), + ty::IntVarValue::Unknown => { + Err(ty::IntVar(inner.int_unification_table().find(v))) + } + }; drop(inner); Some(self.freshen_ty(input, |n| Ty::new_fresh_int(self.infcx.tcx, n))) } ty::FloatVar(v) => { let mut inner = self.infcx.inner.borrow_mut(); - let input = inner - .float_unification_table() - .probe_value(v) - .map(|v| v.to_type(self.infcx.tcx)) - .ok_or_else(|| ty::FloatVar(inner.float_unification_table().find(v))); + let value = inner.float_unification_table().probe_value(v); + let input = match value { + ty::FloatVarValue::Known(ty) => Ok(Ty::new_float(self.infcx.tcx, ty)), + ty::FloatVarValue::Unknown => { + Err(ty::FloatVar(inner.float_unification_table().find(v))) + } + }; drop(inner); Some(self.freshen_ty(input, |n| Ty::new_fresh_float(self.infcx.tcx, n))) } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c8bb6cf5f9b4..e9a4cc3e04b6 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -12,7 +12,7 @@ pub use SubregionOrigin::*; pub use ValuePairs::*; use crate::traits::{ - self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine, TraitEngineExt, + self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine, }; use error_reporting::TypeErrCtxt; use free_regions::RegionRelations; @@ -29,9 +29,9 @@ use rustc_errors::{Diag, DiagCtxt, ErrorGuaranteed}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::extension; use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::infer::unify_key::ConstVariableValue; use rustc_middle::infer::unify_key::EffectVarValue; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ToType}; use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey}; use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult}; use rustc_middle::mir::ConstraintCategory; @@ -41,7 +41,7 @@ use rustc_middle::ty::fold::BoundVarReplacerDelegate; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::visit::TypeVisitableExt; -use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt}; +use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt}; use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid}; use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef}; use rustc_middle::{bug, span_bug}; @@ -424,8 +424,8 @@ pub enum ValuePairs<'tcx> { impl<'tcx> ValuePairs<'tcx> { pub fn ty(&self) -> Option<(Ty<'tcx>, Ty<'tcx>)> { if let ValuePairs::Terms(ExpectedFound { expected, found }) = self - && let Some(expected) = expected.ty() - && let Some(found) = found.ty() + && let Some(expected) = expected.as_type() + && let Some(found) = found.as_type() { Some((expected, found)) } else { @@ -587,6 +587,7 @@ pub enum FixupError { UnresolvedFloatTy(FloatVid), UnresolvedTy(TyVid), UnresolvedConst(ConstVid), + UnresolvedEffect(EffectVid), } /// See the `region_obligations` field for more information. @@ -614,6 +615,7 @@ impl fmt::Display for FixupError { ), UnresolvedTy(_) => write!(f, "unconstrained type"), UnresolvedConst(_) => write!(f, "unconstrained const value"), + UnresolvedEffect(_) => write!(f, "unconstrained effect value"), } } } @@ -737,10 +739,10 @@ impl<'tcx> InferCtxtBuilder<'tcx> { impl<'tcx, T> InferOk<'tcx, T> { /// Extracts `value`, registering any obligations into `fulfill_cx`. - pub fn into_value_registering_obligations( + pub fn into_value_registering_obligations( self, infcx: &InferCtxt<'tcx>, - fulfill_cx: &mut dyn TraitEngine<'tcx>, + fulfill_cx: &mut dyn TraitEngine<'tcx, E>, ) -> T { let InferOk { value, obligations } = self; fulfill_cx.register_predicate_obligations(infcx, obligations); @@ -811,13 +813,13 @@ impl<'tcx> InferCtxt<'tcx> { vars.extend( (0..inner.int_unification_table().len()) .map(|i| ty::IntVid::from_u32(i as u32)) - .filter(|&vid| inner.int_unification_table().probe_value(vid).is_none()) + .filter(|&vid| inner.int_unification_table().probe_value(vid).is_unknown()) .map(|v| Ty::new_int_var(self.tcx, v)), ); vars.extend( (0..inner.float_unification_table().len()) .map(|i| ty::FloatVid::from_u32(i as u32)) - .filter(|&vid| inner.float_unification_table().probe_value(vid).is_none()) + .filter(|&vid| inner.float_unification_table().probe_value(vid).is_unknown()) .map(|v| Ty::new_float_var(self.tcx, v)), ); vars @@ -1025,14 +1027,28 @@ impl<'tcx> InferCtxt<'tcx> { ty::Const::new_var(self.tcx, vid, ty) } + pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid { + self.inner + .borrow_mut() + .const_unification_table() + .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() }) + .vid + } + + fn next_int_var_id(&self) -> IntVid { + self.inner.borrow_mut().int_unification_table().new_key(ty::IntVarValue::Unknown) + } + pub fn next_int_var(&self) -> Ty<'tcx> { - let vid = self.inner.borrow_mut().int_unification_table().new_key(None); - Ty::new_int_var(self.tcx, vid) + Ty::new_int_var(self.tcx, self.next_int_var_id()) + } + + fn next_float_var_id(&self) -> FloatVid { + self.inner.borrow_mut().float_unification_table().new_key(ty::FloatVarValue::Unknown) } pub fn next_float_var(&self) -> Ty<'tcx> { - let vid = self.inner.borrow_mut().float_unification_table().new_key(None); - Ty::new_float_var(self.tcx, vid) + Ty::new_float_var(self.tcx, self.next_float_var_id()) } /// Creates a fresh region variable with the next available index. @@ -1234,45 +1250,44 @@ impl<'tcx> InferCtxt<'tcx> { } pub fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> { - if let ty::Infer(v) = ty.kind() { self.fold_infer_ty(*v).unwrap_or(ty) } else { ty } - } + if let ty::Infer(v) = *ty.kind() { + match v { + ty::TyVar(v) => { + // Not entirely obvious: if `typ` is a type variable, + // it can be resolved to an int/float variable, which + // can then be recursively resolved, hence the + // recursion. Note though that we prevent type + // variables from unifying to other type variables + // directly (though they may be embedded + // structurally), and we prevent cycles in any case, + // so this recursion should always be of very limited + // depth. + // + // Note: if these two lines are combined into one we get + // dynamic borrow errors on `self.inner`. + let known = self.inner.borrow_mut().type_variables().probe(v).known(); + known.map_or(ty, |t| self.shallow_resolve(t)) + } - // This is separate from `shallow_resolve` to keep that method small and inlinable. - #[inline(never)] - fn fold_infer_ty(&self, v: InferTy) -> Option> { - match v { - ty::TyVar(v) => { - // Not entirely obvious: if `typ` is a type variable, - // it can be resolved to an int/float variable, which - // can then be recursively resolved, hence the - // recursion. Note though that we prevent type - // variables from unifying to other type variables - // directly (though they may be embedded - // structurally), and we prevent cycles in any case, - // so this recursion should always be of very limited - // depth. - // - // Note: if these two lines are combined into one we get - // dynamic borrow errors on `self.inner`. - let known = self.inner.borrow_mut().type_variables().probe(v).known(); - known.map(|t| self.shallow_resolve(t)) + ty::IntVar(v) => { + match self.inner.borrow_mut().int_unification_table().probe_value(v) { + ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty), + ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty), + ty::IntVarValue::Unknown => ty, + } + } + + ty::FloatVar(v) => { + match self.inner.borrow_mut().float_unification_table().probe_value(v) { + ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty), + ty::FloatVarValue::Unknown => ty, + } + } + + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => ty, } - - ty::IntVar(v) => self - .inner - .borrow_mut() - .int_unification_table() - .probe_value(v) - .map(|v| v.to_type(self.tcx)), - - ty::FloatVar(v) => self - .inner - .borrow_mut() - .float_unification_table() - .probe_value(v) - .map(|v| v.to_type(self.tcx)), - - ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => None, + } else { + ty } } @@ -1321,10 +1336,13 @@ impl<'tcx> InferCtxt<'tcx> { /// or else the root int var in the unification table. pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> { let mut inner = self.inner.borrow_mut(); - if let Some(value) = inner.int_unification_table().probe_value(vid) { - value.to_type(self.tcx) - } else { - Ty::new_int_var(self.tcx, inner.int_unification_table().find(vid)) + let value = inner.int_unification_table().probe_value(vid); + match value { + ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty), + ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty), + ty::IntVarValue::Unknown => { + Ty::new_int_var(self.tcx, inner.int_unification_table().find(vid)) + } } } @@ -1332,10 +1350,12 @@ impl<'tcx> InferCtxt<'tcx> { /// or else the root float var in the unification table. pub fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> { let mut inner = self.inner.borrow_mut(); - if let Some(value) = inner.float_unification_table().probe_value(vid) { - value.to_type(self.tcx) - } else { - Ty::new_float_var(self.tcx, inner.float_unification_table().find(vid)) + let value = inner.float_unification_table().probe_value(vid); + match value { + ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty), + ty::FloatVarValue::Unknown => { + Ty::new_float_var(self.tcx, inner.float_unification_table().find(vid)) + } } } @@ -1626,7 +1646,7 @@ impl<'tcx> InferCtxt<'tcx> { // If `inlined_probe_value` returns a value it's always a // `ty::Int(_)` or `ty::UInt(_)`, which never matches a // `ty::Infer(_)`. - self.inner.borrow_mut().int_unification_table().inlined_probe_value(v).is_some() + self.inner.borrow_mut().int_unification_table().inlined_probe_value(v).is_known() } TyOrConstInferVar::TyFloat(v) => { @@ -1634,7 +1654,7 @@ impl<'tcx> InferCtxt<'tcx> { // `ty::Float(_)`, which never matches a `ty::Infer(_)`. // // Not `inlined_probe_value(v)` because this call site is colder. - self.inner.borrow_mut().float_unification_table().probe_value(v).is_some() + self.inner.borrow_mut().float_unification_table().probe_value(v).is_known() } TyOrConstInferVar::Const(v) => { diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 6b41e4506846..b193f4bcede6 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -22,12 +22,11 @@ use super::glb::Glb; use super::lub::Lub; use super::type_relating::TypeRelating; use super::StructurallyRelateAliases; -use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, TypeTrace}; +use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; use rustc_middle::bug; use rustc_middle::infer::unify_key::EffectVarValue; -use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::error::{ExpectedFound, TypeError}; +use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::{RelateResult, TypeRelation}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast}; use rustc_middle::ty::{IntType, UintType}; @@ -69,40 +68,38 @@ impl<'tcx> InferCtxt<'tcx> { match (a.kind(), b.kind()) { // Relate integral variables to other types (&ty::Infer(ty::IntVar(a_id)), &ty::Infer(ty::IntVar(b_id))) => { - self.inner - .borrow_mut() - .int_unification_table() - .unify_var_var(a_id, b_id) - .map_err(|e| int_unification_error(true, e))?; + self.inner.borrow_mut().int_unification_table().union(a_id, b_id); Ok(a) } (&ty::Infer(ty::IntVar(v_id)), &ty::Int(v)) => { - self.unify_integral_variable(true, v_id, IntType(v)) + self.unify_integral_variable(v_id, IntType(v)); + Ok(b) } (&ty::Int(v), &ty::Infer(ty::IntVar(v_id))) => { - self.unify_integral_variable(false, v_id, IntType(v)) + self.unify_integral_variable(v_id, IntType(v)); + Ok(a) } (&ty::Infer(ty::IntVar(v_id)), &ty::Uint(v)) => { - self.unify_integral_variable(true, v_id, UintType(v)) + self.unify_integral_variable(v_id, UintType(v)); + Ok(b) } (&ty::Uint(v), &ty::Infer(ty::IntVar(v_id))) => { - self.unify_integral_variable(false, v_id, UintType(v)) + self.unify_integral_variable(v_id, UintType(v)); + Ok(a) } // Relate floating-point variables to other types (&ty::Infer(ty::FloatVar(a_id)), &ty::Infer(ty::FloatVar(b_id))) => { - self.inner - .borrow_mut() - .float_unification_table() - .unify_var_var(a_id, b_id) - .map_err(|e| float_unification_error(true, e))?; + self.inner.borrow_mut().float_unification_table().union(a_id, b_id); Ok(a) } (&ty::Infer(ty::FloatVar(v_id)), &ty::Float(v)) => { - self.unify_float_variable(true, v_id, v) + self.unify_float_variable(v_id, ty::FloatVarValue::Known(v)); + Ok(b) } (&ty::Float(v), &ty::Infer(ty::FloatVar(v_id))) => { - self.unify_float_variable(false, v_id, v) + self.unify_float_variable(v_id, ty::FloatVarValue::Known(v)); + Ok(a) } // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm. @@ -170,12 +167,6 @@ impl<'tcx> InferCtxt<'tcx> { let a = self.shallow_resolve_const(a); let b = self.shallow_resolve_const(b); - // It is always an error if the types of two constants that are related are not equal. - let InferOk { value: (), obligations } = self - .at(&ObligationCause::dummy_with_span(relation.span()), relation.param_env()) - .eq(DefineOpaqueTypes::No, a.ty(), b.ty())?; - relation.register_obligations(obligations); - match (a.kind(), b.kind()) { ( ty::ConstKind::Infer(InferConst::Var(a_vid)), @@ -251,35 +242,14 @@ impl<'tcx> InferCtxt<'tcx> { } } - fn unify_integral_variable( - &self, - vid_is_expected: bool, - vid: ty::IntVid, - val: ty::IntVarValue, - ) -> RelateResult<'tcx, Ty<'tcx>> { - self.inner - .borrow_mut() - .int_unification_table() - .unify_var_value(vid, Some(val)) - .map_err(|e| int_unification_error(vid_is_expected, e))?; - match val { - IntType(v) => Ok(Ty::new_int(self.tcx, v)), - UintType(v) => Ok(Ty::new_uint(self.tcx, v)), - } + #[inline(always)] + fn unify_integral_variable(&self, vid: ty::IntVid, val: ty::IntVarValue) { + self.inner.borrow_mut().int_unification_table().union_value(vid, val); } - fn unify_float_variable( - &self, - vid_is_expected: bool, - vid: ty::FloatVid, - val: ty::FloatTy, - ) -> RelateResult<'tcx, Ty<'tcx>> { - self.inner - .borrow_mut() - .float_unification_table() - .unify_var_value(vid, Some(ty::FloatVarValue(val))) - .map_err(|e| float_unification_error(vid_is_expected, e))?; - Ok(Ty::new_float(self.tcx, val)) + #[inline(always)] + fn unify_float_variable(&self, vid: ty::FloatVid, val: ty::FloatVarValue) { + self.inner.borrow_mut().float_unification_table().union_value(vid, val); } fn unify_effect_variable(&self, vid: ty::EffectVid, val: ty::Const<'tcx>) -> ty::Const<'tcx> { @@ -357,19 +327,3 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { /// Register `AliasRelate` obligation(s) that both types must be related to each other. fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>); } - -fn int_unification_error<'tcx>( - a_is_expected: bool, - v: (ty::IntVarValue, ty::IntVarValue), -) -> TypeError<'tcx> { - let (a, b) = v; - TypeError::IntMismatch(ExpectedFound::new(a_is_expected, a, b)) -} - -fn float_unification_error<'tcx>( - a_is_expected: bool, - v: (ty::FloatVarValue, ty::FloatVarValue), -) -> TypeError<'tcx> { - let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v; - TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b)) -} diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 38e25b0d9b68..c0c51a2820b3 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -64,8 +64,8 @@ where let infcx = this.infcx(); - let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a); - let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b); + let a = infcx.shallow_resolve(a); + let b = infcx.shallow_resolve(b); match (a.kind(), b.kind()) { // If one side is known to be a variable and one is not, diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 21064fff97f7..e55a58788212 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -80,8 +80,8 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> { } let infcx = self.fields.infcx; - let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a); - let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b); + let a = infcx.shallow_resolve(a); + let b = infcx.shallow_resolve(b); match (a.kind(), b.kind()) { (&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => { diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 21ef2e89523f..830d79f52b94 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -167,6 +167,9 @@ impl<'a, 'tcx> FallibleTypeFolder> for FullTypeResolver<'a, 'tcx> { ty::ConstKind::Infer(InferConst::Fresh(_)) => { bug!("Unexpected const in full const resolver: {:?}", c); } + ty::ConstKind::Infer(InferConst::EffectVar(evid)) => { + return Err(FixupError::UnresolvedEffect(evid)); + } _ => {} } c.try_super_fold_with(self) diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index e27e6a0a4a15..026b2c1b905e 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -1,13 +1,38 @@ +use std::fmt::Debug; + use crate::infer::InferCtxt; use crate::traits::Obligation; use rustc_hir::def_id::DefId; -use rustc_macros::extension; use rustc_middle::ty::{self, Ty, Upcast}; -use super::FulfillmentError; use super::{ObligationCause, PredicateObligation}; -pub trait TraitEngine<'tcx>: 'tcx { +/// A trait error with most of its information removed. This is the error +/// returned by an `ObligationCtxt` by default, and suitable if you just +/// want to see if a predicate holds, and don't particularly care about the +/// error itself (except for if it's an ambiguity or true error). +/// +/// use `ObligationCtxt::new_with_diagnostics` to get a `FulfillmentError`. +#[derive(Clone, Debug)] +pub enum ScrubbedTraitError<'tcx> { + /// A real error. This goal definitely does not hold. + TrueError, + /// An ambiguity. This goal may hold if further inference is done. + Ambiguity, + /// An old-solver-style cycle error, which will fatal. + Cycle(Vec>), +} + +impl<'tcx> ScrubbedTraitError<'tcx> { + pub fn is_true_error(&self) -> bool { + match self { + ScrubbedTraitError::TrueError => true, + ScrubbedTraitError::Ambiguity | ScrubbedTraitError::Cycle(_) => false, + } + } +} + +pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx { /// Requires that `ty` must implement the trait with `def_id` in /// the given environment. This trait must not have any type /// parameters (except for `Self`). @@ -37,10 +62,30 @@ pub trait TraitEngine<'tcx>: 'tcx { obligation: PredicateObligation<'tcx>, ); - #[must_use] - fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec>; + fn register_predicate_obligations( + &mut self, + infcx: &InferCtxt<'tcx>, + obligations: Vec>, + ) { + for obligation in obligations { + self.register_predicate_obligation(infcx, obligation); + } + } - fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec>; + #[must_use] + fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec; + + fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec; + + #[must_use] + fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec { + let errors = self.select_where_possible(infcx); + if !errors.is_empty() { + return errors; + } + + self.collect_remaining_errors(infcx) + } fn pending_obligations(&self) -> Vec>; @@ -53,25 +98,6 @@ pub trait TraitEngine<'tcx>: 'tcx { ) -> Vec>; } -#[extension(pub trait TraitEngineExt<'tcx>)] -impl<'tcx, T: ?Sized + TraitEngine<'tcx>> T { - fn register_predicate_obligations( - &mut self, - infcx: &InferCtxt<'tcx>, - obligations: impl IntoIterator>, - ) { - for obligation in obligations { - self.register_predicate_obligation(infcx, obligation); - } - } - - #[must_use] - fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec> { - let errors = self.select_where_possible(infcx); - if !errors.is_empty() { - return errors; - } - - self.collect_remaining_errors(infcx) - } +pub trait FromSolverError<'tcx, E>: Debug + 'tcx { + fn from_solver_error(infcx: &InferCtxt<'tcx>, error: E) -> Self; } diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 0ae4340098bc..ca6c6570e072 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -15,15 +15,14 @@ use hir::def_id::LocalDefId; use rustc_hir as hir; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::Certainty; -use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, Const, Ty, TyCtxt, Upcast}; +use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; use rustc_span::Span; pub use self::ImplSource::*; pub use self::SelectionError::*; use crate::infer::InferCtxt; -pub use self::engine::{TraitEngine, TraitEngineExt}; +pub use self::engine::{FromSolverError, ScrubbedTraitError, TraitEngine}; pub use self::project::MismatchedProjectionTypes; pub(crate) use self::project::UndoLog; pub use self::project::{ @@ -124,32 +123,6 @@ pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>; pub type ObligationInspector<'tcx> = fn(&InferCtxt<'tcx>, &PredicateObligation<'tcx>, Result); -pub struct FulfillmentError<'tcx> { - pub obligation: PredicateObligation<'tcx>, - pub code: FulfillmentErrorCode<'tcx>, - /// Diagnostics only: the 'root' obligation which resulted in - /// the failure to process `obligation`. This is the obligation - /// that was initially passed to `register_predicate_obligation` - pub root_obligation: PredicateObligation<'tcx>, -} - -#[derive(Clone)] -pub enum FulfillmentErrorCode<'tcx> { - /// Inherently impossible to fulfill; this trait is implemented if and only - /// if it is already implemented. - Cycle(Vec>), - Select(SelectionError<'tcx>), - Project(MismatchedProjectionTypes<'tcx>), - Subtype(ExpectedFound>, TypeError<'tcx>), // always comes from a SubtypePredicate - ConstEquate(ExpectedFound>, TypeError<'tcx>), - Ambiguity { - /// Overflow is only `Some(suggest_recursion_limit)` when using the next generation - /// trait solver `-Znext-solver`. With the old solver overflow is eagerly handled by - /// emitting a fatal error instead. - overflow: Option, - }, -} - impl<'tcx, O> Obligation<'tcx, O> { pub fn new( tcx: TyCtxt<'tcx>, @@ -198,28 +171,6 @@ impl<'tcx, O> Obligation<'tcx, O> { } } -impl<'tcx> FulfillmentError<'tcx> { - pub fn new( - obligation: PredicateObligation<'tcx>, - code: FulfillmentErrorCode<'tcx>, - root_obligation: PredicateObligation<'tcx>, - ) -> FulfillmentError<'tcx> { - FulfillmentError { obligation, code, root_obligation } - } - - pub fn is_true_error(&self) -> bool { - match self.code { - FulfillmentErrorCode::Select(_) - | FulfillmentErrorCode::Project(_) - | FulfillmentErrorCode::Subtype(_, _) - | FulfillmentErrorCode::ConstEquate(_, _) => true, - FulfillmentErrorCode::Cycle(_) | FulfillmentErrorCode::Ambiguity { overflow: _ } => { - false - } - } - } -} - impl<'tcx> PolyTraitObligation<'tcx> { pub fn polarity(&self) -> ty::PredicatePolarity { self.predicate.skip_binder().polarity diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index b616d37e5b5e..b26734a296fd 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -29,33 +29,6 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for traits::Obligation<'tcx, O> { } } -impl<'tcx> fmt::Debug for traits::FulfillmentError<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "FulfillmentError({:?},{:?})", self.obligation, self.code) - } -} - -impl<'tcx> fmt::Debug for traits::FulfillmentErrorCode<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use traits::FulfillmentErrorCode::*; - match *self { - Select(ref e) => write!(f, "{e:?}"), - Project(ref e) => write!(f, "{e:?}"), - Subtype(ref a, ref b) => { - write!(f, "CodeSubtypeError({a:?}, {b:?})") - } - ConstEquate(ref a, ref b) => { - write!(f, "CodeConstEquateError({a:?}, {b:?})") - } - Ambiguity { overflow: None } => write!(f, "Ambiguity"), - Ambiguity { overflow: Some(suggest_increasing_limit) } => { - write!(f, "Overflow({suggest_increasing_limit})") - } - Cycle(ref cycle) => write!(f, "Cycle({cycle:?})"), - } - } -} - impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "MismatchedProjectionTypes({:?})", self.err) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 33995f80162e..b678582766d5 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -832,7 +832,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { let traits = tcx.traits(LOCAL_CRATE); for &tr in traits { - if !tcx.check_is_object_safe(tr) { + if !tcx.is_object_safe(tr) { continue; } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index ba42eae34415..87c433a5dc0b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1494,8 +1494,9 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { let ty = cx.tcx.type_of(item.owner_id).skip_binder(); if ty.has_inherent_projections() { - // Bounds of type aliases that contain opaque types or inherent projections are respected. - // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`, `type X = Type::Inherent;`. + // Bounds of type aliases that contain opaque types or inherent projections are + // respected. E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`, `type X = + // Type::Inherent;`. return; } @@ -2224,7 +2225,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { hir_generics.span.shrink_to_hi().to(where_span) }; - // Due to macro expansions, the `full_where_span` might not actually contain all predicates. + // Due to macro expansions, the `full_where_span` might not actually contain all + // predicates. if where_lint_spans.iter().all(|&sp| full_where_span.contains(sp)) { lint_spans.push(full_where_span); } else { @@ -2601,7 +2603,8 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { }; // So we have at least one potentially inhabited variant. Might we have two? let Some(second_variant) = potential_variants.next() else { - // There is only one potentially inhabited variant. So we can recursively check that variant! + // There is only one potentially inhabited variant. So we can recursively + // check that variant! return variant_find_init_error( cx, ty, @@ -2611,10 +2614,10 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { init, ); }; - // So we have at least two potentially inhabited variants. - // If we can prove that we have at least two *definitely* inhabited variants, - // then we have a tag and hence leaving this uninit is definitely disallowed. - // (Leaving it zeroed could be okay, depending on which variant is encoded as zero tag.) + // So we have at least two potentially inhabited variants. If we can prove that + // we have at least two *definitely* inhabited variants, then we have a tag and + // hence leaving this uninit is definitely disallowed. (Leaving it zeroed could + // be okay, depending on which variant is encoded as zero tag.) if init == InitKind::Uninit { let definitely_inhabited = (first_variant.1 as usize) + (second_variant.1 as usize) @@ -2825,7 +2828,8 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels { let mut found_labels = Vec::new(); - // A semicolon might not actually be specified as a separator for all targets, but it seems like LLVM accepts it always + // A semicolon might not actually be specified as a separator for all targets, but + // it seems like LLVM accepts it always. let statements = template_str.split(|c| matches!(c, '\n' | ';')); for statement in statements { // If there's a comment, trim it from the statement @@ -2838,7 +2842,8 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels { let mut chars = possible_label.chars(); let Some(start) = chars.next() else { - // Empty string means a leading ':' in this section, which is not a label. + // Empty string means a leading ':' in this section, which is not a + // label. break 'label_loop; }; @@ -2855,12 +2860,15 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels { // Labels continue with ASCII alphanumeric characters, _, or $ for c in chars { - // Inside a template format arg, any character is permitted for the puproses of label detection - // because we assume that it can be replaced with some other valid label string later. - // `options(raw)` asm blocks cannot have format args, so they are excluded from this special case. + // Inside a template format arg, any character is permitted for the + // puproses of label detection because we assume that it can be + // replaced with some other valid label string later. `options(raw)` + // asm blocks cannot have format args, so they are excluded from this + // special case. if !raw && in_bracket { if c == '{' { - // Nested brackets are not allowed in format args, this cannot be a label. + // Nested brackets are not allowed in format args, this cannot + // be a label. break 'label_loop; } @@ -2873,7 +2881,8 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels { in_bracket = true; } else { if !(c.is_ascii_alphanumeric() || matches!(c, '_' | '$')) { - // The potential label had an invalid character inside it, it cannot be a label. + // The potential label had an invalid character inside it, it + // cannot be a label. break 'label_loop; } } @@ -2892,7 +2901,8 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels { .into_iter() .filter_map(|label| find_label_span(label)) .collect::>(); - // If there were labels but we couldn't find a span, combine the warnings and use the template span + // If there were labels but we couldn't find a span, combine the warnings and + // use the template span. let target_spans: MultiSpan = if spans.len() > 0 { spans.into() } else { (*template_span).into() }; diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 56f07a2b5e99..9f0f116cbd03 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -94,7 +94,8 @@ enum TargetLint { /// A lint name that should give no warnings and have no effect. /// - /// This is used by rustc to avoid warning about old rustdoc lints before rustdoc registers them as tool lints. + /// This is used by rustc to avoid warning about old rustdoc lints before rustdoc registers + /// them as tool lints. Ignored, } @@ -126,12 +127,16 @@ pub enum CheckLintNameResult<'a> { Renamed(String), /// The lint has been removed due to the given reason. Removed(String), - /// The lint is from a tool. If the Option is None, then either - /// the lint does not exist in the tool or the code was not - /// compiled with the tool and therefore the lint was never - /// added to the `LintStore`. Otherwise the `LintId` will be - /// returned as if it where a rustc lint. - Tool(Result<&'a [LintId], (Option<&'a [LintId]>, String)>), + + /// The lint is from a tool. The `LintId` will be returned as if it were a + /// rustc lint. The `Option` indicates if the lint has been + /// renamed. + Tool(&'a [LintId], Option), + + /// The lint is from a tool. Either the lint does not exist in the tool or + /// the code was not compiled with the tool and therefore the lint was + /// never added to the `LintStore`. + MissingTool, } impl LintStore { @@ -384,14 +389,14 @@ impl LintStore { } else { // 2. The tool isn't currently running, so no lints will be registered. // To avoid giving a false positive, ignore all unknown lints. - CheckLintNameResult::Tool(Err((None, String::new()))) + CheckLintNameResult::MissingTool }; } Some(LintGroup { lint_ids, .. }) => { - return CheckLintNameResult::Tool(Ok(lint_ids)); + return CheckLintNameResult::Tool(lint_ids, None); } }, - Some(Id(id)) => return CheckLintNameResult::Tool(Ok(slice::from_ref(id))), + Some(Id(id)) => return CheckLintNameResult::Tool(slice::from_ref(id), None), // If the lint was registered as removed or renamed by the lint tool, we don't need // to treat tool_lints and rustc lints different and can use the code below. _ => {} @@ -411,7 +416,7 @@ impl LintStore { return if *silent { CheckLintNameResult::Ok(lint_ids) } else { - CheckLintNameResult::Tool(Err((Some(lint_ids), (*name).to_string()))) + CheckLintNameResult::Tool(lint_ids, Some((*name).to_string())) }; } CheckLintNameResult::Ok(lint_ids) @@ -472,18 +477,17 @@ impl LintStore { // Reaching this would be weird, but let's cover this case anyway if let Some(LintAlias { name, silent }) = depr { let LintGroup { lint_ids, .. } = self.lint_groups.get(name).unwrap(); - return if *silent { - CheckLintNameResult::Tool(Err((Some(lint_ids), complete_name))) + if *silent { + CheckLintNameResult::Tool(lint_ids, Some(complete_name)) } else { - CheckLintNameResult::Tool(Err((Some(lint_ids), (*name).to_string()))) - }; + CheckLintNameResult::Tool(lint_ids, Some((*name).to_string())) + } + } else { + CheckLintNameResult::Tool(lint_ids, Some(complete_name)) } - CheckLintNameResult::Tool(Err((Some(lint_ids), complete_name))) } }, - Some(Id(id)) => { - CheckLintNameResult::Tool(Err((Some(slice::from_ref(id)), complete_name))) - } + Some(Id(id)) => CheckLintNameResult::Tool(slice::from_ref(id), Some(complete_name)), Some(other) => { debug!("got renamed lint {:?}", other); CheckLintNameResult::NoLint(None) diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index c23d1221bc86..46dfaf0b83f9 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -16,7 +16,7 @@ pub struct OverruledAttribute<'a> { #[subdiagnostic] pub sub: OverruledAttributeSub, } -// + pub enum OverruledAttributeSub { DefaultSource { id: String }, NodeSource { span: Span, reason: Option }, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 6e291a327fa6..9110cccdc46f 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -18,11 +18,11 @@ use rustc_span::Span; use tracing::debug; declare_tool_lint! { - /// The `default_hash_type` lint detects use of [`std::collections::HashMap`]/[`std::collections::HashSet`], - /// suggesting the use of `FxHashMap`/`FxHashSet`. + /// The `default_hash_type` lint detects use of [`std::collections::HashMap`] and + /// [`std::collections::HashSet`], suggesting the use of `FxHashMap`/`FxHashSet`. /// - /// This can help as `FxHasher` can perform better than the default hasher. DOS protection is not - /// required as input is assumed to be trusted. + /// This can help as `FxHasher` can perform better than the default hasher. DOS protection is + /// not required as input is assumed to be trusted. pub rustc::DEFAULT_HASH_TYPES, Allow, "forbid HashMap and HashSet and suggest the FxHash* variants", @@ -35,7 +35,7 @@ impl LateLintPass<'_> for DefaultHashTypes { fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) { let Res::Def(rustc_hir::def::DefKind::Struct, def_id) = path.res else { return }; if matches!(cx.tcx.hir_node(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) { - // don't lint imports, only actual usages + // Don't lint imports, only actual usages. return; } let preferred = match cx.tcx.get_diagnostic_name(def_id) { @@ -75,8 +75,8 @@ declare_tool_lint! { /// potential query instability, such as iterating over a `HashMap`. /// /// Due to the [incremental compilation](https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation.html) model, - /// queries must return deterministic, stable results. `HashMap` iteration order can change between compilations, - /// and will introduce instability if query results expose the order. + /// queries must return deterministic, stable results. `HashMap` iteration order can change + /// between compilations, and will introduce instability if query results expose the order. pub rustc::POTENTIAL_QUERY_INSTABILITY, Allow, "require explicit opt-in when using potentially unstable methods or functions", diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index b638ab10e11e..aa328fb87b27 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -125,7 +125,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas }); } - fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) { + fn visit_body(&mut self, body: &hir::Body<'tcx>) { lint_callback!(self, check_body, body); hir_visit::walk_body(self, body); lint_callback!(self, check_body_post, body); diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs index ea82fb9f2625..e6c274ec09a7 100644 --- a/compiler/rustc_lint/src/let_underscore.rs +++ b/compiler/rustc_lint/src/let_underscore.rs @@ -113,11 +113,11 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { let mut top_level = true; - // We recursively walk through all patterns, so that we can catch cases where the lock is nested in a pattern. - // For the basic `let_underscore_drop` lint, we only look at the top level, since there are many legitimate reasons - // to bind a sub-pattern to an `_`, if we're only interested in the rest. - // But with locks, we prefer having the chance of "false positives" over missing cases, since the effects can be - // quite catastrophic. + // We recursively walk through all patterns, so that we can catch cases where the lock is + // nested in a pattern. For the basic `let_underscore_drop` lint, we only look at the top + // level, since there are many legitimate reasons to bind a sub-pattern to an `_`, if we're + // only interested in the rest. But with locks, we prefer having the chance of "false + // positives" over missing cases, since the effects can be quite catastrophic. local.pat.walk_always(|pat| { let is_top_level = top_level; top_level = false; diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 84645e0ce7fc..1317af50a4a8 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -593,7 +593,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { let lint = UnknownLintFromCommandLine { name, suggestion, requested_level }; self.emit_lint(UNKNOWN_LINTS, lint); } - CheckLintNameResult::Tool(Err((Some(_), ref replace))) => { + CheckLintNameResult::Tool(_, Some(ref replace)) => { let name = lint_name.clone(); let requested_level = RequestedLevel { level, lint_name }; let lint = DeprecatedLintNameFromCommandLine { name, replace, requested_level }; @@ -750,7 +750,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { let level = match Level::from_attr(attr) { None => continue, - // This is the only lint level with a `LintExpectationId` that can be created from an attribute + // This is the only lint level with a `LintExpectationId` that can be created from + // an attribute. Some(Level::Expect(unstable_id)) if let Some(hir_id) = source_hir_id => { let LintExpectationId::Unstable { attr_id, lint_index } = unstable_id else { bug!("stable id Level::from_attr") @@ -760,8 +761,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { hir_id, attr_index: attr_index.try_into().unwrap(), lint_index, - // we pass the previous unstable attr_id such that we can trace the ast id when building a map - // to go from unstable to stable id. + // We pass the previous unstable attr_id such that we can trace the ast id + // when building a map to go from unstable to stable id. attr_id: Some(attr_id), }; @@ -860,13 +861,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { self.store.check_lint_name(&name, tool_name, self.registered_tools); match &lint_result { CheckLintNameResult::Ok(ids) => { - // This checks for instances where the user writes `#[expect(unfulfilled_lint_expectations)]` - // in that case we want to avoid overriding the lint level but instead add an expectation that - // can't be fulfilled. The lint message will include an explanation, that the + // This checks for instances where the user writes + // `#[expect(unfulfilled_lint_expectations)]` in that case we want to avoid + // overriding the lint level but instead add an expectation that can't be + // fulfilled. The lint message will include an explanation, that the // `unfulfilled_lint_expectations` lint can't be expected. if let Level::Expect(expect_id) = level { - // The `unfulfilled_lint_expectations` lint is not part of any lint groups. Therefore. we - // only need to check the slice if it contains a single lint. + // The `unfulfilled_lint_expectations` lint is not part of any lint + // groups. Therefore. we only need to check the slice if it contains a + // single lint. let is_unfulfilled_lint_expectations = match ids { [lint] => *lint == LintId::of(UNFULFILLED_LINT_EXPECTATIONS), _ => false, @@ -899,32 +902,20 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { } } - CheckLintNameResult::Tool(result) => { - match *result { - Ok(ids) => { + CheckLintNameResult::Tool(ids, new_lint_name) => { + let src = match new_lint_name { + None => { let complete_name = &format!("{}::{}", tool_ident.unwrap().name, name); - let src = LintLevelSource::Node { + LintLevelSource::Node { name: Symbol::intern(complete_name), span: sp, reason, - }; - for &id in ids { - if self.check_gated_lint(id, attr.span, false) { - self.insert_spec(id, (level, src)); - } - } - if let Level::Expect(expect_id) = level { - self.provider.push_expectation( - expect_id, - LintExpectation::new(reason, sp, false, tool_name), - ); } } - Err((Some(ids), ref new_lint_name)) => { - let lint = builtin::RENAMED_AND_REMOVED_LINTS; + Some(new_lint_name) => { self.emit_span_lint( - lint, + builtin::RENAMED_AND_REMOVED_LINTS, sp.into(), DeprecatedLintName { name, @@ -932,29 +923,31 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { replace: new_lint_name, }, ); - - let src = LintLevelSource::Node { + LintLevelSource::Node { name: Symbol::intern(new_lint_name), span: sp, reason, - }; - for id in ids { - self.insert_spec(*id, (level, src)); - } - if let Level::Expect(expect_id) = level { - self.provider.push_expectation( - expect_id, - LintExpectation::new(reason, sp, false, tool_name), - ); } } - Err((None, _)) => { - // If Tool(Err(None, _)) is returned, then either the lint does not - // exist in the tool or the code was not compiled with the tool and - // therefore the lint was never added to the `LintStore`. To detect - // this is the responsibility of the lint tool. + }; + for &id in *ids { + if self.check_gated_lint(id, attr.span, false) { + self.insert_spec(id, (level, src)); } } + if let Level::Expect(expect_id) = level { + self.provider.push_expectation( + expect_id, + LintExpectation::new(reason, sp, false, tool_name), + ); + } + } + + CheckLintNameResult::MissingTool => { + // If `MissingTool` is returned, then either the lint does not + // exist in the tool or the code was not compiled with the tool and + // therefore the lint was never added to the `LintStore`. To detect + // this is the responsibility of the lint tool. } &CheckLintNameResult::NoTool => { @@ -997,7 +990,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { // we don't warn about the name change. if let CheckLintNameResult::Renamed(new_name) = lint_result { // Ignore any errors or warnings that happen because the new name is inaccurate - // NOTE: `new_name` already includes the tool name, so we don't have to add it again. + // NOTE: `new_name` already includes the tool name, so we don't have to add it + // again. let CheckLintNameResult::Ok(ids) = self.store.check_lint_name(&new_name, None, self.registered_tools) else { diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs index b93245d58d9d..7a71fec769fe 100644 --- a/compiler/rustc_lint/src/methods.rs +++ b/compiler/rustc_lint/src/methods.rs @@ -25,9 +25,9 @@ declare_lint! { /// /// The inner pointer of a `CString` lives only as long as the `CString` it /// points to. Getting the inner pointer of a *temporary* `CString` allows the `CString` - /// to be dropped at the end of the statement, as it is not being referenced as far as the typesystem - /// is concerned. This means outside of the statement the pointer will point to freed memory, which - /// causes undefined behavior if the pointer is later dereferenced. + /// to be dropped at the end of the statement, as it is not being referenced as far as the + /// typesystem is concerned. This means outside of the statement the pointer will point to + /// freed memory, which causes undefined behavior if the pointer is later dereferenced. pub TEMPORARY_CSTRING_AS_PTR, Warn, "detects getting the inner pointer of a temporary `CString`" diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index 48d140c6b7f3..aa1d94228ea2 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -38,10 +38,10 @@ declare_lint_pass!(MultipleSupertraitUpcastable => [MULTIPLE_SUPERTRAIT_UPCASTAB impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { let def_id = item.owner_id.to_def_id(); - // NOTE(nbdd0121): use `object_safety_violations` instead of `check_is_object_safe` because + // NOTE(nbdd0121): use `object_safety_violations` instead of `is_object_safe` because // the latter will report `where_clause_object_safety` lint. if let hir::ItemKind::Trait(_, _, _, _, _) = item.kind - && cx.tcx.object_safety_violations(def_id).is_empty() + && cx.tcx.is_object_safe(def_id) { let direct_super_traits_iter = cx .tcx diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 42b03f47a5bc..d7ffc34d824f 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -68,11 +68,11 @@ impl_lint_pass!(NonLocalDefinitions => [NON_LOCAL_DEFINITIONS]); // instead check_mod is called after every body has been handled. impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { - fn check_body(&mut self, _cx: &LateContext<'tcx>, _body: &'tcx Body<'tcx>) { + fn check_body(&mut self, _cx: &LateContext<'tcx>, _body: &Body<'tcx>) { self.body_depth += 1; } - fn check_body_post(&mut self, _cx: &LateContext<'tcx>, _body: &'tcx Body<'tcx>) { + fn check_body_post(&mut self, _cx: &LateContext<'tcx>, _body: &Body<'tcx>) { self.body_depth -= 1; } @@ -306,7 +306,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { } } -// Detecting if the impl definition is leaking outside of it's defining scope. +// Detecting if the impl definition is leaking outside of its defining scope. // // Rule: for each impl, instantiate all local types with inference vars and // then assemble candidates for that goal, if there are more than 1 (non-private diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index dbb0644cd63f..d64f44471620 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -297,14 +297,14 @@ impl NonSnakeCase { // We cannot provide meaningful suggestions // if the characters are in the category of "Uppercase Letter". let sub = if name != sc { - // We have a valid span in almost all cases, but we don't have one when linting a crate - // name provided via the command line. + // We have a valid span in almost all cases, but we don't have one when linting a + // crate name provided via the command line. if !span.is_dummy() { let sc_ident = Ident::from_str_and_span(&sc, span); if sc_ident.is_reserved() { - // We shouldn't suggest a reserved identifier to fix non-snake-case identifiers. - // Instead, recommend renaming the identifier entirely or, if permitted, - // escaping it to create a raw identifier. + // We shouldn't suggest a reserved identifier to fix non-snake-case + // identifiers. Instead, recommend renaming the identifier entirely or, if + // permitted, escaping it to create a raw identifier. if sc_ident.name.can_be_raw() { NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index eda40e4a011a..6098da990c04 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { }; // Only check types, since those are the only things that may // have opaques in them anyways. - let Some(proj_term) = proj.term.ty() else { return }; + let Some(proj_term) = proj.term.as_type() else { return }; // HACK: `impl Trait` from an RPIT is "ok"... if let ty::Alias(ty::Opaque, opaque_ty) = *proj_term.kind() diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index d8ba84eb7a1a..2a843977990c 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -7,8 +7,8 @@ use rustc_session::lint::LintPass; macro_rules! late_lint_methods { ($macro:path, $args:tt) => ( $macro!($args, [ - fn check_body(a: &'tcx rustc_hir::Body<'tcx>); - fn check_body_post(a: &'tcx rustc_hir::Body<'tcx>); + fn check_body(a: &rustc_hir::Body<'tcx>); + fn check_body_post(a: &rustc_hir::Body<'tcx>); fn check_crate(); fn check_crate_post(); fn check_mod(a: &'tcx rustc_hir::Mod<'tcx>, b: rustc_hir::HirId); @@ -237,5 +237,5 @@ macro_rules! declare_combined_early_lint_pass { } /// A lint pass boxed up as a trait object. -pub type EarlyLintPassObject = Box; -pub type LateLintPassObject<'tcx> = Box + 'tcx>; +pub(crate) type EarlyLintPassObject = Box; +pub(crate) type LateLintPassObject<'tcx> = Box + 'tcx>; diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index a6993547c8fc..c8da9f179e71 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -387,7 +387,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { } } - // Returns whether further errors should be suppressed because either a lint has been emitted or the type should be ignored. + // Returns whether further errors should be suppressed because either a lint has been + // emitted or the type should be ignored. fn check_must_use_def( cx: &LateContext<'_>, def_id: DefId, @@ -677,7 +678,8 @@ trait UnusedDelimLint { return true; } - // Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`. + // Check if LHS needs parens to prevent false-positives in cases like + // `fn x() -> u8 { ({ 0 } + 1) }`. // // FIXME: https://github.com/rust-lang/rust/issues/119426 // The syntax tree in this code is from after macro expansion, so the @@ -722,7 +724,8 @@ trait UnusedDelimLint { } } - // Check if RHS needs parens to prevent false-positives in cases like `if (() == return) {}`. + // Check if RHS needs parens to prevent false-positives in cases like `if (() == return) + // {}`. if !followed_by_block { return false; } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 13867319e5cd..a3044489fdce 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -37,6 +37,7 @@ declare_lint_pass! { DEPRECATED, DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, DEPRECATED_IN_FUTURE, + DEPRECATED_SAFE, DEPRECATED_WHERE_CLAUSE_LOCATION, DUPLICATE_MACRO_ATTRIBUTES, ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, @@ -135,7 +136,6 @@ declare_lint_pass! { USELESS_DEPRECATED, WARNINGS, WASM_C_ABI, - WHERE_CLAUSES_OBJECT_SAFETY, WRITES_THROUGH_IMMUTABLE_POINTER, // tidy-alphabetical-end ] @@ -2092,47 +2092,6 @@ declare_lint! { "detects labels that are never used" } -declare_lint! { - /// The `where_clauses_object_safety` lint detects for [object safety] of - /// [where clauses]. - /// - /// [object safety]: https://doc.rust-lang.org/reference/items/traits.html#object-safety - /// [where clauses]: https://doc.rust-lang.org/reference/items/generics.html#where-clauses - /// - /// ### Example - /// - /// ```rust,no_run - /// trait Trait {} - /// - /// trait X { fn foo(&self) where Self: Trait; } - /// - /// impl X for () { fn foo(&self) {} } - /// - /// impl Trait for dyn X {} - /// - /// // Segfault at opt-level 0, SIGILL otherwise. - /// pub fn main() { ::foo(&()); } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// The compiler previously allowed these object-unsafe bounds, which was - /// incorrect. This is a [future-incompatible] lint to transition this to - /// a hard error in the future. See [issue #51443] for more details. - /// - /// [issue #51443]: https://github.com/rust-lang/rust/issues/51443 - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub WHERE_CLAUSES_OBJECT_SAFETY, - Warn, - "checks the object safety of where clauses", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, - reference: "issue #51443 ", - }; -} - declare_lint! { /// The `proc_macro_derive_resolution_fallback` lint detects proc macro /// derives using inaccessible names from parent modules. @@ -4844,3 +4803,51 @@ declare_lint! { reference: "issue #124559 ", }; } + +declare_lint! { + /// The `deprecated_safe` lint detects unsafe functions being used as safe + /// functions. + /// + /// ### Example + /// + /// ```rust,edition2021,compile_fail + /// #![deny(deprecated_safe)] + /// // edition 2021 + /// use std::env; + /// fn enable_backtrace() { + /// env::set_var("RUST_BACKTRACE", "1"); + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Rust [editions] allow the language to evolve without breaking backward + /// compatibility. This lint catches code that uses `unsafe` functions that + /// were declared as safe (non-`unsafe`) in earlier editions. If you switch + /// the compiler to a new edition without updating the code, then it + /// will fail to compile if you are using a function previously marked as + /// safe. + /// + /// You can audit the code to see if it suffices the preconditions of the + /// `unsafe` code, and if it does, you can wrap it in an `unsafe` block. If + /// you can't fulfill the preconditions, you probably need to switch to a + /// different way of doing what you want to achieve. + /// + /// This lint can automatically wrap the calls in `unsafe` blocks, but this + /// obviously cannot verify that the preconditions of the `unsafe` + /// functions are fulfilled, so that is still up to the user. + /// + /// The lint is currently "allow" by default, but that might change in the + /// future. + /// + /// [editions]: https://doc.rust-lang.org/edition-guide/ + pub DEPRECATED_SAFE, + Allow, + "detects unsafe functions being used as safe functions", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), + reference: "issue #27970 ", + }; +} diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index e11c45b66e6d..41b26ecce3c5 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -103,7 +103,6 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> { let mut layer = tracing_tree::HierarchicalLayer::default() .with_writer(io::stderr) - .with_indent_lines(true) .with_ansi(color_logs) .with_targets(true) .with_verbose_exit(verbose_entry_exit) diff --git a/compiler/rustc_macros/src/extension.rs b/compiler/rustc_macros/src/extension.rs index 5377bbdfeabd..bbaa477237b1 100644 --- a/compiler/rustc_macros/src/extension.rs +++ b/compiler/rustc_macros/src/extension.rs @@ -6,6 +6,7 @@ use syn::spanned::Spanned; use syn::{ braced, parse_macro_input, Attribute, Generics, ImplItem, Pat, PatIdent, Path, Signature, Token, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, Type, Visibility, + WhereClause, }; pub(crate) fn extension( @@ -13,7 +14,7 @@ pub(crate) fn extension( input: proc_macro::TokenStream, ) -> proc_macro::TokenStream { let ExtensionAttr { vis, trait_ } = parse_macro_input!(attr as ExtensionAttr); - let Impl { attrs, generics, self_ty, items } = parse_macro_input!(input as Impl); + let Impl { attrs, generics, self_ty, items, wc } = parse_macro_input!(input as Impl); let headers: Vec<_> = items .iter() .map(|item| match item { @@ -59,7 +60,7 @@ pub(crate) fn extension( #(#headers)* } - impl #generics #trait_ for #self_ty { + impl #generics #trait_ for #self_ty #wc { #(#items)* } } @@ -133,6 +134,7 @@ struct Impl { generics: Generics, self_ty: Type, items: Vec, + wc: Option, } impl Parse for Impl { @@ -141,6 +143,7 @@ impl Parse for Impl { let _: Token![impl] = input.parse()?; let generics = input.parse()?; let self_ty = input.parse()?; + let wc = input.parse()?; let content; let _brace_token = braced!(content in input); @@ -149,6 +152,6 @@ impl Parse for Impl { items.push(content.parse()?); } - Ok(Impl { attrs, generics, self_ty, items }) + Ok(Impl { attrs, generics, self_ty, items, wc }) } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 4cad317ce80c..f6b9c7ed9926 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -287,6 +287,10 @@ provide! { tcx, def_id, other, cdata, let _ = cdata; tcx.calculate_dtor(def_id, |_,_| Ok(())) } + adt_async_destructor => { + let _ = cdata; + tcx.calculate_async_dtor(def_id, |_,_| Ok(())) + } associated_item_def_ids => { tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index)) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 4587a4315e3c..4f186981a76f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1677,9 +1677,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if should_encode_const(tcx.def_kind(def_id)) { let qualifs = tcx.mir_const_qualif(def_id); record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); - let body_id = tcx.hir().maybe_body_owned_by(def_id); - if let Some(body_id) = body_id { - let const_data = rendered_const(self.tcx, body_id); + let body = tcx.hir().maybe_body_owned_by(def_id); + if let Some(body) = body { + let const_data = rendered_const(self.tcx, &body, def_id); record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); } } @@ -2368,9 +2368,9 @@ pub fn provide(providers: &mut Providers) { /// Whenever possible, prefer to evaluate the constant first and try to /// use a different method for pretty-printing. Ideally this function /// should only ever be used as a fallback. -pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String { +pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body<'_>, def_id: LocalDefId) -> String { let hir = tcx.hir(); - let value = &hir.body(body).value; + let value = body.value; #[derive(PartialEq, Eq)] enum Classification { @@ -2426,13 +2426,13 @@ pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String { // Otherwise we prefer pretty-printing to get rid of extraneous whitespace, comments and // other formatting artifacts. - Literal | Simple => id_to_string(&hir, body.hir_id), + Literal | Simple => id_to_string(&hir, body.id().hir_id), // FIXME: Omit the curly braces if the enclosing expression is an array literal // with a repeated element (an `ExprKind::Repeat`) as in such case it // would not actually need any disambiguation. Complex => { - if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst { + if tcx.def_kind(def_id) == DefKind::AnonConst { "{ _ }".to_owned() } else { "_".to_owned() diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index ff8d29197055..639c98155e70 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use crate::hir::ModuleItems; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; use crate::query::LocalCrate; @@ -254,13 +256,26 @@ impl<'hir> Map<'hir> { /// Given a `LocalDefId`, returns the `BodyId` associated with it, /// if the node is a body owner, otherwise returns `None`. - pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option { - self.tcx.hir_node_by_def_id(id).body_id() + pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option>> { + Some(match self.tcx.def_kind(id) { + // Inline consts do not have bodies of their own, so create one to make the follow-up logic simpler. + DefKind::InlineConst => { + let e = self.expect_expr(self.tcx.local_def_id_to_hir_id(id)); + Cow::Owned(Body { + params: &[], + value: match e.kind { + ExprKind::ConstBlock(body) => body, + _ => span_bug!(e.span, "InlineConst was not a ConstBlock: {e:#?}"), + }, + }) + } + _ => Cow::Borrowed(self.body(self.tcx.hir_node_by_def_id(id).body_id()?)), + }) } /// Given a body owner's id, returns the `BodyId` associated with it. #[track_caller] - pub fn body_owned_by(self, id: LocalDefId) -> BodyId { + pub fn body_owned_by(self, id: LocalDefId) -> Cow<'hir, Body<'hir>> { self.maybe_body_owned_by(id).unwrap_or_else(|| { let hir_id = self.tcx.local_def_id_to_hir_id(id); span_bug!( @@ -910,7 +925,7 @@ impl<'hir> Map<'hir> { .with_hi(seg.args.map_or_else(|| ident_span.hi(), |args| args.span_ext.hi())) } Node::Ty(ty) => ty.span, - Node::TypeBinding(tb) => tb.span, + Node::AssocItemConstraint(constraint) => constraint.span, Node::TraitRef(tr) => tr.path.span, Node::Pat(pat) => pat.span, Node::PatField(field) => field.span, @@ -1175,7 +1190,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { Node::Stmt(_) => node_str("stmt"), Node::PathSegment(_) => node_str("path segment"), Node::Ty(_) => node_str("type"), - Node::TypeBinding(_) => node_str("type binding"), + Node::AssocItemConstraint(_) => node_str("assoc item constraint"), Node::TraitRef(_) => node_str("trait ref"), Node::Pat(_) => node_str("pat"), Node::PatField(_) => node_str("pattern field"), diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index d39422b2b04d..b0c14cdfec93 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -194,8 +194,7 @@ pub fn provide(providers: &mut Providers) { }; providers.fn_arg_names = |tcx, def_id| { let hir = tcx.hir(); - let hir_id = tcx.local_def_id_to_hir_id(def_id); - if let Some(body_id) = hir.maybe_body_owned_by(def_id) { + if let Some(body_id) = tcx.hir_node_by_def_id(def_id).body_id() { tcx.arena.alloc_from_iter(hir.body_param_names(body_id)) } else if let Node::TraitItem(&TraitItem { kind: TraitItemKind::Fn(_, TraitFn::Required(idents)), @@ -204,11 +203,15 @@ pub fn provide(providers: &mut Providers) { | Node::ForeignItem(&ForeignItem { kind: ForeignItemKind::Fn(_, idents, _), .. - }) = tcx.hir_node(hir_id) + }) = tcx.hir_node(tcx.local_def_id_to_hir_id(def_id)) { idents } else { - span_bug!(hir.span(hir_id), "fn_arg_names: unexpected item {:?}", def_id); + span_bug!( + hir.span(tcx.local_def_id_to_hir_id(def_id)), + "fn_arg_names: unexpected item {:?}", + def_id + ); } }; providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 105be21f2727..a5da7e7739e4 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -86,21 +86,6 @@ impl<'tcx> UnifyValue for RegionVariableValue<'tcx> { } } -impl ToType for ty::IntVarValue { - fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - match *self { - ty::IntType(i) => Ty::new_int(tcx, i), - ty::UintType(i) => Ty::new_uint(tcx, i), - } - } -} - -impl ToType for ty::FloatVarValue { - fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - Ty::new_float(tcx, self.0) - } -} - // Generic consts. #[derive(Copy, Clone, Debug)] @@ -211,6 +196,7 @@ impl<'tcx> EffectVarValue<'tcx> { impl<'tcx> UnifyValue for EffectVarValue<'tcx> { type Error = NoError; + fn unify_values(value1: &Self, value2: &Self) -> Result { match (*value1, *value2) { (EffectVarValue::Unknown, EffectVarValue::Unknown) => Ok(EffectVarValue::Unknown), diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 4155c61e96d0..da25fbb0a82b 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -329,14 +329,14 @@ pub struct MCDCBranchSpan { #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)] pub struct DecisionInfo { pub bitmap_idx: u32, - pub conditions_num: u16, + pub num_conditions: u16, } #[derive(Clone, Debug)] #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)] pub struct MCDCDecisionSpan { pub span: Span, - pub conditions_num: usize, + pub num_conditions: usize, pub end_markers: Vec, pub decision_depth: u16, } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 7bfb4ac867aa..f1c79c0b0391 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -512,12 +512,12 @@ fn write_coverage_branch_info( )?; } - for coverage::MCDCDecisionSpan { span, conditions_num, end_markers, decision_depth } in + for coverage::MCDCDecisionSpan { span, num_conditions, end_markers, decision_depth } in mcdc_decision_spans { writeln!( w, - "{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}" + "{INDENT}coverage mcdc decision {{ num_conditions: {num_conditions:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}" )?; } diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 9d70231be3b0..46b38e4a6a60 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -1,7 +1,7 @@ //! Values computed by queries that use MIR. use crate::mir; -use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt}; +use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty, TyCtxt}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LocalDefId; diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 1e36f034cc22..f98dbf8a0bd4 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -238,6 +238,7 @@ trivial! { Option, Option, Option, + Option, Option, Option, Option, @@ -295,6 +296,7 @@ trivial! { rustc_middle::ty::AssocItem, rustc_middle::ty::AssocItemContainer, rustc_middle::ty::Asyncness, + rustc_middle::ty::AsyncDestructor, rustc_middle::ty::BoundVariableKind, rustc_middle::ty::DeducedParamAttrs, rustc_middle::ty::Destructor, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 6ad4b7c40fb2..3c4aae73bc49 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -703,6 +703,11 @@ rustc_queries! { cache_on_disk_if { key.is_local() } separate_provide_extern } + query adt_async_destructor(key: DefId) -> Option { + desc { |tcx| "computing `AsyncDrop` impl for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } query adt_sized_constraint(key: DefId) -> Option>> { desc { |tcx| "computing the `Sized` constraint for `{}`", tcx.def_path_str(key) } @@ -1304,7 +1309,7 @@ rustc_queries! { query object_safety_violations(trait_id: DefId) -> &'tcx [ObjectSafetyViolation] { desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) } } - query check_is_object_safe(trait_id: DefId) -> bool { + query is_object_safe(trait_id: DefId) -> bool { desc { |tcx| "checking if trait `{}` is object safe", tcx.def_path_str(trait_id) } } @@ -1343,18 +1348,14 @@ rustc_queries! { query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is `Unpin`", env.value } } - /// Query backing `Ty::has_surface_async_drop`. - query has_surface_async_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` has `AsyncDrop` implementation", env.value } - } - /// Query backing `Ty::has_surface_drop`. - query has_surface_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` has `Drop` implementation", env.value } - } /// Query backing `Ty::needs_drop`. query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` needs drop", env.value } } + /// Query backing `Ty::needs_async_drop`. + query needs_async_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` needs async drop", env.value } + } /// Query backing `Ty::has_significant_drop_raw`. query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` has a significant drop", env.value } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 8e946bc8b314..5f9b870331c9 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -24,7 +24,9 @@ use std::hash::{Hash, Hasher}; use std::ops::Range; use std::str; -use super::{Destructor, FieldDef, GenericPredicates, Ty, TyCtxt, VariantDef, VariantDiscr}; +use super::{ + AsyncDestructor, Destructor, FieldDef, GenericPredicates, Ty, TyCtxt, VariantDef, VariantDiscr, +}; #[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] pub struct AdtFlags(u16); @@ -577,6 +579,12 @@ impl<'tcx> AdtDef<'tcx> { tcx.adt_destructor(self.did()) } + // FIXME: consider combining this method with `AdtDef::destructor` and removing + // this version + pub fn async_destructor(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.adt_async_destructor(self.did()) + } + /// Returns a type such that `Self: Sized` if and only if that type is `Sized`, /// or `None` if the type is always sized. pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option>> { diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 6416bbbe889c..384a4e7009d8 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -24,7 +24,7 @@ pub type ConstKind<'tcx> = ir::ConstKind>; pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst>; #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(ConstKind<'_>, 32); +rustc_data_structures::static_assert_size!(ConstKind<'_>, 24); /// Use this rather than `ConstData`, whenever possible. #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)] @@ -58,7 +58,7 @@ pub struct ConstData<'tcx> { } #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(ConstData<'_>, 40); +rustc_data_structures::static_assert_size!(ConstData<'_>, 32); impl<'tcx> Const<'tcx> { #[inline] diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index d7ae050ed4d0..5f29acf5ed27 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -1,7 +1,7 @@ use super::Const; use crate::mir; use crate::ty::abstract_const::CastKind; -use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt}; +use crate::ty::{self, visit::TypeVisitableExt as _, Ty, TyCtxt}; use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; #[extension(pub(crate) trait UnevaluatedConstEvalExt<'tcx>)] @@ -40,14 +40,125 @@ impl<'tcx> ty::UnevaluatedConst<'tcx> { } } +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] +pub enum ExprKind { + Binop(mir::BinOp), + UnOp(mir::UnOp), + FunctionCall, + Cast(CastKind), +} #[derive(Copy, Clone, Eq, PartialEq, Hash)] #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] -pub enum Expr<'tcx> { - Binop(mir::BinOp, Const<'tcx>, Const<'tcx>), - UnOp(mir::UnOp, Const<'tcx>), - FunctionCall(Const<'tcx>, &'tcx List>), - Cast(CastKind, Const<'tcx>, Ty<'tcx>), +pub struct Expr<'tcx> { + pub kind: ExprKind, + args: ty::GenericArgsRef<'tcx>, +} +impl<'tcx> Expr<'tcx> { + pub fn new_binop( + tcx: TyCtxt<'tcx>, + binop: mir::BinOp, + lhs_ty: Ty<'tcx>, + rhs_ty: Ty<'tcx>, + lhs_ct: Const<'tcx>, + rhs_ct: Const<'tcx>, + ) -> Self { + let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>( + [lhs_ty.into(), rhs_ty.into(), lhs_ct.into(), rhs_ct.into()].into_iter(), + ); + + Self { kind: ExprKind::Binop(binop), args } + } + + pub fn binop_args(self) -> (Ty<'tcx>, Ty<'tcx>, Const<'tcx>, Const<'tcx>) { + assert!(matches!(self.kind, ExprKind::Binop(_))); + + match self.args().as_slice() { + [lhs_ty, rhs_ty, lhs_ct, rhs_ct] => ( + lhs_ty.expect_ty(), + rhs_ty.expect_ty(), + lhs_ct.expect_const(), + rhs_ct.expect_const(), + ), + _ => bug!("Invalid args for `Binop` expr {self:?}"), + } + } + + pub fn new_unop(tcx: TyCtxt<'tcx>, unop: mir::UnOp, ty: Ty<'tcx>, ct: Const<'tcx>) -> Self { + let args = + tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>([ty.into(), ct.into()].into_iter()); + + Self { kind: ExprKind::UnOp(unop), args } + } + + pub fn unop_args(self) -> (Ty<'tcx>, Const<'tcx>) { + assert!(matches!(self.kind, ExprKind::UnOp(_))); + + match self.args().as_slice() { + [ty, ct] => (ty.expect_ty(), ct.expect_const()), + _ => bug!("Invalid args for `UnOp` expr {self:?}"), + } + } + + pub fn new_call( + tcx: TyCtxt<'tcx>, + func_ty: Ty<'tcx>, + func_expr: Const<'tcx>, + arguments: impl Iterator>, + ) -> Self { + let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>( + [func_ty.into(), func_expr.into()].into_iter().chain(arguments.map(|ct| ct.into())), + ); + + Self { kind: ExprKind::FunctionCall, args } + } + + pub fn call_args(self) -> (Ty<'tcx>, Const<'tcx>, impl Iterator>) { + assert!(matches!(self.kind, ExprKind::FunctionCall)); + + match self.args().as_slice() { + [func_ty, func, rest @ ..] => ( + func_ty.expect_ty(), + func.expect_const(), + rest.iter().map(|arg| arg.expect_const()), + ), + _ => bug!("Invalid args for `Call` expr {self:?}"), + } + } + + pub fn new_cast( + tcx: TyCtxt<'tcx>, + cast: CastKind, + value_ty: Ty<'tcx>, + value: Const<'tcx>, + to_ty: Ty<'tcx>, + ) -> Self { + let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>( + [value_ty.into(), value.into(), to_ty.into()].into_iter(), + ); + + Self { kind: ExprKind::Cast(cast), args } + } + + pub fn cast_args(self) -> (Ty<'tcx>, Const<'tcx>, Ty<'tcx>) { + assert!(matches!(self.kind, ExprKind::Cast(_))); + + match self.args().as_slice() { + [value_ty, value, to_ty] => { + (value_ty.expect_ty(), value.expect_const(), to_ty.expect_ty()) + } + _ => bug!("Invalid args for `Cast` expr {self:?}"), + } + } + + pub fn new(kind: ExprKind, args: ty::GenericArgsRef<'tcx>) -> Self { + Self { kind, args } + } + + pub fn args(&self) -> ty::GenericArgsRef<'tcx> { + self.args + } } #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(Expr<'_>, 24); +rustc_data_structures::static_assert_size!(Expr<'_>, 16); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c2219fba023b..47f66c644062 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -90,7 +90,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type AdtDef = ty::AdtDef<'tcx>; type GenericArgs = ty::GenericArgsRef<'tcx>; - type OwnItemArgs = &'tcx [ty::GenericArg<'tcx>]; + type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>]; type GenericArg = ty::GenericArg<'tcx>; type Term = ty::Term<'tcx>; @@ -113,7 +113,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type ErrorGuaranteed = ErrorGuaranteed; type BoundExistentialPredicates = &'tcx List>; - type PolyFnSig = PolyFnSig<'tcx>; type AllocId = crate::mir::interpret::AllocId; type Pat = Pattern<'tcx>; @@ -191,7 +190,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self, def_id: Self::DefId, args: Self::GenericArgs, - ) -> (rustc_type_ir::TraitRef, Self::OwnItemArgs) { + ) -> (rustc_type_ir::TraitRef, Self::GenericArgsSlice) { assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst); let trait_def_id = self.parent(def_id); assert_matches!(self.def_kind(trait_def_id), DefKind::Trait); diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 99d703be873e..9e2c626478ac 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -49,8 +49,6 @@ pub enum TypeError<'tcx> { Sorts(ExpectedFound>), ArgumentSorts(ExpectedFound>, usize), - IntMismatch(ExpectedFound), - FloatMismatch(ExpectedFound), Traits(ExpectedFound), VariadicMismatch(ExpectedFound), @@ -155,23 +153,6 @@ impl<'tcx> TypeError<'tcx> { report_maybe_different(&format!("trait `{expected}`"), &format!("trait `{found}`")) .into() } - IntMismatch(ref values) => { - let expected = match values.expected { - ty::IntVarValue::IntType(ty) => ty.name_str(), - ty::IntVarValue::UintType(ty) => ty.name_str(), - }; - let found = match values.found { - ty::IntVarValue::IntType(ty) => ty.name_str(), - ty::IntVarValue::UintType(ty) => ty.name_str(), - }; - format!("expected `{expected}`, found `{found}`").into() - } - FloatMismatch(ref values) => format!( - "expected `{}`, found `{}`", - values.expected.name_str(), - values.found.name_str() - ) - .into(), VariadicMismatch(ref values) => format!( "expected {} fn, found {} function", if values.expected { "variadic" } else { "non-variadic" }, @@ -206,8 +187,7 @@ impl<'tcx> TypeError<'tcx> { match self { CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | ConstnessMismatch(_) | PolarityMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_) - | ArgumentSorts(..) | Sorts(_) | IntMismatch(_) | FloatMismatch(_) - | VariadicMismatch(_) | TargetFeatureCast(_) => false, + | ArgumentSorts(..) | Sorts(_) | VariadicMismatch(_) | TargetFeatureCast(_) => false, Mutability | ArgumentMutability(_) diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 4de7d532c967..93a51d3a3340 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -374,26 +374,7 @@ impl FlagComputation { self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } ty::ConstKind::Value(_) => {} - ty::ConstKind::Expr(e) => { - use ty::Expr; - match e { - Expr::Binop(_, l, r) => { - self.add_const(l); - self.add_const(r); - } - Expr::UnOp(_, v) => self.add_const(v), - Expr::FunctionCall(f, args) => { - self.add_const(f); - for arg in args { - self.add_const(arg); - } - } - Expr::Cast(_, c, t) => { - self.add_ty(t); - self.add_const(c); - } - } - } + ty::ConstKind::Expr(e) => self.add_args(e.args()), ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), } } diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 7a516b9f2c80..c3ab755175d8 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -2,9 +2,10 @@ use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; -use crate::ty::sty::{ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineConstArgs}; use crate::ty::visit::{TypeVisitable, TypeVisitor}; -use crate::ty::{self, Lift, List, Ty, TyCtxt}; +use crate::ty::{ + self, ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineConstArgs, Lift, List, Ty, TyCtxt, +}; use rustc_ast_ir::visit::VisitorResult; use rustc_ast_ir::walk_visitable_list; @@ -56,6 +57,64 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs> for ty::GenericArg ) -> ty::GenericArgsRef<'tcx> { ty::GenericArgs::extend_with_error(tcx, def_id, original_args) } + + fn split_closure_args(self) -> ty::ClosureArgsParts> { + match self[..] { + [ref parent_args @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => { + ty::ClosureArgsParts { + parent_args, + closure_kind_ty: closure_kind_ty.expect_ty(), + closure_sig_as_fn_ptr_ty: closure_sig_as_fn_ptr_ty.expect_ty(), + tupled_upvars_ty: tupled_upvars_ty.expect_ty(), + } + } + _ => bug!("closure args missing synthetics"), + } + } + + fn split_coroutine_closure_args(self) -> ty::CoroutineClosureArgsParts> { + match self[..] { + [ + ref parent_args @ .., + closure_kind_ty, + signature_parts_ty, + tupled_upvars_ty, + coroutine_captures_by_ref_ty, + coroutine_witness_ty, + ] => ty::CoroutineClosureArgsParts { + parent_args, + closure_kind_ty: closure_kind_ty.expect_ty(), + signature_parts_ty: signature_parts_ty.expect_ty(), + tupled_upvars_ty: tupled_upvars_ty.expect_ty(), + coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(), + coroutine_witness_ty: coroutine_witness_ty.expect_ty(), + }, + _ => bug!("closure args missing synthetics"), + } + } + + fn split_coroutine_args(self) -> ty::CoroutineArgsParts> { + match self[..] { + [ + ref parent_args @ .., + kind_ty, + resume_ty, + yield_ty, + return_ty, + witness, + tupled_upvars_ty, + ] => ty::CoroutineArgsParts { + parent_args, + kind_ty: kind_ty.expect_ty(), + resume_ty: resume_ty.expect_ty(), + yield_ty: yield_ty.expect_ty(), + return_ty: return_ty.expect_ty(), + witness: witness.expect_ty(), + tupled_upvars_ty: tupled_upvars_ty.expect_ty(), + }, + _ => bug!("coroutine args missing synthetics"), + } + } } impl<'tcx> rustc_type_ir::inherent::IntoKind for GenericArg<'tcx> { @@ -295,7 +354,7 @@ impl<'tcx> GenericArgs<'tcx> { /// Closure args have a particular structure controlled by the /// compiler that encodes information like the signature and closure kind; /// see `ty::ClosureArgs` struct for more comments. - pub fn as_closure(&'tcx self) -> ClosureArgs<'tcx> { + pub fn as_closure(&'tcx self) -> ClosureArgs> { ClosureArgs { args: self } } @@ -303,7 +362,7 @@ impl<'tcx> GenericArgs<'tcx> { /// Coroutine-closure args have a particular structure controlled by the /// compiler that encodes information like the signature and closure kind; /// see `ty::CoroutineClosureArgs` struct for more comments. - pub fn as_coroutine_closure(&'tcx self) -> CoroutineClosureArgs<'tcx> { + pub fn as_coroutine_closure(&'tcx self) -> CoroutineClosureArgs> { CoroutineClosureArgs { args: self } } @@ -311,7 +370,7 @@ impl<'tcx> GenericArgs<'tcx> { /// Coroutine args have a particular structure controlled by the /// compiler that encodes information like the signature and coroutine kind; /// see `ty::CoroutineArgs` struct for more comments. - pub fn as_coroutine(&'tcx self) -> CoroutineArgs<'tcx> { + pub fn as_coroutine(&'tcx self) -> CoroutineArgs> { CoroutineArgs { args: self } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 60ce87440328..a2df90b2c0f8 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2,7 +2,7 @@ use crate::error::UnsupportedFnAbi; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::query::TyCtxtAt; use crate::ty::normalize_erasing_regions::NormalizationError; -use crate::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt}; use rustc_error_messages::DiagMessage; use rustc_errors::{ Diag, DiagArgValue, DiagCtxt, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, @@ -827,25 +827,14 @@ where }); } - let mk_dyn_vtable = || { + let mk_dyn_vtable = |principal: Option>| { + let min_count = ty::vtable_min_entries(tcx, principal); Ty::new_imm_ref( tcx, tcx.lifetimes.re_static, - Ty::new_array(tcx, tcx.types.usize, 3), + // FIXME: properly type (e.g. usize and fn pointers) the fields. + Ty::new_array(tcx, tcx.types.usize, min_count.try_into().unwrap()), ) - /* FIXME: use actual fn pointers - Warning: naively computing the number of entries in the - vtable by counting the methods on the trait + methods on - all parent traits does not work, because some methods can - be not object safe and thus excluded from the vtable. - Increase this counter if you tried to implement this but - failed to do it without duplicating a lot of code from - other places in the compiler: 2 - Ty::new_tup(tcx,&[ - Ty::new_array(tcx,tcx.types.usize, 3), - Ty::new_array(tcx,Option), - ]) - */ }; let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() @@ -864,16 +853,16 @@ where // `std::mem::uninitialized::<&dyn Trait>()`, for example. if let ty::Adt(def, args) = metadata.kind() && Some(def.did()) == tcx.lang_items().dyn_metadata() - && args.type_at(0).is_trait() + && let ty::Dynamic(data, _, ty::Dyn) = args.type_at(0).kind() { - mk_dyn_vtable() + mk_dyn_vtable(data.principal()) } else { metadata } } else { match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() { ty::Slice(_) | ty::Str => tcx.types.usize, - ty::Dynamic(_, _, ty::Dyn) => mk_dyn_vtable(), + ty::Dynamic(data, _, ty::Dyn) => mk_dyn_vtable(data.principal()), _ => bug!("TyAndLayout::field({:?}): not applicable", this), } }; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f24074cb472d..c6028ef74a9f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -87,7 +87,7 @@ pub use self::closure::{ CAPTURE_STRUCT_LOCAL, }; pub use self::consts::{ - Const, ConstData, ConstInt, ConstKind, Expr, ScalarInt, UnevaluatedConst, ValTree, + Const, ConstData, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree, }; pub use self::context::{ tls, CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, @@ -113,10 +113,8 @@ pub use self::region::{ pub use self::rvalue_scopes::RvalueScopes; pub use self::sty::{ AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig, - ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, CoroutineClosureArgs, - CoroutineClosureArgsParts, CoroutineClosureSignature, EarlyBinder, FnSig, GenSig, - InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut, - UpvarArgs, VarianceDiagInfo, + CoroutineArgsExt, EarlyBinder, FnSig, InlineConstArgs, InlineConstArgsParts, ParamConst, + ParamTy, PolyFnSig, TyKind, TypeAndMut, UpvarArgs, VarianceDiagInfo, }; pub use self::trait_def::TraitDef; pub use self::typeck_results::{ @@ -626,14 +624,22 @@ impl<'tcx> Term<'tcx> { } } - pub fn ty(&self) -> Option> { + pub fn as_type(&self) -> Option> { if let TermKind::Ty(ty) = self.unpack() { Some(ty) } else { None } } - pub fn ct(&self) -> Option> { + pub fn expect_type(&self) -> Ty<'tcx> { + self.as_type().expect("expected a type, but found a const") + } + + pub fn as_const(&self) -> Option> { if let TermKind::Const(c) = self.unpack() { Some(c) } else { None } } + pub fn expect_const(&self) -> Const<'tcx> { + self.as_const().expect("expected a const, but found a type") + } + pub fn into_arg(self) -> GenericArg<'tcx> { match self.unpack() { TermKind::Ty(ty) => ty.into(), @@ -1172,6 +1178,15 @@ pub struct Destructor { pub constness: hir::Constness, } +// FIXME: consider combining this definition with regular `Destructor` +#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)] +pub struct AsyncDestructor { + /// The `DefId` of the async destructor future constructor + pub ctor: DefId, + /// The `DefId` of the async destructor future type + pub future: DefId, +} + #[derive(Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] pub struct VariantFlags(u8); bitflags::bitflags! { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 83790db99260..1b37078e703d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1077,7 +1077,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } p!(")"); - if let Some(ty) = return_ty.skip_binder().ty() { + if let Some(ty) = return_ty.skip_binder().as_type() { if !ty.is_unit() { p!(" -> ", print(return_ty)); } @@ -1144,7 +1144,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { for (assoc_item_def_id, term) in assoc_items { // Skip printing `<{coroutine@} as Coroutine<_>>::Return` from async blocks, // unless we can find out what coroutine return type it comes from. - let term = if let Some(ty) = term.skip_binder().ty() + let term = if let Some(ty) = term.skip_binder().as_type() && let ty::Alias(ty::Projection, proj) = ty.kind() && let Some(assoc) = tcx.opt_associated_item(proj.def_id) && assoc.trait_container(tcx) == tcx.lang_items().coroutine_trait() @@ -1322,7 +1322,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { p!(pretty_fn_sig( tys, false, - proj.skip_binder().term.ty().expect("Return type was a const") + proj.skip_binder().term.as_type().expect("Return type was a const") )); resugared = true; } @@ -1533,8 +1533,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { print_ty: bool, ) -> Result<(), PrintError> { define_scoped_cx!(self); - match expr { - Expr::Binop(op, c1, c2) => { + match expr.kind { + ty::ExprKind::Binop(op) => { + let (_, _, c1, c2) = expr.binop_args(); + let precedence = |binop: rustc_middle::mir::BinOp| { use rustc_ast::util::parser::AssocOp; AssocOp::from_ast_binop(binop.to_hir_binop().into()).precedence() @@ -1543,22 +1545,26 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let formatted_op = op.to_hir_binop().as_str(); let (lhs_parenthesized, rhs_parenthesized) = match (c1.kind(), c2.kind()) { ( - ty::ConstKind::Expr(Expr::Binop(lhs_op, _, _)), - ty::ConstKind::Expr(Expr::Binop(rhs_op, _, _)), + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }), + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }), ) => (precedence(lhs_op) < op_precedence, precedence(rhs_op) < op_precedence), - (ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), ty::ConstKind::Expr(_)) => { - (precedence(lhs_op) < op_precedence, true) - } - (ty::ConstKind::Expr(_), ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => { - (true, precedence(rhs_op) < op_precedence) - } + ( + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }), + ty::ConstKind::Expr(_), + ) => (precedence(lhs_op) < op_precedence, true), + ( + ty::ConstKind::Expr(_), + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }), + ) => (true, precedence(rhs_op) < op_precedence), (ty::ConstKind::Expr(_), ty::ConstKind::Expr(_)) => (true, true), - (ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), _) => { - (precedence(lhs_op) < op_precedence, false) - } - (_, ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => { - (false, precedence(rhs_op) < op_precedence) - } + ( + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }), + _, + ) => (precedence(lhs_op) < op_precedence, false), + ( + _, + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }), + ) => (false, precedence(rhs_op) < op_precedence), (ty::ConstKind::Expr(_), _) => (true, false), (_, ty::ConstKind::Expr(_)) => (false, true), _ => (false, false), @@ -1574,7 +1580,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { rhs_parenthesized, )?; } - Expr::UnOp(op, ct) => { + ty::ExprKind::UnOp(op) => { + let (_, ct) = expr.unop_args(); + use rustc_middle::mir::UnOp; let formatted_op = match op { UnOp::Not => "!", @@ -1583,7 +1591,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { }; let parenthesized = match ct.kind() { _ if op == UnOp::PtrMetadata => true, - ty::ConstKind::Expr(Expr::UnOp(c_op, ..)) => c_op != op, + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::UnOp(c_op), .. }) => { + c_op != op + } ty::ConstKind::Expr(_) => true, _ => false, }; @@ -1593,61 +1603,37 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { parenthesized, )? } - Expr::FunctionCall(fn_def, fn_args) => { - use ty::TyKind; - match fn_def.ty().kind() { - TyKind::FnDef(def_id, gen_args) => { - p!(print_value_path(*def_id, gen_args), "("); - if print_ty { - let tcx = self.tcx(); - let sig = tcx.fn_sig(def_id).instantiate(tcx, gen_args).skip_binder(); + ty::ExprKind::FunctionCall => { + let (_, fn_def, fn_args) = expr.call_args(); - let mut args_with_ty = fn_args.iter().map(|ct| (ct, ct.ty())); - let output_ty = sig.output(); - - if let Some((ct, ty)) = args_with_ty.next() { - self.typed_value( - |this| this.pretty_print_const(ct, print_ty), - |this| this.pretty_print_type(ty), - ": ", - )?; - for (ct, ty) in args_with_ty { - p!(", "); - self.typed_value( - |this| this.pretty_print_const(ct, print_ty), - |this| this.pretty_print_type(ty), - ": ", - )?; - } - } - p!(write(") -> {output_ty}")); - } else { - p!(comma_sep(fn_args.iter()), ")"); - } - } - _ => bug!("unexpected type of fn def"), - } + write!(self, "(")?; + self.pretty_print_const(fn_def, print_ty)?; + p!(")(", comma_sep(fn_args), ")"); } - Expr::Cast(kind, ct, ty) => { + ty::ExprKind::Cast(kind) => { + let (_, value, to_ty) = expr.cast_args(); + use ty::abstract_const::CastKind; if kind == CastKind::As || (kind == CastKind::Use && self.should_print_verbose()) { - let parenthesized = match ct.kind() { - ty::ConstKind::Expr(Expr::Cast(_, _, _)) => false, + let parenthesized = match value.kind() { + ty::ConstKind::Expr(ty::Expr { + kind: ty::ExprKind::Cast { .. }, .. + }) => false, ty::ConstKind::Expr(_) => true, _ => false, }; self.maybe_parenthesized( |this| { this.typed_value( - |this| this.pretty_print_const(ct, print_ty), - |this| this.pretty_print_type(ty), + |this| this.pretty_print_const(value, print_ty), + |this| this.pretty_print_type(to_ty), " as ", ) }, parenthesized, )?; } else { - self.pretty_print_const(ct, print_ty)? + self.pretty_print_const(value, print_ty)? } } } @@ -1938,7 +1924,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { Ok(()) } - fn pretty_closure_as_impl(&mut self, closure: ty::ClosureArgs<'tcx>) -> Result<(), PrintError> { + fn pretty_closure_as_impl( + &mut self, + closure: ty::ClosureArgs>, + ) -> Result<(), PrintError> { let sig = closure.sig(); let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn); @@ -2973,7 +2962,7 @@ impl<'tcx> ty::PolyTraitPredicate<'tcx> { #[derive(Debug, Copy, Clone, Lift)] pub struct PrintClosureAsImpl<'tcx> { - pub closure: ty::ClosureArgs<'tcx>, + pub closure: ty::ClosureArgs>, } macro_rules! forward_display_to_print { @@ -3199,7 +3188,7 @@ define_print_and_forward_display! { if let ty::PredicatePolarity::Negative = self.0.polarity { p!("!") } - p!(print(self.0.trait_ref.print_only_trait_path())); + p!(print(self.0.trait_ref.print_trait_sugared())); } PrintClosureAsImpl<'tcx> { diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index f02b4849f83d..a621d255a03e 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -6,8 +6,8 @@ use crate::ty::error::{ExpectedFound, TypeError}; use crate::ty::{ - self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, Expr, GenericArg, - GenericArgKind, GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable, + self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, GenericArg, GenericArgKind, + GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable, }; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -665,46 +665,18 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>( a.ty(), )); } - // Before calling relate on exprs, it is necessary to ensure that the nested consts - // have identical types. (ty::ConstKind::Expr(ae), ty::ConstKind::Expr(be)) => { - let r = relation; - - // FIXME(generic_const_exprs): is it possible to relate two consts which are not identical - // exprs? Should we care about that? - // FIXME(generic_const_exprs): relating the `ty()`s is a little weird since it is supposed to - // ICE If they mismatch. Unfortunately `ConstKind::Expr` is a little special and can be thought - // of as being generic over the argument types, however this is implicit so these types don't get - // related when we relate the args of the item this const arg is for. - let expr = match (ae, be) { - (Expr::Binop(a_op, al, ar), Expr::Binop(b_op, bl, br)) if a_op == b_op => { - r.relate(al.ty(), bl.ty())?; - r.relate(ar.ty(), br.ty())?; - Expr::Binop(a_op, r.consts(al, bl)?, r.consts(ar, br)?) - } - (Expr::UnOp(a_op, av), Expr::UnOp(b_op, bv)) if a_op == b_op => { - r.relate(av.ty(), bv.ty())?; - Expr::UnOp(a_op, r.consts(av, bv)?) - } - (Expr::Cast(ak, av, at), Expr::Cast(bk, bv, bt)) if ak == bk => { - r.relate(av.ty(), bv.ty())?; - Expr::Cast(ak, r.consts(av, bv)?, r.tys(at, bt)?) - } - (Expr::FunctionCall(af, aa), Expr::FunctionCall(bf, ba)) - if aa.len() == ba.len() => - { - r.relate(af.ty(), bf.ty())?; - let func = r.consts(af, bf)?; - let mut related_args = Vec::with_capacity(aa.len()); - for (a_arg, b_arg) in aa.iter().zip(ba.iter()) { - related_args.push(r.consts(a_arg, b_arg)?); - } - let related_args = tcx.mk_const_list(&related_args); - Expr::FunctionCall(func, related_args) - } + match (ae.kind, be.kind) { + (ty::ExprKind::Binop(a_binop), ty::ExprKind::Binop(b_binop)) + if a_binop == b_binop => {} + (ty::ExprKind::UnOp(a_unop), ty::ExprKind::UnOp(b_unop)) if a_unop == b_unop => {} + (ty::ExprKind::FunctionCall, ty::ExprKind::FunctionCall) => {} + (ty::ExprKind::Cast(a_kind), ty::ExprKind::Cast(b_kind)) if a_kind == b_kind => {} _ => return Err(TypeError::ConstMismatch(expected_found(a, b))), - }; - return Ok(ty::Const::new_expr(tcx, expr, a.ty())); + } + + let args = relation.relate(ae.args(), be.args())?; + return Ok(ty::Const::new_expr(tcx, ty::Expr::new(ae.kind, args), a.ty())); } _ => false, }; @@ -756,28 +728,6 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> { } } -impl<'tcx> Relate<'tcx> for ty::ClosureArgs<'tcx> { - fn relate>( - relation: &mut R, - a: ty::ClosureArgs<'tcx>, - b: ty::ClosureArgs<'tcx>, - ) -> RelateResult<'tcx, ty::ClosureArgs<'tcx>> { - let args = relate_args_invariantly(relation, a.args, b.args)?; - Ok(ty::ClosureArgs { args }) - } -} - -impl<'tcx> Relate<'tcx> for ty::CoroutineArgs<'tcx> { - fn relate>( - relation: &mut R, - a: ty::CoroutineArgs<'tcx>, - b: ty::CoroutineArgs<'tcx>, - ) -> RelateResult<'tcx, ty::CoroutineArgs<'tcx>> { - let args = relate_args_invariantly(relation, a.args, b.args)?; - Ok(ty::CoroutineArgs { args }) - } -} - impl<'tcx> Relate<'tcx> for GenericArgsRef<'tcx> { fn relate>( relation: &mut R, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index af3aa3b56f7b..7a291b4dbff6 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -147,14 +147,27 @@ impl<'tcx> DebugWithInfcx> for ty::consts::Expr<'tcx> { this: WithInfcx<'_, Infcx, &Self>, f: &mut core::fmt::Formatter<'_>, ) -> core::fmt::Result { - match this.data { - ty::Expr::Binop(op, lhs, rhs) => { - write!(f, "({op:?}: {:?}, {:?})", &this.wrap(lhs), &this.wrap(rhs)) + match this.data.kind { + ty::ExprKind::Binop(op) => { + let (lhs_ty, rhs_ty, lhs, rhs) = this.data.binop_args(); + write!( + f, + "({op:?}: ({:?}: {:?}), ({:?}: {:?}))", + &this.wrap(lhs), + &this.wrap(lhs_ty), + &this.wrap(rhs), + &this.wrap(rhs_ty), + ) } - ty::Expr::UnOp(op, rhs) => write!(f, "({op:?}: {:?})", &this.wrap(rhs)), - ty::Expr::FunctionCall(func, args) => { - write!(f, "{:?}(", &this.wrap(func))?; - for arg in args.as_slice().iter().rev().skip(1).rev() { + ty::ExprKind::UnOp(op) => { + let (rhs_ty, rhs) = this.data.unop_args(); + write!(f, "({op:?}: ({:?}: {:?}))", &this.wrap(rhs), &this.wrap(rhs_ty)) + } + ty::ExprKind::FunctionCall => { + let (func_ty, func, args) = this.data.call_args(); + let args = args.collect::>(); + write!(f, "({:?}: {:?})(", &this.wrap(func), &this.wrap(func_ty))?; + for arg in args.iter().rev().skip(1).rev() { write!(f, "{:?}, ", &this.wrap(arg))?; } if let Some(arg) = args.last() { @@ -163,8 +176,15 @@ impl<'tcx> DebugWithInfcx> for ty::consts::Expr<'tcx> { write!(f, ")") } - ty::Expr::Cast(cast_kind, lhs, rhs) => { - write!(f, "({cast_kind:?}: {:?}, {:?})", &this.wrap(lhs), &this.wrap(rhs)) + ty::ExprKind::Cast(kind) => { + let (value_ty, value, to_ty) = this.data.cast_args(); + write!( + f, + "({kind:?}: ({:?}: {:?}), {:?})", + &this.wrap(value), + &this.wrap(value_ty), + &this.wrap(to_ty) + ) } } } @@ -259,18 +279,6 @@ impl<'tcx> DebugWithInfcx> for Region<'tcx> { } } -impl<'tcx, T: DebugWithInfcx>> DebugWithInfcx> for ty::Binder<'tcx, T> { - fn fmt>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - f.debug_tuple("Binder") - .field(&this.map(|data| data.as_ref().skip_binder())) - .field(&this.data.bound_vars()) - .finish() - } -} - /////////////////////////////////////////////////////////////////////////// // Atomic structs // diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 5cf96d298375..879396b06781 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -16,7 +16,7 @@ use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; -use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable}; +use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; @@ -25,12 +25,11 @@ use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::iter; use std::ops::{ControlFlow, Range}; -use ty::util::IntTypeExt; +use ty::util::{AsyncDropGlueMorphology, IntTypeExt}; use rustc_type_ir::TyKind::*; use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind}; -use super::fold::FnMutDelegate; use super::GenericParamDefKind; // Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here @@ -60,670 +59,14 @@ impl<'tcx> Article for TyKind<'tcx> { } } -/// A closure can be modeled as a struct that looks like: -/// ```ignore (illustrative) -/// struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U); -/// ``` -/// where: -/// -/// - 'l0...'li and T0...Tj are the generic parameters -/// in scope on the function that defined the closure, -/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This -/// is rather hackily encoded via a scalar type. See -/// `Ty::to_opt_closure_kind` for details. -/// - CS represents the *closure signature*, representing as a `fn()` -/// type. For example, `fn(u32, u32) -> u32` would mean that the closure -/// implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait -/// specified above. -/// - U is a type parameter representing the types of its upvars, tupled up -/// (borrowed, if appropriate; that is, if a U field represents a by-ref upvar, -/// and the up-var has the type `Foo`, then that field of U will be `&Foo`). -/// -/// So, for example, given this function: -/// ```ignore (illustrative) -/// fn foo<'a, T>(data: &'a mut T) { -/// do(|| data.count += 1) -/// } -/// ``` -/// the type of the closure would be something like: -/// ```ignore (illustrative) -/// struct Closure<'a, T, U>(...U); -/// ``` -/// Note that the type of the upvar is not specified in the struct. -/// You may wonder how the impl would then be able to use the upvar, -/// if it doesn't know it's type? The answer is that the impl is -/// (conceptually) not fully generic over Closure but rather tied to -/// instances with the expected upvar types: -/// ```ignore (illustrative) -/// impl<'b, 'a, T> FnMut() for Closure<'a, T, (&'b mut &'a mut T,)> { -/// ... -/// } -/// ``` -/// You can see that the *impl* fully specified the type of the upvar -/// and thus knows full well that `data` has type `&'b mut &'a mut T`. -/// (Here, I am assuming that `data` is mut-borrowed.) -/// -/// Now, the last question you may ask is: Why include the upvar types -/// in an extra type parameter? The reason for this design is that the -/// upvar types can reference lifetimes that are internal to the -/// creating function. In my example above, for example, the lifetime -/// `'b` represents the scope of the closure itself; this is some -/// subset of `foo`, probably just the scope of the call to the to -/// `do()`. If we just had the lifetime/type parameters from the -/// enclosing function, we couldn't name this lifetime `'b`. Note that -/// there can also be lifetimes in the types of the upvars themselves, -/// if one of them happens to be a reference to something that the -/// creating fn owns. -/// -/// OK, you say, so why not create a more minimal set of parameters -/// that just includes the extra lifetime parameters? The answer is -/// primarily that it would be hard --- we don't know at the time when -/// we create the closure type what the full types of the upvars are, -/// nor do we know which are borrowed and which are not. In this -/// design, we can just supply a fresh type parameter and figure that -/// out later. -/// -/// All right, you say, but why include the type parameters from the -/// original function then? The answer is that codegen may need them -/// when monomorphizing, and they may not appear in the upvars. A -/// closure could capture no variables but still make use of some -/// in-scope type parameter with a bound (e.g., if our example above -/// had an extra `U: Default`, and the closure called `U::default()`). -/// -/// There is another reason. This design (implicitly) prohibits -/// closures from capturing themselves (except via a trait -/// object). This simplifies closure inference considerably, since it -/// means that when we infer the kind of a closure or its upvars, we -/// don't have to handle cycles where the decisions we make for -/// closure C wind up influencing the decisions we ought to make for -/// closure C (which would then require fixed point iteration to -/// handle). Plus it fixes an ICE. :P -/// -/// ## Coroutines -/// -/// Coroutines are handled similarly in `CoroutineArgs`. The set of -/// type parameters is similar, but `CK` and `CS` are replaced by the -/// following type parameters: -/// -/// * `GS`: The coroutine's "resume type", which is the type of the -/// argument passed to `resume`, and the type of `yield` expressions -/// inside the coroutine. -/// * `GY`: The "yield type", which is the type of values passed to -/// `yield` inside the coroutine. -/// * `GR`: The "return type", which is the type of value returned upon -/// completion of the coroutine. -/// * `GW`: The "coroutine witness". -#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)] -pub struct ClosureArgs<'tcx> { - /// Lifetime and type parameters from the enclosing function, - /// concatenated with a tuple containing the types of the upvars. - /// - /// These are separated out because codegen wants to pass them around - /// when monomorphizing. - pub args: GenericArgsRef<'tcx>, -} - -/// Struct returned by `split()`. -pub struct ClosureArgsParts<'tcx> { - /// This is the args of the typeck root. - pub parent_args: &'tcx [GenericArg<'tcx>], - /// Represents the maximum calling capability of the closure. - pub closure_kind_ty: Ty<'tcx>, - /// Captures the closure's signature. This closure signature is "tupled", and - /// thus has a peculiar signature of `extern "rust-call" fn((Args, ...)) -> Ty`. - pub closure_sig_as_fn_ptr_ty: Ty<'tcx>, - /// The upvars captured by the closure. Remains an inference variable - /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: Ty<'tcx>, -} - -impl<'tcx> ClosureArgs<'tcx> { - /// Construct `ClosureArgs` from `ClosureArgsParts`, containing `Args` - /// for the closure parent, alongside additional closure-specific components. - pub fn new(tcx: TyCtxt<'tcx>, parts: ClosureArgsParts<'tcx>) -> ClosureArgs<'tcx> { - ClosureArgs { - args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ - parts.closure_kind_ty.into(), - parts.closure_sig_as_fn_ptr_ty.into(), - parts.tupled_upvars_ty.into(), - ])), - } - } - - /// Divides the closure args into their respective components. - /// The ordering assumed here must match that used by `ClosureArgs::new` above. - fn split(self) -> ClosureArgsParts<'tcx> { - match self.args[..] { - [ref parent_args @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => { - ClosureArgsParts { - parent_args, - closure_kind_ty: closure_kind_ty.expect_ty(), - closure_sig_as_fn_ptr_ty: closure_sig_as_fn_ptr_ty.expect_ty(), - tupled_upvars_ty: tupled_upvars_ty.expect_ty(), - } - } - _ => bug!("closure args missing synthetics"), - } - } - - /// Returns the generic parameters of the closure's parent. - pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] { - self.split().parent_args - } - - /// Returns an iterator over the list of types of captured paths by the closure. - /// In case there was a type error in figuring out the types of the captured path, an - /// empty iterator is returned. - #[inline] - pub fn upvar_tys(self) -> &'tcx List> { - match *self.tupled_upvars_ty().kind() { - TyKind::Error(_) => ty::List::empty(), - TyKind::Tuple(tys) => tys, - TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), - ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), - } - } - - /// Returns the tuple type representing the upvars for this closure. - #[inline] - pub fn tupled_upvars_ty(self) -> Ty<'tcx> { - self.split().tupled_upvars_ty - } - - /// Returns the closure kind for this closure; may return a type - /// variable during inference. To get the closure kind during - /// inference, use `infcx.closure_kind(args)`. - pub fn kind_ty(self) -> Ty<'tcx> { - self.split().closure_kind_ty - } - - /// Returns the `fn` pointer type representing the closure signature for this - /// closure. - // FIXME(eddyb) this should be unnecessary, as the shallowly resolved - // type is known at the time of the creation of `ClosureArgs`, - // see `rustc_hir_analysis::check::closure`. - pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> { - self.split().closure_sig_as_fn_ptr_ty - } - - /// Returns the closure kind for this closure; only usable outside - /// of an inference context, because in that context we know that - /// there are no type variables. - /// - /// If you have an inference context, use `infcx.closure_kind()`. - pub fn kind(self) -> ty::ClosureKind { - self.kind_ty().to_opt_closure_kind().unwrap() - } - - /// Extracts the signature from the closure. - pub fn sig(self) -> ty::PolyFnSig<'tcx> { - match *self.sig_as_fn_ptr_ty().kind() { - ty::FnPtr(sig) => sig, - ty => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {ty:?}"), - } - } - - pub fn print_as_impl_trait(self) -> ty::print::PrintClosureAsImpl<'tcx> { - ty::print::PrintClosureAsImpl { closure: self } - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)] -pub struct CoroutineClosureArgs<'tcx> { - pub args: GenericArgsRef<'tcx>, -} - -/// See docs for explanation of how each argument is used. -/// -/// See [`CoroutineClosureSignature`] for how these arguments are put together -/// to make a callable [`FnSig`] suitable for typeck and borrowck. -pub struct CoroutineClosureArgsParts<'tcx> { - /// This is the args of the typeck root. - pub parent_args: &'tcx [GenericArg<'tcx>], - /// Represents the maximum calling capability of the closure. - pub closure_kind_ty: Ty<'tcx>, - /// Represents all of the relevant parts of the coroutine returned by this - /// coroutine-closure. This signature parts type will have the general - /// shape of `fn(tupled_inputs, resume_ty) -> (return_ty, yield_ty)`, where - /// `resume_ty`, `return_ty`, and `yield_ty` are the respective types for the - /// coroutine returned by the coroutine-closure. - /// - /// Use `coroutine_closure_sig` to break up this type rather than using it - /// yourself. - pub signature_parts_ty: Ty<'tcx>, - /// The upvars captured by the closure. Remains an inference variable - /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: Ty<'tcx>, - /// a function pointer that has the shape `for<'env> fn() -> (&'env T, ...)`. - /// This allows us to represent the binder of the self-captures of the closure. - /// - /// For example, if the coroutine returned by the closure borrows `String` - /// from the closure's upvars, this will be `for<'env> fn() -> (&'env String,)`, - /// while the `tupled_upvars_ty`, representing the by-move version of the same - /// captures, will be `(String,)`. - pub coroutine_captures_by_ref_ty: Ty<'tcx>, - /// Witness type returned by the generator produced by this coroutine-closure. - pub coroutine_witness_ty: Ty<'tcx>, -} - -impl<'tcx> CoroutineClosureArgs<'tcx> { - pub fn new( - tcx: TyCtxt<'tcx>, - parts: CoroutineClosureArgsParts<'tcx>, - ) -> CoroutineClosureArgs<'tcx> { - CoroutineClosureArgs { - args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ - parts.closure_kind_ty.into(), - parts.signature_parts_ty.into(), - parts.tupled_upvars_ty.into(), - parts.coroutine_captures_by_ref_ty.into(), - parts.coroutine_witness_ty.into(), - ])), - } - } - - fn split(self) -> CoroutineClosureArgsParts<'tcx> { - match self.args[..] { - [ - ref parent_args @ .., - closure_kind_ty, - signature_parts_ty, - tupled_upvars_ty, - coroutine_captures_by_ref_ty, - coroutine_witness_ty, - ] => CoroutineClosureArgsParts { - parent_args, - closure_kind_ty: closure_kind_ty.expect_ty(), - signature_parts_ty: signature_parts_ty.expect_ty(), - tupled_upvars_ty: tupled_upvars_ty.expect_ty(), - coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(), - coroutine_witness_ty: coroutine_witness_ty.expect_ty(), - }, - _ => bug!("closure args missing synthetics"), - } - } - - pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] { - self.split().parent_args - } - - #[inline] - pub fn upvar_tys(self) -> &'tcx List> { - match self.tupled_upvars_ty().kind() { - TyKind::Error(_) => ty::List::empty(), - TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(), - TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), - ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), - } - } - - #[inline] - pub fn tupled_upvars_ty(self) -> Ty<'tcx> { - self.split().tupled_upvars_ty - } - - pub fn kind_ty(self) -> Ty<'tcx> { - self.split().closure_kind_ty - } - - pub fn kind(self) -> ty::ClosureKind { - self.kind_ty().to_opt_closure_kind().unwrap() - } - - pub fn signature_parts_ty(self) -> Ty<'tcx> { - self.split().signature_parts_ty - } - - pub fn coroutine_closure_sig(self) -> Binder<'tcx, CoroutineClosureSignature<'tcx>> { - let interior = self.coroutine_witness_ty(); - let ty::FnPtr(sig) = self.signature_parts_ty().kind() else { bug!() }; - sig.map_bound(|sig| { - let [resume_ty, tupled_inputs_ty] = *sig.inputs() else { - bug!(); - }; - let [yield_ty, return_ty] = **sig.output().tuple_fields() else { bug!() }; - CoroutineClosureSignature { - interior, - tupled_inputs_ty, - resume_ty, - yield_ty, - return_ty, - c_variadic: sig.c_variadic, - safety: sig.safety, - abi: sig.abi, - } - }) - } - - pub fn coroutine_captures_by_ref_ty(self) -> Ty<'tcx> { - self.split().coroutine_captures_by_ref_ty - } - - pub fn coroutine_witness_ty(self) -> Ty<'tcx> { - self.split().coroutine_witness_ty - } - - pub fn has_self_borrows(&self) -> bool { - match self.coroutine_captures_by_ref_ty().kind() { - ty::FnPtr(sig) => sig - .skip_binder() - .visit_with(&mut HasRegionsBoundAt { binder: ty::INNERMOST }) - .is_break(), - ty::Error(_) => true, - _ => bug!(), - } - } -} -/// Unlike `has_escaping_bound_vars` or `outermost_exclusive_binder`, this will -/// detect only regions bound *at* the debruijn index. -struct HasRegionsBoundAt { - binder: ty::DebruijnIndex, -} -// FIXME: Could be optimized to not walk into components with no escaping bound vars. -impl<'tcx> TypeVisitor> for HasRegionsBoundAt { - type Result = ControlFlow<()>; - fn visit_binder>>( - &mut self, - t: &ty::Binder<'tcx, T>, - ) -> Self::Result { - self.binder.shift_in(1); - t.super_visit_with(self)?; - self.binder.shift_out(1); - ControlFlow::Continue(()) - } - - fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result { - if let ty::ReBound(binder, _) = *r - && self.binder == binder - { - ControlFlow::Break(()) - } else { - ControlFlow::Continue(()) - } - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)] -pub struct CoroutineClosureSignature<'tcx> { - pub interior: Ty<'tcx>, - pub tupled_inputs_ty: Ty<'tcx>, - pub resume_ty: Ty<'tcx>, - pub yield_ty: Ty<'tcx>, - pub return_ty: Ty<'tcx>, - - // Like the `fn_sig_as_fn_ptr_ty` of a regular closure, these types - // never actually differ. But we save them rather than recreating them - // from scratch just for good measure. - /// Always false - pub c_variadic: bool, - /// Always [`hir::Safety::Safe`] - pub safety: hir::Safety, - /// Always [`abi::Abi::RustCall`] - pub abi: abi::Abi, -} - -impl<'tcx> CoroutineClosureSignature<'tcx> { - /// Construct a coroutine from the closure signature. Since a coroutine signature - /// is agnostic to the type of generator that is returned (by-ref/by-move), - /// the caller must specify what "flavor" of generator that they'd like to - /// create. Additionally, they must manually compute the upvars of the closure. - /// - /// This helper is not really meant to be used directly except for early on - /// during typeck, when we want to put inference vars into the kind and upvars tys. - /// When the kind and upvars are known, use the other helper functions. - pub fn to_coroutine( - self, - tcx: TyCtxt<'tcx>, - parent_args: &'tcx [GenericArg<'tcx>], - coroutine_kind_ty: Ty<'tcx>, - coroutine_def_id: DefId, - tupled_upvars_ty: Ty<'tcx>, - ) -> Ty<'tcx> { - let coroutine_args = ty::CoroutineArgs::new( - tcx, - ty::CoroutineArgsParts { - parent_args, - kind_ty: coroutine_kind_ty, - resume_ty: self.resume_ty, - yield_ty: self.yield_ty, - return_ty: self.return_ty, - witness: self.interior, - tupled_upvars_ty, - }, - ); - - Ty::new_coroutine(tcx, coroutine_def_id, coroutine_args.args) - } - - /// Given known upvars and a [`ClosureKind`](ty::ClosureKind), compute the coroutine - /// returned by that corresponding async fn trait. - /// - /// This function expects the upvars to have been computed already, and doesn't check - /// that the `ClosureKind` is actually supported by the coroutine-closure. - pub fn to_coroutine_given_kind_and_upvars( - self, - tcx: TyCtxt<'tcx>, - parent_args: &'tcx [GenericArg<'tcx>], - coroutine_def_id: DefId, - goal_kind: ty::ClosureKind, - env_region: ty::Region<'tcx>, - closure_tupled_upvars_ty: Ty<'tcx>, - coroutine_captures_by_ref_ty: Ty<'tcx>, - ) -> Ty<'tcx> { - let tupled_upvars_ty = Self::tupled_upvars_by_closure_kind( - tcx, - goal_kind, - self.tupled_inputs_ty, - closure_tupled_upvars_ty, - coroutine_captures_by_ref_ty, - env_region, - ); - - self.to_coroutine( - tcx, - parent_args, - Ty::from_coroutine_closure_kind(tcx, goal_kind), - coroutine_def_id, - tupled_upvars_ty, - ) - } - - /// Compute the tupled upvars that a coroutine-closure's output coroutine - /// would return for the given `ClosureKind`. - /// - /// When `ClosureKind` is `FnMut`/`Fn`, then this will use the "captures by ref" - /// to return a set of upvars which are borrowed with the given `env_region`. - /// - /// This ensures that the `AsyncFn::call` will return a coroutine whose upvars' - /// lifetimes are related to the lifetime of the borrow on the closure made for - /// the call. This allows borrowck to enforce the self-borrows correctly. - pub fn tupled_upvars_by_closure_kind( - tcx: TyCtxt<'tcx>, - kind: ty::ClosureKind, - tupled_inputs_ty: Ty<'tcx>, - closure_tupled_upvars_ty: Ty<'tcx>, - coroutine_captures_by_ref_ty: Ty<'tcx>, - env_region: ty::Region<'tcx>, - ) -> Ty<'tcx> { - match kind { - ty::ClosureKind::Fn | ty::ClosureKind::FnMut => { - let ty::FnPtr(sig) = *coroutine_captures_by_ref_ty.kind() else { - bug!(); - }; - let coroutine_captures_by_ref_ty = tcx.replace_escaping_bound_vars_uncached( - sig.output().skip_binder(), - FnMutDelegate { - consts: &mut |c, t| ty::Const::new_bound(tcx, ty::INNERMOST, c, t), - types: &mut |t| Ty::new_bound(tcx, ty::INNERMOST, t), - regions: &mut |_| env_region, - }, - ); - Ty::new_tup_from_iter( - tcx, - tupled_inputs_ty - .tuple_fields() - .iter() - .chain(coroutine_captures_by_ref_ty.tuple_fields()), - ) - } - ty::ClosureKind::FnOnce => Ty::new_tup_from_iter( - tcx, - tupled_inputs_ty - .tuple_fields() - .iter() - .chain(closure_tupled_upvars_ty.tuple_fields()), - ), - } - } -} -/// Similar to `ClosureArgs`; see the above documentation for more. -#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)] -pub struct CoroutineArgs<'tcx> { - pub args: GenericArgsRef<'tcx>, -} - -pub struct CoroutineArgsParts<'tcx> { - /// This is the args of the typeck root. - pub parent_args: &'tcx [GenericArg<'tcx>], - - /// The coroutines returned by a coroutine-closure's `AsyncFnOnce`/`AsyncFnMut` - /// implementations must be distinguished since the former takes the closure's - /// upvars by move, and the latter takes the closure's upvars by ref. - /// - /// This field distinguishes these fields so that codegen can select the right - /// body for the coroutine. This has the same type representation as the closure - /// kind: `i8`/`i16`/`i32`. - /// - /// For regular coroutines, this field will always just be `()`. - pub kind_ty: Ty<'tcx>, - - pub resume_ty: Ty<'tcx>, - pub yield_ty: Ty<'tcx>, - pub return_ty: Ty<'tcx>, - - /// The interior type of the coroutine. - /// Represents all types that are stored in locals - /// in the coroutine's body. - pub witness: Ty<'tcx>, - - /// The upvars captured by the closure. Remains an inference variable - /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: Ty<'tcx>, -} - -impl<'tcx> CoroutineArgs<'tcx> { - /// Construct `CoroutineArgs` from `CoroutineArgsParts`, containing `Args` - /// for the coroutine parent, alongside additional coroutine-specific components. - pub fn new(tcx: TyCtxt<'tcx>, parts: CoroutineArgsParts<'tcx>) -> CoroutineArgs<'tcx> { - CoroutineArgs { - args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ - parts.kind_ty.into(), - parts.resume_ty.into(), - parts.yield_ty.into(), - parts.return_ty.into(), - parts.witness.into(), - parts.tupled_upvars_ty.into(), - ])), - } - } - - /// Divides the coroutine args into their respective components. - /// The ordering assumed here must match that used by `CoroutineArgs::new` above. - fn split(self) -> CoroutineArgsParts<'tcx> { - match self.args[..] { - [ - ref parent_args @ .., - kind_ty, - resume_ty, - yield_ty, - return_ty, - witness, - tupled_upvars_ty, - ] => CoroutineArgsParts { - parent_args, - kind_ty: kind_ty.expect_ty(), - resume_ty: resume_ty.expect_ty(), - yield_ty: yield_ty.expect_ty(), - return_ty: return_ty.expect_ty(), - witness: witness.expect_ty(), - tupled_upvars_ty: tupled_upvars_ty.expect_ty(), - }, - _ => bug!("coroutine args missing synthetics"), - } - } - - /// Returns the generic parameters of the coroutine's parent. - pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] { - self.split().parent_args - } - - // Returns the kind of the coroutine. See docs on the `kind_ty` field. - pub fn kind_ty(self) -> Ty<'tcx> { - self.split().kind_ty - } - - /// This describes the types that can be contained in a coroutine. - /// It will be a type variable initially and unified in the last stages of typeck of a body. - /// It contains a tuple of all the types that could end up on a coroutine frame. - /// The state transformation MIR pass may only produce layouts which mention types - /// in this tuple. Upvars are not counted here. - pub fn witness(self) -> Ty<'tcx> { - self.split().witness - } - - /// Returns an iterator over the list of types of captured paths by the coroutine. - /// In case there was a type error in figuring out the types of the captured path, an - /// empty iterator is returned. - #[inline] - pub fn upvar_tys(self) -> &'tcx List> { - match *self.tupled_upvars_ty().kind() { - TyKind::Error(_) => ty::List::empty(), - TyKind::Tuple(tys) => tys, - TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), - ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), - } - } - - /// Returns the tuple type representing the upvars for this coroutine. - #[inline] - pub fn tupled_upvars_ty(self) -> Ty<'tcx> { - self.split().tupled_upvars_ty - } - - /// Returns the type representing the resume type of the coroutine. - pub fn resume_ty(self) -> Ty<'tcx> { - self.split().resume_ty - } - - /// Returns the type representing the yield type of the coroutine. - pub fn yield_ty(self) -> Ty<'tcx> { - self.split().yield_ty - } - - /// Returns the type representing the return type of the coroutine. - pub fn return_ty(self) -> Ty<'tcx> { - self.split().return_ty - } - - /// Returns the "coroutine signature", which consists of its resume, yield - /// and return types. - pub fn sig(self) -> GenSig<'tcx> { - let parts = self.split(); - ty::GenSig { - resume_ty: parts.resume_ty, - yield_ty: parts.yield_ty, - return_ty: parts.return_ty, - } - } -} - -impl<'tcx> CoroutineArgs<'tcx> { +#[extension(pub trait CoroutineArgsExt<'tcx>)] +impl<'tcx> ty::CoroutineArgs> { /// Coroutine has not been resumed yet. - pub const UNRESUMED: usize = 0; + const UNRESUMED: usize = 0; /// Coroutine has returned or is completed. - pub const RETURNED: usize = 1; + const RETURNED: usize = 1; /// Coroutine has been poisoned. - pub const POISONED: usize = 2; + const POISONED: usize = 2; const UNRESUMED_NAME: &'static str = "Unresumed"; const RETURNED_NAME: &'static str = "Returned"; @@ -731,7 +74,7 @@ impl<'tcx> CoroutineArgs<'tcx> { /// The valid variant indices of this coroutine. #[inline] - pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range { + fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range { // FIXME requires optimized MIR FIRST_VARIANT ..tcx.coroutine_layout(def_id, tcx.types.unit).unwrap().variant_fields.next_index() @@ -740,7 +83,7 @@ impl<'tcx> CoroutineArgs<'tcx> { /// The discriminant for the given variant. Panics if the `variant_index` is /// out of range. #[inline] - pub fn discriminant_for_variant( + fn discriminant_for_variant( &self, def_id: DefId, tcx: TyCtxt<'tcx>, @@ -755,7 +98,7 @@ impl<'tcx> CoroutineArgs<'tcx> { /// The set of all discriminants for the coroutine, enumerated with their /// variant indices. #[inline] - pub fn discriminants( + fn discriminants( self, def_id: DefId, tcx: TyCtxt<'tcx>, @@ -767,7 +110,7 @@ impl<'tcx> CoroutineArgs<'tcx> { /// Calls `f` with a reference to the name of the enumerator for the given /// variant `v`. - pub fn variant_name(v: VariantIdx) -> Cow<'static, str> { + fn variant_name(v: VariantIdx) -> Cow<'static, str> { match v.as_usize() { Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME), Self::RETURNED => Cow::from(Self::RETURNED_NAME), @@ -778,7 +121,7 @@ impl<'tcx> CoroutineArgs<'tcx> { /// The type of the state discriminant used in the coroutine type. #[inline] - pub fn discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + fn discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { tcx.types.u32 } @@ -789,7 +132,7 @@ impl<'tcx> CoroutineArgs<'tcx> { /// The locals are grouped by their variant number. Note that some locals may /// be repeated in multiple variants. #[inline] - pub fn state_tys( + fn state_tys( self, def_id: DefId, tcx: TyCtxt<'tcx>, @@ -805,7 +148,7 @@ impl<'tcx> CoroutineArgs<'tcx> { /// This is the types of the fields of a coroutine which are not stored in a /// variant. #[inline] - pub fn prefix_tys(self) -> &'tcx List> { + fn prefix_tys(self) -> &'tcx List> { self.upvar_tys() } } @@ -859,7 +202,7 @@ impl<'tcx> UpvarArgs<'tcx> { /// /// When the inline const is instantiated, `R` is instantiated as the actual inferred /// type of the constant. The reason that `R` is represented as an extra type parameter -/// is the same reason that [`ClosureArgs`] have `CS` and `U` as type parameters: +/// is the same reason that [`ty::ClosureArgs`] have `CS` and `U` as type parameters: /// inline const can reference lifetimes that are internal to the creating function. #[derive(Copy, Clone, Debug)] pub struct InlineConstArgs<'tcx> { @@ -938,13 +281,6 @@ impl BoundVariableKind { } } -#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] -pub struct GenSig<'tcx> { - pub resume_ty: Ty<'tcx>, - pub yield_ty: Ty<'tcx>, - pub return_ty: Ty<'tcx>, -} - pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>; pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>; @@ -1451,6 +787,41 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> { ) -> Self { Ty::new_alias(interner, kind, alias_ty) } + + fn new_coroutine( + interner: TyCtxt<'tcx>, + def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + ) -> Self { + Ty::new_coroutine(interner, def_id, args) + } + + fn new_tup_from_iter(interner: TyCtxt<'tcx>, iter: It) -> T::Output + where + It: Iterator, + T: CollectAndApply, + { + Ty::new_tup_from_iter(interner, iter) + } + + fn tuple_fields(self) -> &'tcx ty::List> { + self.tuple_fields() + } + + fn to_opt_closure_kind(self) -> Option { + self.to_opt_closure_kind() + } + + fn from_closure_kind(interner: TyCtxt<'tcx>, kind: ty::ClosureKind) -> Self { + Ty::from_closure_kind(interner, kind) + } + + fn from_coroutine_closure_kind( + interner: TyCtxt<'tcx>, + kind: rustc_type_ir::ClosureKind, + ) -> Self { + Ty::from_coroutine_closure_kind(interner, kind) + } } /// Type utilities @@ -1951,11 +1322,22 @@ impl<'tcx> Ty<'tcx> { } /// Returns the type of the async destructor of this type. - pub fn async_destructor_ty(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Ty<'tcx> { - if self.is_async_destructor_noop(tcx, param_env) || matches!(self.kind(), ty::Error(_)) { - return Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop) - .instantiate_identity(); + pub fn async_destructor_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + match self.async_drop_glue_morphology(tcx) { + AsyncDropGlueMorphology::Noop => { + return Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop) + .instantiate_identity(); + } + AsyncDropGlueMorphology::DeferredDropInPlace => { + let drop_in_place = + Ty::async_destructor_combinator(tcx, LangItem::AsyncDropDeferredDropInPlace) + .instantiate(tcx, &[self.into()]); + return Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse) + .instantiate(tcx, &[drop_in_place.into()]); + } + AsyncDropGlueMorphology::Custom => (), } + match *self.kind() { ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => { let assoc_items = tcx @@ -1974,24 +1356,18 @@ impl<'tcx> Ty<'tcx> { .adt_async_destructor_ty( tcx, adt_def.variants().iter().map(|v| v.fields.iter().map(|f| f.ty(tcx, args))), - param_env, ), - ty::Tuple(tys) => self.adt_async_destructor_ty(tcx, iter::once(tys), param_env), - ty::Closure(_, args) => self.adt_async_destructor_ty( - tcx, - iter::once(args.as_closure().upvar_tys()), - param_env, - ), - ty::CoroutineClosure(_, args) => self.adt_async_destructor_ty( - tcx, - iter::once(args.as_coroutine_closure().upvar_tys()), - param_env, - ), + ty::Tuple(tys) => self.adt_async_destructor_ty(tcx, iter::once(tys)), + ty::Closure(_, args) => { + self.adt_async_destructor_ty(tcx, iter::once(args.as_closure().upvar_tys())) + } + ty::CoroutineClosure(_, args) => self + .adt_async_destructor_ty(tcx, iter::once(args.as_coroutine_closure().upvar_tys())), ty::Adt(adt_def, _) => { assert!(adt_def.is_union()); - let surface_drop = self.surface_async_dropper_ty(tcx, param_env).unwrap(); + let surface_drop = self.surface_async_dropper_ty(tcx).unwrap(); Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse) .instantiate(tcx, &[surface_drop.into()]) @@ -2008,17 +1384,12 @@ impl<'tcx> Ty<'tcx> { } } - fn adt_async_destructor_ty( - self, - tcx: TyCtxt<'tcx>, - variants: I, - param_env: ParamEnv<'tcx>, - ) -> Ty<'tcx> + fn adt_async_destructor_ty(self, tcx: TyCtxt<'tcx>, variants: I) -> Ty<'tcx> where I: Iterator + ExactSizeIterator, I::Item: IntoIterator>, { - debug_assert!(!self.is_async_destructor_noop(tcx, param_env)); + debug_assert_eq!(self.async_drop_glue_morphology(tcx), AsyncDropGlueMorphology::Custom); let defer = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropDefer); let chain = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain); @@ -2041,7 +1412,7 @@ impl<'tcx> Ty<'tcx> { }) .unwrap(); - let dtor = if let Some(dropper_ty) = self.surface_async_dropper_ty(tcx, param_env) { + let dtor = if let Some(dropper_ty) = self.surface_async_dropper_ty(tcx) { Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain) .instantiate(tcx, &[dropper_ty.into(), variants_dtor.into()]) } else { @@ -2052,21 +1423,13 @@ impl<'tcx> Ty<'tcx> { .instantiate(tcx, &[dtor.into()]) } - fn surface_async_dropper_ty( - self, - tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, - ) -> Option> { - if self.has_surface_async_drop(tcx, param_env) { - Some(LangItem::SurfaceAsyncDropInPlace) - } else if self.has_surface_drop(tcx, param_env) { - Some(LangItem::AsyncDropSurfaceDropInPlace) - } else { - None - } - .map(|dropper| { - Ty::async_destructor_combinator(tcx, dropper).instantiate(tcx, &[self.into()]) - }) + fn surface_async_dropper_ty(self, tcx: TyCtxt<'tcx>) -> Option> { + let adt_def = self.ty_adt_def()?; + let dropper = adt_def + .async_destructor(tcx) + .map(|_| LangItem::SurfaceAsyncDropInPlace) + .or_else(|| adt_def.destructor(tcx).map(|_| LangItem::AsyncDropSurfaceDropInPlace))?; + Some(Ty::async_destructor_combinator(tcx, dropper).instantiate(tcx, &[self.into()])) } fn async_destructor_combinator( @@ -2177,8 +1540,8 @@ impl<'tcx> Ty<'tcx> { /// } /// ``` /// - /// After upvar analysis, you should instead use [`ClosureArgs::kind()`] - /// or [`CoroutineClosureArgs::kind()`] to assert that the `ClosureKind` + /// After upvar analysis, you should instead use [`ty::ClosureArgs::kind()`] + /// or [`ty::CoroutineClosureArgs::kind()`] to assert that the `ClosureKind` /// has been constrained instead of manually calling this method. /// /// ```rust,ignore (snippet of compiler code) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index cacaa859d526..52a0e72e17e2 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -4,7 +4,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::query::{IntoQueryParam, Providers}; use crate::ty::layout::{FloatExt, IntegerExt}; use crate::ty::{ - self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + self, Asyncness, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, Upcast, }; use crate::ty::{GenericArgKind, GenericArgsRef}; @@ -382,6 +382,64 @@ impl<'tcx> TyCtxt<'tcx> { Some(ty::Destructor { did, constness }) } + /// Calculate the async destructor of a given type. + pub fn calculate_async_dtor( + self, + adt_did: DefId, + validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>, + ) -> Option { + let async_drop_trait = self.lang_items().async_drop_trait()?; + self.ensure().coherent_trait(async_drop_trait).ok()?; + + let ty = self.type_of(adt_did).instantiate_identity(); + let mut dtor_candidate = None; + self.for_each_relevant_impl(async_drop_trait, ty, |impl_did| { + if validate(self, impl_did).is_err() { + // Already `ErrorGuaranteed`, no need to delay a span bug here. + return; + } + + let [future, ctor] = self.associated_item_def_ids(impl_did) else { + self.dcx().span_delayed_bug( + self.def_span(impl_did), + "AsyncDrop impl without async_drop function or Dropper type", + ); + return; + }; + + if let Some((_, _, old_impl_did)) = dtor_candidate { + self.dcx() + .struct_span_err(self.def_span(impl_did), "multiple async drop impls found") + .with_span_note(self.def_span(old_impl_did), "other impl here") + .delay_as_bug(); + } + + dtor_candidate = Some((*future, *ctor, impl_did)); + }); + + let (future, ctor, _) = dtor_candidate?; + Some(ty::AsyncDestructor { future, ctor }) + } + + /// Returns async drop glue morphology for a definition. To get async drop + /// glue morphology for a type see [`Ty::async_drop_glue_morphology`]. + // + // FIXME: consider making this a query + pub fn async_drop_glue_morphology(self, did: DefId) -> AsyncDropGlueMorphology { + let ty: Ty<'tcx> = self.type_of(did).instantiate_identity(); + + // Async drop glue morphology is an internal detail, so reveal_all probably + // should be fine + let param_env = ty::ParamEnv::reveal_all(); + if ty.needs_async_drop(self, param_env) { + AsyncDropGlueMorphology::Custom + } else if ty.needs_drop(self, param_env) { + AsyncDropGlueMorphology::DeferredDropInPlace + } else { + AsyncDropGlueMorphology::Noop + } + } + /// Returns the set of types that are required to be alive in /// order to run the destructor of `def` (see RFCs 769 and /// 1238). @@ -1138,6 +1196,18 @@ impl<'tcx> TypeFolder> for WeakAliasTypeExpander<'tcx> { } } +/// Indicates the form of `AsyncDestruct::Destructor`. Used to simplify async +/// drop glue for types not using async drop. +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum AsyncDropGlueMorphology { + /// Async destructor simply does nothing + Noop, + /// Async destructor simply runs `drop_in_place` + DeferredDropInPlace, + /// Async destructor has custom logic + Custom, +} + impl<'tcx> Ty<'tcx> { /// Returns the `Size` for primitive types (bool, uint, int, char, float). pub fn primitive_size(self, tcx: TyCtxt<'tcx>) -> Size { @@ -1303,80 +1373,16 @@ impl<'tcx> Ty<'tcx> { } } - /// Checks whether values of this type `T` implements the `AsyncDrop` - /// trait. - pub fn has_surface_async_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { - self.could_have_surface_async_drop() && tcx.has_surface_async_drop_raw(param_env.and(self)) - } - - /// Fast path helper for testing if a type has `AsyncDrop` - /// implementation. - /// - /// Returning `false` means the type is known to not have `AsyncDrop` - /// implementation. Returning `true` means nothing -- could be - /// `AsyncDrop`, might not be. - fn could_have_surface_async_drop(self) -> bool { - !self.is_async_destructor_trivially_noop() - && !matches!( - self.kind(), - ty::Tuple(_) - | ty::Slice(_) - | ty::Array(_, _) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Coroutine(..) - ) - } - - /// Checks whether values of this type `T` implements the `Drop` - /// trait. - pub fn has_surface_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { - self.could_have_surface_drop() && tcx.has_surface_drop_raw(param_env.and(self)) - } - - /// Fast path helper for testing if a type has `Drop` implementation. - /// - /// Returning `false` means the type is known to not have `Drop` - /// implementation. Returning `true` means nothing -- could be - /// `Drop`, might not be. - fn could_have_surface_drop(self) -> bool { - !self.is_async_destructor_trivially_noop() - && !matches!( - self.kind(), - ty::Tuple(_) - | ty::Slice(_) - | ty::Array(_, _) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Coroutine(..) - ) - } - - /// Checks whether values of this type `T` implement has noop async destructor. + /// Get morphology of the async drop glue, needed for types which do not + /// use async drop. To get async drop glue morphology for a definition see + /// [`TyCtxt::async_drop_glue_morphology`]. Used for `AsyncDestruct::Destructor` + /// type construction. // - // FIXME: implement optimization to make ADTs, which do not need drop, - // to skip fields or to have noop async destructor. - pub fn is_async_destructor_noop( - self, - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> bool { - self.is_async_destructor_trivially_noop() - || if let ty::Adt(adt_def, _) = self.kind() { - (adt_def.is_union() || adt_def.is_payloadfree()) - && !self.has_surface_async_drop(tcx, param_env) - && !self.has_surface_drop(tcx, param_env) - } else { - false - } - } - - /// Fast path helper for testing if a type has noop async destructor. - /// - /// Returning `true` means the type is known to have noop async destructor - /// implementation. Returning `true` means nothing -- could be - /// `Drop`, might not be. - fn is_async_destructor_trivially_noop(self) -> bool { + // FIXME: implement optimization to not instantiate a certain morphology of + // async drop glue too soon to allow per type optimizations, see array case + // for more info. Perhaps then remove this method and use `needs_(async_)drop` + // instead. + pub fn async_drop_glue_morphology(self, tcx: TyCtxt<'tcx>) -> AsyncDropGlueMorphology { match self.kind() { ty::Int(_) | ty::Uint(_) @@ -1388,10 +1394,43 @@ impl<'tcx> Ty<'tcx> { | ty::Ref(..) | ty::RawPtr(..) | ty::FnDef(..) - | ty::FnPtr(_) => true, - ty::Tuple(tys) => tys.is_empty(), - ty::Adt(adt_def, _) => adt_def.is_manually_drop(), - _ => false, + | ty::FnPtr(_) + | ty::Infer(ty::FreshIntTy(_)) + | ty::Infer(ty::FreshFloatTy(_)) => AsyncDropGlueMorphology::Noop, + + ty::Tuple(tys) if tys.is_empty() => AsyncDropGlueMorphology::Noop, + ty::Adt(adt_def, _) if adt_def.is_manually_drop() => AsyncDropGlueMorphology::Noop, + + // Foreign types can never have destructors. + ty::Foreign(_) => AsyncDropGlueMorphology::Noop, + + // FIXME: implement dynamic types async drops + ty::Error(_) | ty::Dynamic(..) => AsyncDropGlueMorphology::DeferredDropInPlace, + + ty::Tuple(_) | ty::Array(_, _) | ty::Slice(_) => { + // Assume worst-case scenario, because we can instantiate async + // destructors in different orders: + // + // 1. Instantiate [T; N] with T = String and N = 0 + // 2. Instantiate <[String; 0] as AsyncDestruct>::Destructor + // + // And viceversa, thus we cannot rely on String not using async + // drop or array having zero (0) elements + AsyncDropGlueMorphology::Custom + } + ty::Pat(ty, _) => ty.async_drop_glue_morphology(tcx), + + ty::Adt(adt_def, _) => tcx.async_drop_glue_morphology(adt_def.did()), + + ty::Closure(did, _) + | ty::CoroutineClosure(did, _) + | ty::Coroutine(did, _) + | ty::CoroutineWitness(did, _) => tcx.async_drop_glue_morphology(*did), + + ty::Alias(..) | ty::Param(_) | ty::Bound(..) | ty::Placeholder(..) | ty::Infer(_) => { + // No specifics, but would usually mean forwarding async drop glue + AsyncDropGlueMorphology::Custom + } } } @@ -1430,6 +1469,46 @@ impl<'tcx> Ty<'tcx> { } } + /// If `ty.needs_async_drop(...)` returns `true`, then `ty` is definitely + /// non-copy and *might* have a async destructor attached; if it returns + /// `false`, then `ty` definitely has no async destructor (i.e., no async + /// drop glue). + /// + /// (Note that this implies that if `ty` has an async destructor attached, + /// then `needs_async_drop` will definitely return `true` for `ty`.) + /// + /// When constructing `AsyncDestruct::Destructor` type, use + /// [`Ty::async_drop_glue_morphology`] instead. + // + // FIXME(zetanumbers): Note that this method is used to check eligible types + // in unions. + #[inline] + pub fn needs_async_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { + // Avoid querying in simple cases. + match needs_drop_components(tcx, self) { + Err(AlwaysRequiresDrop) => true, + Ok(components) => { + let query_ty = match *components { + [] => return false, + // If we've got a single component, call the query with that + // to increase the chance that we hit the query cache. + [component_ty] => component_ty, + _ => self, + }; + + // This doesn't depend on regions, so try to minimize distinct + // query keys used. + // If normalization fails, we just use `query_ty`. + debug_assert!(!param_env.has_infer()); + let query_ty = tcx + .try_normalize_erasing_regions(param_env, query_ty) + .unwrap_or_else(|_| tcx.erase_regions(query_ty)); + + tcx.needs_async_drop_raw(param_env.and(query_ty)) + } + } + } + /// Checks if `ty` has a significant drop. /// /// Note that this method can return false even if `ty` has a destructor @@ -1601,9 +1680,24 @@ impl<'tcx> ExplicitSelf<'tcx> { /// Returns a list of types such that the given type needs drop if and only if /// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if /// this type always needs drop. +// +// FIXME(zetanumbers): consider replacing this with only +// `needs_drop_components_with_async` +#[inline] pub fn needs_drop_components<'tcx>( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, +) -> Result; 2]>, AlwaysRequiresDrop> { + needs_drop_components_with_async(tcx, ty, Asyncness::No) +} + +/// Returns a list of types such that the given type needs drop if and only if +/// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if +/// this type always needs drop. +pub fn needs_drop_components_with_async<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, + asyncness: Asyncness, ) -> Result; 2]>, AlwaysRequiresDrop> { match *ty.kind() { ty::Infer(ty::FreshIntTy(_)) @@ -1623,11 +1717,18 @@ pub fn needs_drop_components<'tcx>( // Foreign types can never have destructors. ty::Foreign(..) => Ok(SmallVec::new()), - ty::Dynamic(..) | ty::Error(_) => Err(AlwaysRequiresDrop), + // FIXME(zetanumbers): Temporary workaround for async drop of dynamic types + ty::Dynamic(..) | ty::Error(_) => { + if asyncness.is_async() { + Ok(SmallVec::new()) + } else { + Err(AlwaysRequiresDrop) + } + } - ty::Pat(ty, _) | ty::Slice(ty) => needs_drop_components(tcx, ty), + ty::Pat(ty, _) | ty::Slice(ty) => needs_drop_components_with_async(tcx, ty, asyncness), ty::Array(elem_ty, size) => { - match needs_drop_components(tcx, elem_ty) { + match needs_drop_components_with_async(tcx, elem_ty, asyncness) { Ok(v) if v.is_empty() => Ok(v), res => match size.try_to_target_usize(tcx) { // Arrays of size zero don't need drop, even if their element @@ -1643,7 +1744,7 @@ pub fn needs_drop_components<'tcx>( } // If any field needs drop, then the whole tuple does. ty::Tuple(fields) => fields.iter().try_fold(SmallVec::new(), move |mut acc, elem| { - acc.extend(needs_drop_components(tcx, elem)?); + acc.extend(needs_drop_components_with_async(tcx, elem, asyncness)?); Ok(acc) }), diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index b8371cc2bca5..dc3c84f9e439 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -3,6 +3,8 @@ use std::fmt; use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar}; use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt}; use rustc_ast::Mutability; +use rustc_data_structures::fx::FxHashSet; +use rustc_hir::def_id::DefId; use rustc_macros::HashStable; #[derive(Clone, Copy, PartialEq, HashStable)] @@ -40,12 +42,69 @@ impl<'tcx> fmt::Debug for VtblEntry<'tcx> { impl<'tcx> TyCtxt<'tcx> { pub const COMMON_VTABLE_ENTRIES: &'tcx [VtblEntry<'tcx>] = &[VtblEntry::MetadataDropInPlace, VtblEntry::MetadataSize, VtblEntry::MetadataAlign]; + + pub fn supertrait_def_ids(self, trait_def_id: DefId) -> SupertraitDefIds<'tcx> { + SupertraitDefIds { + tcx: self, + stack: vec![trait_def_id], + visited: Some(trait_def_id).into_iter().collect(), + } + } } pub const COMMON_VTABLE_ENTRIES_DROPINPLACE: usize = 0; pub const COMMON_VTABLE_ENTRIES_SIZE: usize = 1; pub const COMMON_VTABLE_ENTRIES_ALIGN: usize = 2; +pub struct SupertraitDefIds<'tcx> { + tcx: TyCtxt<'tcx>, + stack: Vec, + visited: FxHashSet, +} + +impl Iterator for SupertraitDefIds<'_> { + type Item = DefId; + + fn next(&mut self) -> Option { + let def_id = self.stack.pop()?; + let predicates = self.tcx.super_predicates_of(def_id); + let visited = &mut self.visited; + self.stack.extend( + predicates + .predicates + .iter() + .filter_map(|(pred, _)| pred.as_trait_clause()) + .map(|trait_ref| trait_ref.def_id()) + .filter(|&super_def_id| visited.insert(super_def_id)), + ); + Some(def_id) + } +} + +// Note that we don't have access to a self type here, this has to be purely based on the trait (and +// supertrait) definitions. That means we can't call into the same vtable_entries code since that +// returns a specific instantiation (e.g., with Vacant slots when bounds aren't satisfied). The goal +// here is to do a best-effort approximation without duplicating a lot of code. +// +// This function is used in layout computation for e.g. &dyn Trait, so it's critical that this +// function is an accurate approximation. We verify this when actually computing the vtable below. +pub(crate) fn vtable_min_entries<'tcx>( + tcx: TyCtxt<'tcx>, + trait_ref: Option>, +) -> usize { + let mut count = TyCtxt::COMMON_VTABLE_ENTRIES.len(); + let Some(trait_ref) = trait_ref else { + return count; + }; + + // This includes self in supertraits. + for def_id in tcx.supertrait_def_ids(trait_ref.def_id()) { + count += tcx.own_existential_vtable_entries(def_id).len(); + } + + count +} + /// Retrieves an allocation that represents the contents of a vtable. /// Since this is a query, allocations are cached and not duplicated. pub(super) fn vtable_allocation_provider<'tcx>( @@ -63,6 +122,9 @@ pub(super) fn vtable_allocation_provider<'tcx>( TyCtxt::COMMON_VTABLE_ENTRIES }; + // This confirms that the layout computation for &dyn Trait has an accurate sizing. + assert!(vtable_entries.len() >= vtable_min_entries(tcx, poly_trait_ref)); + let layout = tcx .layout_of(ty::ParamEnv::reveal_all().and(ty)) .expect("failed to build vtable representation"); diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index a9421aacff83..58f69d772ecb 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -222,24 +222,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => {} - ty::ConstKind::Expr(expr) => match expr { - ty::Expr::UnOp(_, v) => push_inner(stack, v.into()), - ty::Expr::Binop(_, l, r) => { - push_inner(stack, r.into()); - push_inner(stack, l.into()) - } - ty::Expr::FunctionCall(func, args) => { - for a in args.iter().rev() { - push_inner(stack, a.into()); - } - push_inner(stack, func.into()); - } - ty::Expr::Cast(_, c, t) => { - push_inner(stack, t.into()); - push_inner(stack, c.into()); - } - }, - + ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()), ty::ConstKind::Unevaluated(ct) => { stack.extend(ct.args.iter().rev()); } diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 4ba61226a3fd..1ee8777c2741 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -28,6 +28,12 @@ mir_build_borrow_of_moved_value = borrow of moved value .value_borrowed_label = value borrowed here after move .suggestion = borrow this binding in the pattern to avoid moving the value +mir_build_call_to_deprecated_safe_fn_requires_unsafe = + call to deprecated safe function `{$function}` is unsafe and requires unsafe block + .note = consult the function's documentation for information on how to avoid undefined behavior + .label = call to unsafe function + .suggestion = you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code + mir_build_call_to_fn_with_requires_unsafe = call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block .help = in order for the call to be safe, the context requires the following additional target {$missing_target_features_count -> @@ -97,7 +103,7 @@ mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = .note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior .label = dereference of raw pointer -mir_build_exceeds_mcdc_condition_num_limit = Conditions number of the decision ({$conditions_num}) exceeds limit ({$max_conditions_num}). MCDC analysis will not count this expression. +mir_build_exceeds_mcdc_condition_limit = Number of conditions in decision ({$num_conditions}) exceeds limit ({$max_conditions}). MC/DC analysis will not count this expression. mir_build_extern_static_requires_unsafe = use of extern static is unsafe and requires unsafe block diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs index 728b63d5b21b..f97e9ef60a29 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs @@ -10,12 +10,12 @@ use rustc_middle::ty::TyCtxt; use rustc_span::Span; use crate::build::Builder; -use crate::errors::MCDCExceedsConditionNumLimit; +use crate::errors::MCDCExceedsConditionLimit; /// The MCDC bitmap scales exponentially (2^n) based on the number of conditions seen, /// So llvm sets a maximum value prevents the bitmap footprint from growing too large without the user's knowledge. /// This limit may be relaxed if the [upstream change](https://github.com/llvm/llvm-project/pull/82448) is merged. -const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6; +const MAX_CONDITIONS_IN_DECISION: usize = 6; #[derive(Default)] struct MCDCDecisionCtx { @@ -100,7 +100,7 @@ impl MCDCState { } None => decision_ctx.processing_decision.insert(MCDCDecisionSpan { span, - conditions_num: 0, + num_conditions: 0, end_markers: vec![], decision_depth, }), @@ -108,14 +108,14 @@ impl MCDCState { let parent_condition = decision_ctx.decision_stack.pop_back().unwrap_or_default(); let lhs_id = if parent_condition.condition_id == ConditionId::NONE { - decision.conditions_num += 1; - ConditionId::from(decision.conditions_num) + decision.num_conditions += 1; + ConditionId::from(decision.num_conditions) } else { parent_condition.condition_id }; - decision.conditions_num += 1; - let rhs_condition_id = ConditionId::from(decision.conditions_num); + decision.num_conditions += 1; + let rhs_condition_id = ConditionId::from(decision.num_conditions); let (lhs, rhs) = match op { LogicalOp::And => { @@ -179,18 +179,18 @@ impl MCDCState { } } -pub struct MCDCInfoBuilder { +pub(crate) struct MCDCInfoBuilder { branch_spans: Vec, decision_spans: Vec, state: MCDCState, } impl MCDCInfoBuilder { - pub fn new() -> Self { + pub(crate) fn new() -> Self { Self { branch_spans: vec![], decision_spans: vec![], state: MCDCState::new() } } - pub fn visit_evaluated_condition( + pub(crate) fn visit_evaluated_condition( &mut self, tcx: TyCtxt<'_>, source_info: SourceInfo, @@ -208,17 +208,17 @@ impl MCDCInfoBuilder { // is empty, i.e. when all the conditions of the decision were instrumented, // and the decision is "complete". if let Some(decision) = decision_result { - match decision.conditions_num { + match decision.num_conditions { 0 => { unreachable!("Decision with no condition is not expected"); } - 1..=MAX_CONDITIONS_NUM_IN_DECISION => { + 1..=MAX_CONDITIONS_IN_DECISION => { self.decision_spans.push(decision); } _ => { // Do not generate mcdc mappings and statements for decisions with too many conditions. // Therefore, first erase the condition info of the (N-1) previous branch spans. - let rebase_idx = self.branch_spans.len() - (decision.conditions_num - 1); + let rebase_idx = self.branch_spans.len() - (decision.num_conditions - 1); for branch in &mut self.branch_spans[rebase_idx..] { branch.condition_info = None; } @@ -226,10 +226,10 @@ impl MCDCInfoBuilder { // Then, erase this last branch span's info too, for a total of N. condition_info = None; - tcx.dcx().emit_warn(MCDCExceedsConditionNumLimit { + tcx.dcx().emit_warn(MCDCExceedsConditionLimit { span: decision.span, - conditions_num: decision.conditions_num, - max_conditions_num: MAX_CONDITIONS_NUM_IN_DECISION, + num_conditions: decision.num_conditions, + max_conditions: MAX_CONDITIONS_IN_DECISION, }); } } @@ -243,7 +243,7 @@ impl MCDCInfoBuilder { }); } - pub fn into_done(self) -> (Vec, Vec) { + pub(crate) fn into_done(self) -> (Vec, Vec) { (self.decision_spans, self.branch_spans) } } diff --git a/compiler/rustc_mir_build/src/build/custom/parse.rs b/compiler/rustc_mir_build/src/build/custom/parse.rs index 8bcd429b67eb..9607022c6df0 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse.rs @@ -91,7 +91,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { } } - pub fn parse_args(&mut self, params: &IndexSlice>) -> PResult<()> { + pub(crate) fn parse_args(&mut self, params: &IndexSlice>) -> PResult<()> { for param in params.iter() { let (var, span) = { let pat = param.pat.as_ref().unwrap(); @@ -149,7 +149,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { /// /// This allows us to easily parse the basic blocks declarations, local declarations, and /// basic block definitions in order. - pub fn parse_body(&mut self, expr_id: ExprId) -> PResult<()> { + pub(crate) fn parse_body(&mut self, expr_id: ExprId) -> PResult<()> { let body = parse_by_kind!(self, expr_id, _, "whole body", ExprKind::Block { block } => self.thir[*block].expr.unwrap(), ); diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index de748b9c85d1..b1a305efa4c6 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -12,7 +12,7 @@ use crate::build::expr::as_constant::as_constant_inner; use super::{parse_by_kind, PResult, ParseCtxt}; impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { - pub fn parse_statement(&self, expr_id: ExprId) -> PResult> { + pub(crate) fn parse_statement(&self, expr_id: ExprId) -> PResult> { parse_by_kind!(self, expr_id, _, "statement", @call(mir_storage_live, args) => { Ok(StatementKind::StorageLive(self.parse_local(args[0])?)) @@ -46,7 +46,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { ) } - pub fn parse_terminator(&self, expr_id: ExprId) -> PResult> { + pub(crate) fn parse_terminator(&self, expr_id: ExprId) -> PResult> { parse_by_kind!(self, expr_id, expr, "terminator", @call(mir_return, _args) => { Ok(TerminatorKind::Return) @@ -261,7 +261,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { ) } - pub fn parse_operand(&self, expr_id: ExprId) -> PResult> { + pub(crate) fn parse_operand(&self, expr_id: ExprId) -> PResult> { parse_by_kind!(self, expr_id, expr, "operand", @call(mir_move, args) => self.parse_place(args[0]).map(Operand::Move), @call(mir_static, args) => self.parse_static(args[0]), diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index b4dd423f344a..f7229326c541 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -39,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } -pub fn as_constant_inner<'tcx>( +pub(crate) fn as_constant_inner<'tcx>( expr: &Expr<'tcx>, push_cuta: impl FnMut(&Box>) -> Option, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_mir_build/src/build/expr/mod.rs b/compiler/rustc_mir_build/src/build/expr/mod.rs index dfe85b858cd0..3de43a3370f3 100644 --- a/compiler/rustc_mir_build/src/build/expr/mod.rs +++ b/compiler/rustc_mir_build/src/build/expr/mod.rs @@ -62,9 +62,9 @@ pub(crate) mod as_constant; mod as_operand; -pub mod as_place; +pub(crate) mod as_place; mod as_rvalue; mod as_temp; -pub mod category; +pub(crate) mod category; mod into; mod stmt; diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 770f689724af..50f4ca2d819d 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -456,7 +456,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { } #[must_use] -pub fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind { +pub(crate) fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind { match ref_mutability { Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default }, Mutability::Not => BorrowKind::Shared, diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 13112f2b12c8..14d1b502474f 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -452,7 +452,7 @@ fn construct_fn<'tcx>( assert_eq!(expr.as_usize(), thir.exprs.len() - 1); // Figure out what primary body this item has. - let body_id = tcx.hir().body_owned_by(fn_def); + let body = tcx.hir().body_owned_by(fn_def); let span_with_body = tcx.hir().span_with_body(fn_id); let return_ty_span = tcx .hir() @@ -512,9 +512,9 @@ fn construct_fn<'tcx>( ); let call_site_scope = - region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::CallSite }; + region::Scope { id: body.id().hir_id.local_id, data: region::ScopeData::CallSite }; let arg_scope = - region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::Arguments }; + region::Scope { id: body.id().hir_id.local_id, data: region::ScopeData::Arguments }; let source_info = builder.source_info(span); let call_site_s = (call_site_scope, source_info); unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| { diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index c7850c7aea87..5b6de39bb2e7 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -97,7 +97,7 @@ use rustc_span::{Span, DUMMY_SP}; use tracing::{debug, instrument}; #[derive(Debug)] -pub struct Scopes<'tcx> { +pub(crate) struct Scopes<'tcx> { scopes: Vec, /// The current set of breakable scopes. See module comment for more details. diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index b5f7ffbd2afb..659ae1724603 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -9,7 +9,7 @@ use rustc_middle::thir::visit::Visitor; use rustc_middle::thir::*; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; -use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; +use rustc_session::lint::builtin::{DEPRECATED_SAFE, UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; use rustc_session::lint::Level; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::symbol::Symbol; @@ -110,14 +110,34 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { ); self.suggest_unsafe_block = false; } - SafetyContext::Safe => { - kind.emit_requires_unsafe_err( + SafetyContext::Safe => match kind { + // Allow calls to deprecated-safe unsafe functions if the + // caller is from an edition before 2024. + UnsafeOpKind::CallToUnsafeFunction(Some(id)) + if !span.at_least_rust_2024() + && self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) => + { + self.tcx.emit_node_span_lint( + DEPRECATED_SAFE, + self.hir_context, + span, + CallToDeprecatedSafeFnRequiresUnsafe { + span, + function: with_no_trimmed_paths!(self.tcx.def_path_str(id)), + sub: CallToDeprecatedSafeFnRequiresUnsafeSub { + left: span.shrink_to_lo(), + right: span.shrink_to_hi(), + }, + }, + ) + } + _ => kind.emit_requires_unsafe_err( self.tcx, span, self.hir_context, unsafe_op_in_unsafe_fn_allowed, - ); - } + ), + }, } } @@ -577,7 +597,7 @@ enum UnsafeOpKind { use UnsafeOpKind::*; impl UnsafeOpKind { - pub fn emit_unsafe_op_in_unsafe_fn_lint( + fn emit_unsafe_op_in_unsafe_fn_lint( &self, tcx: TyCtxt<'_>, hir_id: HirId, @@ -717,7 +737,7 @@ impl UnsafeOpKind { } } - pub fn emit_requires_unsafe_err( + fn emit_requires_unsafe_err( &self, tcx: TyCtxt<'_>, span: Span, diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index ae6e126a4e2c..cf324c03dc9f 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -13,92 +13,111 @@ use rustc_span::Span; #[derive(LintDiagnostic)] #[diag(mir_build_unconditional_recursion)] #[help] -pub struct UnconditionalRecursion { +pub(crate) struct UnconditionalRecursion { #[label] - pub span: Span, + pub(crate) span: Span, #[label(mir_build_unconditional_recursion_call_site_label)] - pub call_sites: Vec, + pub(crate) call_sites: Vec, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build_call_to_deprecated_safe_fn_requires_unsafe)] +pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe { + #[label] + pub(crate) span: Span, + pub(crate) function: String, + #[subdiagnostic] + pub(crate) sub: CallToDeprecatedSafeFnRequiresUnsafeSub, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")] +pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub { + #[suggestion_part(code = "unsafe {{ ")] + pub(crate) left: Span, + #[suggestion_part(code = " }}")] + pub(crate) right: Span, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { #[label] - pub span: Span, - pub function: String, + pub(crate) span: Span, + pub(crate) function: String, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { +pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] @@ -107,11 +126,11 @@ pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { code = E0133 )] #[note] -pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] @@ -119,63 +138,63 @@ pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe, code = E0133, )] -pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe, code = E0133)] #[help] -pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { #[label] - pub span: Span, - pub function: String, - pub missing_target_features: DiagArgValue, - pub missing_target_features_count: usize, + pub(crate) span: Span, + pub(crate) function: String, + pub(crate) missing_target_features: DiagArgValue, + pub(crate) missing_target_features_count: usize, #[note] - pub note: Option<()>, - pub build_target_features: DiagArgValue, - pub build_target_features_count: usize, + pub(crate) note: Option<()>, + pub(crate) build_target_features: DiagArgValue, + pub(crate) build_target_features_count: usize, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = E0133)] #[note] -pub struct CallToUnsafeFunctionRequiresUnsafe { +pub(crate) struct CallToUnsafeFunctionRequiresUnsafe { #[primary_span] #[label] - pub span: Span, - pub function: String, + pub(crate) span: Span, + pub(crate) function: String, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)] #[note] -pub struct CallToUnsafeFunctionRequiresUnsafeNameless { +pub(crate) struct CallToUnsafeFunctionRequiresUnsafeNameless { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, - pub function: String, + pub(crate) span: Span, + pub(crate) function: String, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] @@ -184,45 +203,45 @@ pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { code = E0133 )] #[note] -pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { +pub(crate) struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_inline_assembly_requires_unsafe, code = E0133)] #[note] -pub struct UseOfInlineAssemblyRequiresUnsafe { +pub(crate) struct UseOfInlineAssemblyRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_initializing_type_with_requires_unsafe, code = E0133)] #[note] -pub struct InitializingTypeWithRequiresUnsafe { +pub(crate) struct InitializingTypeWithRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] @@ -231,111 +250,111 @@ pub struct InitializingTypeWithRequiresUnsafe { code = E0133 )] #[note] -pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_mutable_static_requires_unsafe, code = E0133)] #[note] -pub struct UseOfMutableStaticRequiresUnsafe { +pub(crate) struct UseOfMutableStaticRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_extern_static_requires_unsafe, code = E0133)] #[note] -pub struct UseOfExternStaticRequiresUnsafe { +pub(crate) struct UseOfExternStaticRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_deref_raw_pointer_requires_unsafe, code = E0133)] #[note] -pub struct DerefOfRawPointerRequiresUnsafe { +pub(crate) struct DerefOfRawPointerRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_union_field_requires_unsafe, code = E0133)] #[note] -pub struct AccessToUnionFieldRequiresUnsafe { +pub(crate) struct AccessToUnionFieldRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = E0133)] #[note] -pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe { +pub(crate) struct MutationOfLayoutConstrainedFieldRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] @@ -344,23 +363,23 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe { code = E0133 )] #[note] -pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = E0133)] #[note] -pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { +pub(crate) struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] @@ -369,60 +388,60 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { code = E0133 )] #[note] -pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_call_to_fn_with_requires_unsafe, code = E0133)] #[help] -pub struct CallToFunctionWithRequiresUnsafe { +pub(crate) struct CallToFunctionWithRequiresUnsafe { #[primary_span] #[label] - pub span: Span, - pub function: String, - pub missing_target_features: DiagArgValue, - pub missing_target_features_count: usize, + pub(crate) span: Span, + pub(crate) function: String, + pub(crate) missing_target_features: DiagArgValue, + pub(crate) missing_target_features_count: usize, #[note] - pub note: Option<()>, - pub build_target_features: DiagArgValue, - pub build_target_features_count: usize, + pub(crate) note: Option<()>, + pub(crate) build_target_features: DiagArgValue, + pub(crate) build_target_features_count: usize, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[help] -pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, - pub function: String, - pub missing_target_features: DiagArgValue, - pub missing_target_features_count: usize, + pub(crate) span: Span, + pub(crate) function: String, + pub(crate) missing_target_features: DiagArgValue, + pub(crate) missing_target_features_count: usize, #[note] - pub note: Option<()>, - pub build_target_features: DiagArgValue, - pub build_target_features_count: usize, + pub(crate) note: Option<()>, + pub(crate) build_target_features: DiagArgValue, + pub(crate) build_target_features_count: usize, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Subdiagnostic)] #[label(mir_build_unsafe_not_inherited)] -pub struct UnsafeNotInheritedNote { +pub(crate) struct UnsafeNotInheritedNote { #[primary_span] - pub span: Span, + pub(crate) span: Span, } -pub struct UnsafeNotInheritedLintNote { - pub signature_span: Span, - pub body_span: Span, +pub(crate) struct UnsafeNotInheritedLintNote { + pub(crate) signature_span: Span, + pub(crate) body_span: Span, } impl Subdiagnostic for UnsafeNotInheritedLintNote { @@ -444,15 +463,15 @@ impl Subdiagnostic for UnsafeNotInheritedLintNote { #[derive(LintDiagnostic)] #[diag(mir_build_unused_unsafe)] -pub struct UnusedUnsafe { +pub(crate) struct UnusedUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub enclosing: Option, + pub(crate) enclosing: Option, } #[derive(Subdiagnostic)] -pub enum UnusedUnsafeEnclosing { +pub(crate) enum UnusedUnsafeEnclosing { #[label(mir_build_unused_unsafe_enclosing_block_label)] Block { #[primary_span] @@ -461,10 +480,10 @@ pub enum UnusedUnsafeEnclosing { } pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> { - pub cx: &'m RustcPatCtxt<'p, 'tcx>, - pub scrut_span: Span, - pub braces_span: Option, - pub ty: Ty<'tcx>, + pub(crate) cx: &'m RustcPatCtxt<'p, 'tcx>, + pub(crate) scrut_span: Span, + pub(crate) braces_span: Option, + pub(crate) ty: Ty<'tcx>, } impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { @@ -533,197 +552,197 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo #[derive(Subdiagnostic)] #[note(mir_build_non_exhaustive_match_all_arms_guarded)] -pub struct NonExhaustiveMatchAllArmsGuarded; +pub(crate) struct NonExhaustiveMatchAllArmsGuarded; #[derive(Diagnostic)] #[diag(mir_build_static_in_pattern, code = E0158)] -pub struct StaticInPattern { +pub(crate) struct StaticInPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_assoc_const_in_pattern, code = E0158)] -pub struct AssocConstInPattern { +pub(crate) struct AssocConstInPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_const_param_in_pattern, code = E0158)] -pub struct ConstParamInPattern { +pub(crate) struct ConstParamInPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_non_const_path, code = E0080)] -pub struct NonConstPath { +pub(crate) struct NonConstPath { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(LintDiagnostic)] #[diag(mir_build_unreachable_pattern)] -pub struct UnreachablePattern { +pub(crate) struct UnreachablePattern { #[label] - pub span: Option, + pub(crate) span: Option, #[label(mir_build_catchall_label)] - pub catchall: Option, + pub(crate) catchall: Option, } #[derive(Diagnostic)] #[diag(mir_build_const_pattern_depends_on_generic_parameter)] -pub struct ConstPatternDependsOnGenericParameter { +pub(crate) struct ConstPatternDependsOnGenericParameter { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_could_not_eval_const_pattern)] -pub struct CouldNotEvalConstPattern { +pub(crate) struct CouldNotEvalConstPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = E0030)] -pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper { +pub(crate) struct LowerRangeBoundMustBeLessThanOrEqualToUpper { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[note(mir_build_teach_note)] - pub teach: Option<()>, + pub(crate) teach: Option<()>, } #[derive(Diagnostic)] #[diag(mir_build_literal_in_range_out_of_bounds)] -pub struct LiteralOutOfRange<'tcx> { +pub(crate) struct LiteralOutOfRange<'tcx> { #[primary_span] #[label] - pub span: Span, - pub ty: Ty<'tcx>, - pub min: i128, - pub max: u128, + pub(crate) span: Span, + pub(crate) ty: Ty<'tcx>, + pub(crate) min: i128, + pub(crate) max: u128, } #[derive(Diagnostic)] #[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = E0579)] -pub struct LowerRangeBoundMustBeLessThanUpper { +pub(crate) struct LowerRangeBoundMustBeLessThanUpper { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(LintDiagnostic)] #[diag(mir_build_leading_irrefutable_let_patterns)] #[note] #[help] -pub struct LeadingIrrefutableLetPatterns { - pub count: usize, +pub(crate) struct LeadingIrrefutableLetPatterns { + pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_trailing_irrefutable_let_patterns)] #[note] #[help] -pub struct TrailingIrrefutableLetPatterns { - pub count: usize, +pub(crate) struct TrailingIrrefutableLetPatterns { + pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_bindings_with_variant_name, code = E0170)] -pub struct BindingsWithVariantName { +pub(crate) struct BindingsWithVariantName { #[suggestion(code = "{ty_path}::{name}", applicability = "machine-applicable")] - pub suggestion: Option, - pub ty_path: String, - pub name: Symbol, + pub(crate) suggestion: Option, + pub(crate) ty_path: String, + pub(crate) name: Symbol, } #[derive(LintDiagnostic)] #[diag(mir_build_irrefutable_let_patterns_if_let)] #[note] #[help] -pub struct IrrefutableLetPatternsIfLet { - pub count: usize, +pub(crate) struct IrrefutableLetPatternsIfLet { + pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_irrefutable_let_patterns_if_let_guard)] #[note] #[help] -pub struct IrrefutableLetPatternsIfLetGuard { - pub count: usize, +pub(crate) struct IrrefutableLetPatternsIfLetGuard { + pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_irrefutable_let_patterns_let_else)] #[note] #[help] -pub struct IrrefutableLetPatternsLetElse { - pub count: usize, +pub(crate) struct IrrefutableLetPatternsLetElse { + pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_irrefutable_let_patterns_while_let)] #[note] #[help] -pub struct IrrefutableLetPatternsWhileLet { - pub count: usize, +pub(crate) struct IrrefutableLetPatternsWhileLet { + pub(crate) count: usize, } #[derive(Diagnostic)] #[diag(mir_build_borrow_of_moved_value)] -pub struct BorrowOfMovedValue<'tcx> { +pub(crate) struct BorrowOfMovedValue<'tcx> { #[primary_span] #[label] #[label(mir_build_occurs_because_label)] - pub binding_span: Span, + pub(crate) binding_span: Span, #[label(mir_build_value_borrowed_label)] - pub conflicts_ref: Vec, - pub name: Symbol, - pub ty: Ty<'tcx>, + pub(crate) conflicts_ref: Vec, + pub(crate) name: Symbol, + pub(crate) ty: Ty<'tcx>, #[suggestion(code = "ref ", applicability = "machine-applicable")] - pub suggest_borrowing: Option, + pub(crate) suggest_borrowing: Option, } #[derive(Diagnostic)] #[diag(mir_build_multiple_mut_borrows)] -pub struct MultipleMutBorrows { +pub(crate) struct MultipleMutBorrows { #[primary_span] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub occurrences: Vec, + pub(crate) occurrences: Vec, } #[derive(Diagnostic)] #[diag(mir_build_already_borrowed)] -pub struct AlreadyBorrowed { +pub(crate) struct AlreadyBorrowed { #[primary_span] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub occurrences: Vec, + pub(crate) occurrences: Vec, } #[derive(Diagnostic)] #[diag(mir_build_already_mut_borrowed)] -pub struct AlreadyMutBorrowed { +pub(crate) struct AlreadyMutBorrowed { #[primary_span] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub occurrences: Vec, + pub(crate) occurrences: Vec, } #[derive(Diagnostic)] #[diag(mir_build_moved_while_borrowed)] -pub struct MovedWhileBorrowed { +pub(crate) struct MovedWhileBorrowed { #[primary_span] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub occurrences: Vec, + pub(crate) occurrences: Vec, } #[derive(Subdiagnostic)] -pub enum Conflict { +pub(crate) enum Conflict { #[label(mir_build_mutable_borrow)] Mut { #[primary_span] @@ -746,118 +765,118 @@ pub enum Conflict { #[derive(Diagnostic)] #[diag(mir_build_union_pattern)] -pub struct UnionPattern { +pub(crate) struct UnionPattern { #[primary_span] - pub span: Span, + 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 struct TypeNotStructural<'tcx> { +pub(crate) struct TypeNotStructural<'tcx> { #[primary_span] - pub span: Span, - pub non_sm_ty: Ty<'tcx>, + pub(crate) span: Span, + pub(crate) non_sm_ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_non_partial_eq_match)] -pub struct TypeNotPartialEq<'tcx> { +pub(crate) struct TypeNotPartialEq<'tcx> { #[primary_span] - pub span: Span, - pub non_peq_ty: Ty<'tcx>, + pub(crate) span: Span, + pub(crate) non_peq_ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_invalid_pattern)] -pub struct InvalidPattern<'tcx> { +pub(crate) struct InvalidPattern<'tcx> { #[primary_span] - pub span: Span, - pub non_sm_ty: Ty<'tcx>, + pub(crate) span: Span, + pub(crate) non_sm_ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_unsized_pattern)] -pub struct UnsizedPattern<'tcx> { +pub(crate) struct UnsizedPattern<'tcx> { #[primary_span] - pub span: Span, - pub non_sm_ty: Ty<'tcx>, + pub(crate) span: Span, + pub(crate) non_sm_ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_nan_pattern)] #[note] #[help] -pub struct NaNPattern { +pub(crate) struct NaNPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_pointer_pattern)] -pub struct PointerPattern { +pub(crate) struct PointerPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_non_empty_never_pattern)] #[note] -pub struct NonEmptyNeverPattern<'tcx> { +pub(crate) struct NonEmptyNeverPattern<'tcx> { #[primary_span] #[label] - pub span: Span, - pub ty: Ty<'tcx>, + pub(crate) span: Span, + pub(crate) ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(mir_build_exceeds_mcdc_condition_num_limit)] -pub(crate) struct MCDCExceedsConditionNumLimit { +#[diag(mir_build_exceeds_mcdc_condition_limit)] +pub(crate) struct MCDCExceedsConditionLimit { #[primary_span] - pub span: Span, - pub conditions_num: usize, - pub max_conditions_num: usize, + pub(crate) span: Span, + pub(crate) num_conditions: usize, + pub(crate) max_conditions: usize, } #[derive(Diagnostic)] #[diag(mir_build_pattern_not_covered, code = E0005)] pub(crate) struct PatternNotCovered<'s, 'tcx> { #[primary_span] - pub span: Span, - pub origin: &'s str, + pub(crate) span: Span, + pub(crate) origin: &'s str, #[subdiagnostic] - pub uncovered: Uncovered<'tcx>, + pub(crate) uncovered: Uncovered<'tcx>, #[subdiagnostic] - pub inform: Option, + pub(crate) inform: Option, #[subdiagnostic] - pub interpreted_as_const: Option, + pub(crate) interpreted_as_const: Option, #[subdiagnostic] - pub adt_defined_here: Option>, + pub(crate) adt_defined_here: Option>, #[note(mir_build_privately_uninhabited)] - pub witness_1_is_privately_uninhabited: Option<()>, + pub(crate) witness_1_is_privately_uninhabited: Option<()>, #[note(mir_build_pattern_ty)] - pub _p: (), - pub pattern_ty: Ty<'tcx>, + pub(crate) _p: (), + pub(crate) pattern_ty: Ty<'tcx>, #[subdiagnostic] - pub let_suggestion: Option, + pub(crate) let_suggestion: Option, #[subdiagnostic] - pub misc_suggestion: Option, + pub(crate) misc_suggestion: Option, } #[derive(Subdiagnostic)] #[note(mir_build_inform_irrefutable)] #[note(mir_build_more_information)] -pub struct Inform; +pub(crate) struct Inform; -pub struct AdtDefinedHere<'tcx> { - pub adt_def_span: Span, - pub ty: Ty<'tcx>, - pub variants: Vec, +pub(crate) struct AdtDefinedHere<'tcx> { + pub(crate) adt_def_span: Span, + pub(crate) ty: Ty<'tcx>, + pub(crate) variants: Vec, } -pub struct Variant { - pub span: Span, +pub(crate) struct Variant { + pub(crate) span: Span, } impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> { @@ -884,14 +903,14 @@ impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> { applicability = "maybe-incorrect" )] #[label(mir_build_confused)] -pub struct InterpretedAsConst { +pub(crate) struct InterpretedAsConst { #[primary_span] - pub span: Span, - pub variable: String, + pub(crate) span: Span, + pub(crate) variable: String, } #[derive(Subdiagnostic)] -pub enum SuggestLet { +pub(crate) enum SuggestLet { #[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")] If { #[suggestion_part(code = "if ")] @@ -913,7 +932,7 @@ pub enum SuggestLet { } #[derive(Subdiagnostic)] -pub enum MiscPatternSuggestion { +pub(crate) enum MiscPatternSuggestion { #[suggestion( mir_build_suggest_attempted_int_lit, code = "_", @@ -927,15 +946,15 @@ pub enum MiscPatternSuggestion { #[derive(Diagnostic)] #[diag(mir_build_rustc_box_attribute_error)] -pub struct RustcBoxAttributeError { +pub(crate) struct RustcBoxAttributeError { #[primary_span] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub reason: RustcBoxAttrReason, + pub(crate) reason: RustcBoxAttrReason, } #[derive(Subdiagnostic)] -pub enum RustcBoxAttrReason { +pub(crate) enum RustcBoxAttrReason { #[note(mir_build_attributes)] Attributes, #[note(mir_build_not_box)] @@ -946,13 +965,13 @@ pub enum RustcBoxAttrReason { #[derive(LintDiagnostic)] #[diag(mir_build_rust_2024_incompatible_pat)] -pub struct Rust2024IncompatiblePat { +pub(crate) struct Rust2024IncompatiblePat { #[subdiagnostic] - pub sugg: Rust2024IncompatiblePatSugg, + pub(crate) sugg: Rust2024IncompatiblePatSugg, } -pub struct Rust2024IncompatiblePatSugg { - pub suggestion: Vec<(Span, String)>, +pub(crate) struct Rust2024IncompatiblePatSugg { + pub(crate) suggestion: Vec<(Span, String)>, } impl Subdiagnostic for Rust2024IncompatiblePatSugg { diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 74600c6b12eb..a1b8b5783491 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -1,6 +1,4 @@ //! Construction of MIR from HIR. -//! -//! This crate also contains the match exhaustiveness and usefulness checking. #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index bd72ef28cb37..bd9e34ae80fc 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -13,10 +13,10 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::HirId; use rustc_hir::Node; +use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::thir::*; use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; -use rustc_middle::{bug, span_bug}; use tracing::instrument; pub(crate) fn thir_body( @@ -24,22 +24,7 @@ pub(crate) fn thir_body( owner_def: LocalDefId, ) -> Result<(&Steal>, ExprId), ErrorGuaranteed> { let hir = tcx.hir(); - let body; - let body = match tcx.def_kind(owner_def) { - // Inline consts do not have bodies of their own, so create one to make the follow-up logic simpler. - DefKind::InlineConst => { - let e = hir.expect_expr(tcx.local_def_id_to_hir_id(owner_def)); - body = hir::Body { - params: &[], - value: match e.kind { - hir::ExprKind::ConstBlock(body) => body, - _ => span_bug!(e.span, "InlineConst was not a ConstBlock: {e:#?}"), - }, - }; - &body - } - _ => hir.body(hir.body_owned_by(owner_def)), - }; + let body = hir.body_owned_by(owner_def); let mut cx = Cx::new(tcx, owner_def); if let Some(reported) = cx.typeck_results.tainted_by_errors { return Err(reported); @@ -49,7 +34,7 @@ pub(crate) fn thir_body( let owner_id = tcx.local_def_id_to_hir_id(owner_def); if let Some(fn_decl) = hir.fn_decl_by_hir_id(owner_id) { let closure_env_param = cx.closure_env_param(owner_def, owner_id); - let explicit_params = cx.explicit_params(owner_id, fn_decl, body); + let explicit_params = cx.explicit_params(owner_id, fn_decl, &body); cx.thir.params = closure_env_param.into_iter().chain(explicit_params).collect(); // The resume argument may be missing, in that case we need to provide it here. diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index a3e6e5a5a915..84512e81637e 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -69,7 +69,7 @@ use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::CoroutineArgs; use rustc_middle::ty::InstanceDef; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, CoroutineArgsExt, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::impls::{ MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, @@ -1608,7 +1608,7 @@ fn check_field_tys_sized<'tcx>( let infcx = tcx.infer_ctxt().ignoring_regions().build(); let param_env = tcx.param_env(def_id); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); for field_ty in &coroutine_layout.field_tys { ocx.register_bound( ObligationCause::new( diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index 61aabea1d8b3..0e209757100c 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -48,7 +48,7 @@ pub(super) struct MCDCDecision { pub(super) span: Span, pub(super) end_bcbs: BTreeSet, pub(super) bitmap_idx: u32, - pub(super) conditions_num: u16, + pub(super) num_conditions: u16, pub(super) decision_depth: u16, } @@ -268,13 +268,13 @@ pub(super) fn extract_mcdc_mappings( // the bitmap, rounded up to a whole number of bytes. // The decision's "bitmap index" points to its first byte in the bitmap. let bitmap_idx = *mcdc_bitmap_bytes; - *mcdc_bitmap_bytes += (1_u32 << decision.conditions_num).div_ceil(8); + *mcdc_bitmap_bytes += (1_u32 << decision.num_conditions).div_ceil(8); Some(MCDCDecision { span, end_bcbs, bitmap_idx, - conditions_num: decision.conditions_num as u16, + num_conditions: decision.num_conditions as u16, decision_depth: decision.decision_depth, }) }, diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 28e0c633d5aa..419e39bc3867 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -195,9 +195,9 @@ fn create_mappings<'tcx>( )); mappings.extend(mcdc_decisions.iter().filter_map( - |&mappings::MCDCDecision { span, bitmap_idx, conditions_num, .. }| { + |&mappings::MCDCDecision { span, bitmap_idx, num_conditions, .. }| { let code_region = region_for_span(span)?; - let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num }); + let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, num_conditions }); Some(Mapping { kind, code_region }) }, )); @@ -269,7 +269,7 @@ fn inject_mcdc_statements<'tcx>( span: _, ref end_bcbs, bitmap_idx, - conditions_num: _, + num_conditions: _, decision_depth, } in &extracted_mappings.mcdc_decisions { diff --git a/compiler/rustc_mir_transform/src/dump_mir.rs b/compiler/rustc_mir_transform/src/dump_mir.rs index 13841be494cf..3b71cf02c1a0 100644 --- a/compiler/rustc_mir_transform/src/dump_mir.rs +++ b/compiler/rustc_mir_transform/src/dump_mir.rs @@ -28,6 +28,9 @@ pub fn emit_mir(tcx: TyCtxt<'_>) -> io::Result<()> { OutFileName::Real(path) => { let mut f = io::BufWriter::new(File::create(&path)?); write_mir_pretty(tcx, None, &mut f)?; + if tcx.sess.opts.json_artifact_notifications { + tcx.dcx().emit_artifact_notification(&path, "mir"); + } } } Ok(()) diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 03d952abad11..665b2260294a 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -34,14 +34,14 @@ use std::fmt; /// /// ```text // fn drop_term(t: &mut T) { -// mir!( +// mir! { // { // Drop(*t, exit) // } // exit = { // Return() // } -// ) +// } // } /// ``` pub struct ElaborateDrops; diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index a54332b6f257..40db3e38fd32 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -123,7 +123,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { /// Transform `&(*a)` ==> `a`. fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { - if let Rvalue::Ref(_, _, place) = rvalue { + if let Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) = rvalue { if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() { if rvalue.ty(self.local_decls, self.tcx) != base.ty(self.local_decls, self.tcx).ty { return; diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 9ba22870403f..8b46658b3225 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -102,8 +102,12 @@ impl<'tcx> Value<'tcx> { } (PlaceElem::Index(idx), Value::Aggregate { fields, .. }) => { let idx = prop.get_const(idx.into())?.immediate()?; - let idx = prop.ecx.read_target_usize(idx).ok()?; - fields.get(FieldIdx::from_u32(idx.try_into().ok()?)).unwrap_or(&Value::Uninit) + let idx = prop.ecx.read_target_usize(idx).ok()?.try_into().ok()?; + if idx <= FieldIdx::MAX_AS_U32 { + fields.get(FieldIdx::from_u32(idx)).unwrap_or(&Value::Uninit) + } else { + return None; + } } ( PlaceElem::ConstantIndex { offset, min_length: _, from_end: false }, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 93ae105150cc..a8741254ffbf 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -226,7 +226,8 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { // typeck instead of during ast lowering, like all other bodies so far. for def_id in tcx.hir().body_owners() { // Incremental performance optimization: only load typeck results for things that actually have inline consts - if tcx.hir_owner_nodes(tcx.hir().body_owned_by(def_id).hir_id.owner).has_inline_consts { + if tcx.hir_owner_nodes(tcx.hir().body_owned_by(def_id).id().hir_id.owner).has_inline_consts + { set.extend(tcx.typeck(def_id).inline_consts.values()) } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index dcf54ad2cfc8..d03c2d18c0c3 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -4,7 +4,7 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::GenericArgs; -use rustc_middle::ty::{self, CoroutineArgs, EarlyBinder, Ty, TyCtxt}; +use rustc_middle::ty::{self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; @@ -634,7 +634,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { dest: Place<'tcx>, src: Place<'tcx>, coroutine_def_id: DefId, - args: CoroutineArgs<'tcx>, + args: CoroutineArgs>, ) { self.block(vec![], TerminatorKind::Goto { target: self.block_index_offset(3) }, false); let unwind = self.block(vec![], TerminatorKind::UnwindResume, true); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index f4481c22fc1f..aa9c87d8f80d 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -12,7 +12,7 @@ use rustc_middle::mir::{ Terminator, TerminatorKind, UnwindAction, UnwindTerminateReason, RETURN_PLACE, }; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::util::Discr; +use rustc_middle::ty::util::{AsyncDropGlueMorphology, Discr}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::source_map::respan; @@ -116,15 +116,25 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { } fn build(self) -> Body<'tcx> { - let (tcx, def_id, Some(self_ty)) = (self.tcx, self.def_id, self.self_ty) else { + let (tcx, Some(self_ty)) = (self.tcx, self.self_ty) else { return self.build_zst_output(); }; + match self_ty.async_drop_glue_morphology(tcx) { + AsyncDropGlueMorphology::Noop => span_bug!( + self.span, + "async drop glue shim generator encountered type with noop async drop glue morphology" + ), + AsyncDropGlueMorphology::DeferredDropInPlace => { + return self.build_deferred_drop_in_place(); + } + AsyncDropGlueMorphology::Custom => (), + } let surface_drop_kind = || { - let param_env = tcx.param_env_reveal_all_normalized(def_id); - if self_ty.has_surface_async_drop(tcx, param_env) { + let adt_def = self_ty.ty_adt_def()?; + if adt_def.async_destructor(tcx).is_some() { Some(SurfaceDropKind::Async) - } else if self_ty.has_surface_drop(tcx, param_env) { + } else if adt_def.destructor(tcx).is_some() { Some(SurfaceDropKind::Sync) } else { None @@ -267,6 +277,13 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { self.return_() } + fn build_deferred_drop_in_place(mut self) -> Body<'tcx> { + self.put_self(); + let deferred = self.combine_deferred_drop_in_place(); + self.combine_fuse(deferred); + self.return_() + } + fn build_fused_async_surface(mut self) -> Body<'tcx> { self.put_self(); let surface = self.combine_async_surface(); @@ -441,6 +458,14 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { ) } + fn combine_deferred_drop_in_place(&mut self) -> Ty<'tcx> { + self.apply_combinator( + 1, + LangItem::AsyncDropDeferredDropInPlace, + &[self.self_ty.unwrap().into()], + ) + } + fn combine_fuse(&mut self, inner_future_ty: Ty<'tcx>) -> Ty<'tcx> { self.apply_combinator(1, LangItem::AsyncDropFuse, &[inner_future_ty.into()]) } @@ -481,7 +506,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { if let Some(ty) = self.self_ty { debug_assert_eq!( output.ty(&self.locals, self.tcx), - ty.async_destructor_ty(self.tcx, self.param_env), + ty.async_destructor_ty(self.tcx), "output async destructor types did not match for type: {ty:?}", ); } diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 851e16559580..3b4d4c938771 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -8,7 +8,10 @@ use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance}; +use rustc_middle::ty::adjustment::PointerCoercion; +use rustc_middle::ty::{ + self, CoroutineArgsExt, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance, +}; use rustc_middle::{bug, span_bug}; use rustc_target::abi::{Size, FIRST_VARIANT}; use rustc_target::spec::abi::Abi; @@ -1132,9 +1135,76 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // FIXME(dyn-star): make sure nothing needs to be done here. } // FIXME: Add Checks for these - CastKind::PointerWithExposedProvenance - | CastKind::PointerExposeProvenance - | CastKind::PointerCoercion(_) => {} + CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {} + CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { + // FIXME: check signature compatibility. + check_kinds!( + op_ty, + "CastKind::{kind:?} input must be a fn item, not {:?}", + ty::FnDef(..) + ); + check_kinds!( + target_type, + "CastKind::{kind:?} output must be a fn pointer, not {:?}", + ty::FnPtr(..) + ); + } + CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => { + // FIXME: check safety and signature compatibility. + check_kinds!( + op_ty, + "CastKind::{kind:?} input must be a fn pointer, not {:?}", + ty::FnPtr(..) + ); + check_kinds!( + target_type, + "CastKind::{kind:?} output must be a fn pointer, not {:?}", + ty::FnPtr(..) + ); + } + CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..)) => { + // FIXME: check safety, captures, and signature compatibility. + check_kinds!( + op_ty, + "CastKind::{kind:?} input must be a closure, not {:?}", + ty::Closure(..) + ); + check_kinds!( + target_type, + "CastKind::{kind:?} output must be a fn pointer, not {:?}", + ty::FnPtr(..) + ); + } + CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => { + // FIXME: check same pointee? + check_kinds!( + op_ty, + "CastKind::{kind:?} input must be a raw mut pointer, not {:?}", + ty::RawPtr(_, Mutability::Mut) + ); + check_kinds!( + target_type, + "CastKind::{kind:?} output must be a raw const pointer, not {:?}", + ty::RawPtr(_, Mutability::Not) + ); + } + CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => { + // FIXME: Check pointee types + check_kinds!( + op_ty, + "CastKind::{kind:?} input must be a raw pointer, not {:?}", + ty::RawPtr(..) + ); + check_kinds!( + target_type, + "CastKind::{kind:?} output must be a raw pointer, not {:?}", + ty::RawPtr(..) + ); + } + CastKind::PointerCoercion(PointerCoercion::Unsize) => { + // This is used for all `CoerceUnsized` types, + // not just pointers/references, so is hard to check. + } CastKind::IntToInt | CastKind::IntToFloat => { let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool(); let target_valid = target_type.is_numeric() || target_type.is_char(); @@ -1145,10 +1215,29 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } - CastKind::FnPtrToPtr | CastKind::PtrToPtr => { - if !(op_ty.is_any_ptr() && target_type.is_unsafe_ptr()) { - self.fail(location, "Can't cast {op_ty} into 'Ptr'"); - } + CastKind::FnPtrToPtr => { + check_kinds!( + op_ty, + "CastKind::{kind:?} input must be a fn pointer, not {:?}", + ty::FnPtr(..) + ); + check_kinds!( + target_type, + "CastKind::{kind:?} output must be a raw pointer, not {:?}", + ty::RawPtr(..) + ); + } + CastKind::PtrToPtr => { + check_kinds!( + op_ty, + "CastKind::{kind:?} input must be a raw pointer, not {:?}", + ty::RawPtr(..) + ); + check_kinds!( + target_type, + "CastKind::{kind:?} output must be a raw pointer, not {:?}", + ty::RawPtr(..) + ); } CastKind::FloatToFloat | CastKind::FloatToInt => { if !op_ty.is_floating_point() || !target_type.is_numeric() { diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 619c4c63e511..a0b704aeea5f 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -47,7 +47,7 @@ impl<'a> Parser<'a> { token.can_begin_expr() // This exception is here for backwards compatibility. && !token.is_keyword(kw::Let) - && (token.span.edition().at_least_rust_2024() || !token.is_keyword(kw::Const)) + && (!token.is_keyword(kw::Const) || token.span.edition().at_least_rust_2024()) } NonterminalKind::Ty => token.can_begin_type(), NonterminalKind::Ident => get_macro_ident(token).is_some(), diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index d845e8ab90d5..fcedc1a4af3a 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -7,8 +7,8 @@ use ast::token::IdentIsRaw; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::{ - self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocConstraint, - AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs, + self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemConstraint, + AssocItemConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs, Path, PathSegment, QSelf, }; use rustc_errors::{Applicability, Diag, PResult}; @@ -720,10 +720,7 @@ impl<'a> Parser<'a> { )); } let kind = if self.eat(&token::Colon) { - // Parse associated type constraint bound. - - let bounds = self.parse_generic_bounds()?; - AssocConstraintKind::Bound { bounds } + AssocItemConstraintKind::Bound { bounds: self.parse_generic_bounds()? } } else if self.eat(&token::Eq) { self.parse_assoc_equality_term( ident, @@ -735,17 +732,17 @@ impl<'a> Parser<'a> { }; let span = lo.to(self.prev_token.span); - // Gate associated type bounds, e.g., `Iterator`. - if let AssocConstraintKind::Bound { .. } = kind { - if let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args - && args.inputs.is_empty() - && matches!(args.output, ast::FnRetTy::Default(..)) - { - self.psess.gated_spans.gate(sym::return_type_notation, span); - } + + if let AssocItemConstraintKind::Bound { .. } = kind + && let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args + && args.inputs.is_empty() + && let ast::FnRetTy::Default(..) = args.output + { + self.psess.gated_spans.gate(sym::return_type_notation, span); } + let constraint = - AssocConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span }; + AssocItemConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span }; Ok(Some(AngleBracketedArg::Constraint(constraint))) } else { // we only want to suggest `:` and `=` in contexts where the previous token @@ -772,7 +769,7 @@ impl<'a> Parser<'a> { ident: Ident, gen_args: Option<&GenericArgs>, eq: Span, - ) -> PResult<'a, AssocConstraintKind> { + ) -> PResult<'a, AssocItemConstraintKind> { let arg = self.parse_generic_arg(None)?; let span = ident.span.to(self.prev_token.span); let term = match arg { @@ -820,7 +817,7 @@ impl<'a> Parser<'a> { return Err(err); } }; - Ok(AssocConstraintKind::Equality { term }) + Ok(AssocItemConstraintKind::Equality { term }) } /// We do not permit arbitrary expressions as const arguments. They must be one of: @@ -941,7 +938,7 @@ impl<'a> Parser<'a> { } /// Given a arg inside of generics, we try to destructure it as if it were the LHS in - /// `LHS = ...`, i.e. an associated type binding. + /// `LHS = ...`, i.e. an associated item binding. /// This returns a bool indicating if there are any `for<'a, 'b>` binder args, the /// identifier, and any GAT arguments. fn get_ident_from_generic_arg( diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 2df8f58507b0..2033f3878875 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -194,7 +194,7 @@ impl<'a> Parser<'a> { pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P> { self.parse_ty_common( AllowPlus::Yes, - AllowCVariadic::Yes, + AllowCVariadic::No, RecoverQPath::Yes, RecoverReturnSign::OnlyFatArrow, None, @@ -344,8 +344,9 @@ impl<'a> Parser<'a> { match allow_c_variadic { AllowCVariadic::Yes => TyKind::CVarArgs, AllowCVariadic::No => { - // FIXME(Centril): Should we just allow `...` syntactically + // FIXME(c_variadic): Should we just allow `...` syntactically // anywhere in a type and use semantic restrictions instead? + // NOTE: This may regress certain MBE calls if done incorrectly. let guar = self .dcx() .emit_err(NestedCVariadicType { span: lo.to(self.prev_token.span) }); diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index faf6ca784670..ef71333d1c39 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -286,13 +286,11 @@ impl<'a> Iterator for Parser<'a> { lbrace_byte_pos.to(InnerOffset(rbrace_byte_pos.0 + width)), ); } - } else { - if let Some(&(_, maybe)) = self.cur.peek() { - match maybe { - '?' => self.suggest_format_debug(), - '<' | '^' | '>' => self.suggest_format_align(maybe), - _ => self.suggest_positional_arg_instead_of_captured_arg(arg), - } + } else if let Some(&(_, maybe)) = self.cur.peek() { + match maybe { + '?' => self.suggest_format_debug(), + '<' | '^' | '>' => self.suggest_format_align(maybe), + _ => self.suggest_positional_arg_instead_of_captured_arg(arg), } } Some(NextArgument(Box::new(arg))) @@ -1028,7 +1026,7 @@ fn find_width_map_from_snippet( if next_c == '{' { // consume up to 6 hexanumeric chars let digits_len = - s.clone().take(6).take_while(|(_, c)| c.is_digit(16)).count(); + s.clone().take(6).take_while(|(_, c)| c.is_ascii_hexdigit()).count(); let len_utf8 = s .as_str() @@ -1047,14 +1045,14 @@ fn find_width_map_from_snippet( width += required_skips + 2; s.nth(digits_len); - } else if next_c.is_digit(16) { + } else if next_c.is_ascii_hexdigit() { width += 1; // We suggest adding `{` and `}` when appropriate, accept it here as if // it were correct let mut i = 0; // consume up to 6 hexanumeric chars while let (Some((_, c)), _) = (s.next(), i < 6) { - if c.is_digit(16) { + if c.is_ascii_hexdigit() { width += 1; } else { break; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4fe84b91b8b1..39cb48c1af3a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2321,7 +2321,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let param_env = ty::ParamEnv::empty(); let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let span = tcx.def_span(def_id); let fresh_args = infcx.fresh_args_for_item(span, def_id.to_def_id()); diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index fa2c8f69c71d..71f3e8b7b5d9 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -196,7 +196,7 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon)); } - fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) { + 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)); diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index a980d5dcaba4..d49298781a23 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -246,7 +246,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_item(self, i) } - fn visit_body(&mut self, b: &'v hir::Body<'v>) { + fn visit_body(&mut self, b: &hir::Body<'v>) { self.record("Body", Id::None, b); hir_visit::walk_body(self, b); } @@ -477,9 +477,9 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_generic_args(self, ga) } - fn visit_assoc_type_binding(&mut self, type_binding: &'v hir::TypeBinding<'v>) { - self.record("TypeBinding", Id::Node(type_binding.hir_id), type_binding); - hir_visit::walk_assoc_type_binding(self, type_binding) + fn visit_assoc_item_constraint(&mut self, constraint: &'v hir::AssocItemConstraint<'v>) { + self.record("AssocItemConstraint", Id::Node(constraint.hir_id), constraint); + hir_visit::walk_assoc_item_constraint(self, constraint) } fn visit_attribute(&mut self, attr: &'v ast::Attribute) { @@ -688,7 +688,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { ast_visit::walk_path_segment(self, path_segment) } - // `GenericArgs` has one inline use (in `ast::AssocConstraint::gen_args`) and one + // `GenericArgs` has one inline use (in `ast::AssocItemConstraint::gen_args`) and one // non-inline use (in `ast::PathSegment::args`). The latter case is more // common, so we implement `visit_generic_args` and tolerate the double // counting in the former case. diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 82d43f078ee2..c9a476504562 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -54,7 +54,7 @@ pub fn ensure_wf<'tcx>( pred, ); let infcx = tcx.infer_ctxt().build(); - let ocx = traits::ObligationCtxt::new(&infcx); + let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx); ocx.register_obligation(obligation); let errors = ocx.select_all_or_error(); if !errors.is_empty() { diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 1f966be26ff4..698f15015c48 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -158,9 +158,8 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { } let mut maps = IrMaps::new(tcx); - let body_id = tcx.hir().body_owned_by(def_id); - let hir_id = tcx.hir().body_owner(body_id); - let body = tcx.hir().body(body_id); + let body = tcx.hir().body_owned_by(def_id); + let hir_id = tcx.hir().body_owner(body.id()); if let Some(upvars) = tcx.upvars_mentioned(def_id) { for &var_hir_id in upvars.keys() { @@ -171,17 +170,17 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { // gather up the various local variables, significant expressions, // and so forth: - maps.visit_body(body); + maps.visit_body(&body); // compute liveness let mut lsets = Liveness::new(&mut maps, def_id); - let entry_ln = lsets.compute(body, hir_id); - lsets.log_liveness(entry_ln, body_id.hir_id); + let entry_ln = lsets.compute(&body, hir_id); + lsets.log_liveness(entry_ln, body.id().hir_id); // check for various error conditions - lsets.visit_body(body); + lsets.visit_body(&body); lsets.warn_about_unused_upvars(entry_ln); - lsets.warn_about_unused_args(body, entry_ln); + lsets.warn_about_unused_args(&body, entry_ln); } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_passes/src/upvars.rs b/compiler/rustc_passes/src/upvars.rs index 2eed58d10bb7..f2454514e4d3 100644 --- a/compiler/rustc_passes/src/upvars.rs +++ b/compiler/rustc_passes/src/upvars.rs @@ -16,17 +16,17 @@ pub fn provide(providers: &mut Providers) { } let local_def_id = def_id.expect_local(); - let body = tcx.hir().body(tcx.hir().maybe_body_owned_by(local_def_id)?); + let body = tcx.hir().maybe_body_owned_by(local_def_id)?; let mut local_collector = LocalCollector::default(); - local_collector.visit_body(body); + local_collector.visit_body(&body); let mut capture_collector = CaptureCollector { tcx, locals: &local_collector.locals, upvars: FxIndexMap::default(), }; - capture_collector.visit_body(body); + capture_collector.visit_body(&body); if !capture_collector.upvars.is_empty() { Some(tcx.arena.alloc(capture_collector.upvars)) diff --git a/compiler/rustc_pattern_analysis/tests/common/mod.rs b/compiler/rustc_pattern_analysis/tests/common/mod.rs index e72fddb9e9a8..6e8bb5050055 100644 --- a/compiler/rustc_pattern_analysis/tests/common/mod.rs +++ b/compiler/rustc_pattern_analysis/tests/common/mod.rs @@ -13,7 +13,6 @@ pub fn init_tracing() { use tracing_subscriber::Layer; let _ = tracing_tree::HierarchicalLayer::default() .with_writer(std::io::stderr) - .with_indent_lines(true) .with_ansi(true) .with_targets(true) .with_indent_amount(2) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index f631ae76de50..698b28c626d0 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1695,7 +1695,7 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { rustc_ty_utils::sig_types::walk_types(tcx, def_id, &mut visitor); if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id) { - visitor.visit_nested_body(body_id); + visitor.visit_nested_body(body_id.id()); } } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 856cfbc01e8c..d1541527cf59 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1562,6 +1562,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some(suggestion) if suggestion.candidate == kw::Underscore => return false, Some(suggestion) => suggestion, }; + + let mut did_label_def_span = false; + if let Some(def_span) = suggestion.res.opt_def_id().map(|def_id| self.def_span(def_id)) { if span.overlaps(def_span) { // Don't suggest typo suggestion for itself like in the following: @@ -1595,31 +1598,38 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { errors::DefinedHere::SingleItem { span, candidate_descr, candidate } } }; + did_label_def_span = true; err.subdiagnostic(self.tcx.dcx(), label); } - let (span, sugg, post) = if let SuggestionTarget::SimilarlyNamed = suggestion.target + let (span, msg, sugg) = if let SuggestionTarget::SimilarlyNamed = suggestion.target && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) && let Some(span) = suggestion.span && let Some(candidate) = suggestion.candidate.as_str().strip_prefix('_') && snippet == candidate { + let candidate = suggestion.candidate; // When the suggested binding change would be from `x` to `_x`, suggest changing the // original binding definition instead. (#60164) - let post = format!(", consider renaming `{}` into `{snippet}`", suggestion.candidate); - (span, snippet, post) - } else { - (span, suggestion.candidate.to_ident_string(), String::new()) - }; - let msg = match suggestion.target { - SuggestionTarget::SimilarlyNamed => format!( - "{} {} with a similar name exists{post}", - suggestion.res.article(), - suggestion.res.descr() - ), - SuggestionTarget::SingleItem => { - format!("maybe you meant this {}", suggestion.res.descr()) + let msg = format!( + "the leading underscore in `{candidate}` marks it as unused, consider renaming it to `{snippet}`" + ); + if !did_label_def_span { + err.span_label(span, format!("`{candidate}` defined here")); } + (span, msg, snippet) + } else { + let msg = match suggestion.target { + SuggestionTarget::SimilarlyNamed => format!( + "{} {} with a similar name exists", + suggestion.res.article(), + suggestion.res.descr() + ), + SuggestionTarget::SingleItem => { + format!("maybe you meant this {}", suggestion.res.descr()) + } + }; + (span, msg, suggestion.candidate.to_ident_string()) }; err.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect); true diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index bcdd6716cc37..bcf2c9a92061 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1148,7 +1148,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, self.diag_metadata.currently_processing_generic_args = prev; } - fn visit_assoc_constraint(&mut self, constraint: &'ast AssocConstraint) { + fn visit_assoc_item_constraint(&mut self, constraint: &'ast AssocItemConstraint) { self.visit_ident(constraint.ident); if let Some(ref gen_args) = constraint.gen_args { // Forbid anonymous lifetimes in GAT parameters until proper semantics are decided. @@ -1157,13 +1157,13 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, }); } match constraint.kind { - AssocConstraintKind::Equality { ref term } => match term { + AssocItemConstraintKind::Equality { ref term } => match term { Term::Ty(ty) => self.visit_ty(ty), Term::Const(c) => { self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No)) } }, - AssocConstraintKind::Bound { ref bounds } => { + AssocItemConstraintKind::Bound { ref bounds } => { self.record_lifetime_params_for_impl_trait(constraint.id); walk_list!(self, visit_param_bound, bounds, BoundKind::Bound); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 9daa22f89d2c..ec24eac4a9d0 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -508,7 +508,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { let ast::AngleBracketedArg::Constraint(constraint) = param else { continue; }; - let ast::AssocConstraintKind::Bound { bounds } = &constraint.kind else { + let ast::AssocItemConstraintKind::Bound { bounds } = &constraint.kind else { continue; }; for bound in bounds { @@ -3390,11 +3390,11 @@ fn mk_where_bound_predicate( }; let mut segments = ThinVec::from(preceding); - let added_constraint = ast::AngleBracketedArg::Constraint(ast::AssocConstraint { + let added_constraint = ast::AngleBracketedArg::Constraint(ast::AssocItemConstraint { id: DUMMY_NODE_ID, ident: last.ident, gen_args: None, - kind: ast::AssocConstraintKind::Equality { + kind: ast::AssocItemConstraintKind::Equality { term: ast::Term::Ty(ast::ptr::P(ast::Ty { kind: ast::TyKind::Path(None, poly_trait_ref.trait_ref.path.clone()), id: DUMMY_NODE_ID, diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 62eb07e82871..2fbfb93150e7 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -367,7 +367,7 @@ pub fn transform_instance<'tcx>( let trait_method = tcx.associated_item(method_id); let trait_id = trait_ref.skip_binder().def_id; if traits::is_vtable_safe_method(tcx, trait_id, trait_method) - && tcx.object_safety_violations(trait_id).is_empty() + && tcx.is_object_safe(trait_id) { // Trait methods will have a Self polymorphic parameter, where the concreteized // implementatation will not. We need to walk back to the more general trait method diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index 412f7eced433..c84bb26735c5 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -252,7 +252,7 @@ impl Encodable for () { } impl Decodable for () { - fn decode(_: &mut D) -> () {} + fn decode(_: &mut D) {} } impl Encodable for PhantomData { diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index 6ec710f97d16..edfd48ed43b1 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -5,17 +5,17 @@ // Prefer importing stable_mir over internal rustc constructs to make this file more readable. use crate::rustc_smir::Tables; -use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy, TyCtxt}; +use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt}; use rustc_span::Symbol; use stable_mir::abi::Layout; use stable_mir::mir::alloc::AllocId; use stable_mir::mir::mono::{Instance, MonoItem, StaticDef}; use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, Safety, UnOp}; use stable_mir::ty::{ - Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const, - DynKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig, - GenericArgKind, GenericArgs, IndexedVal, IntTy, Movability, Pattern, Region, RigidTy, Span, - TermKind, TraitRef, Ty, UintTy, VariantDef, VariantIdx, + Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, DynKind, + ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig, + GenericArgKind, GenericArgs, IndexedVal, IntTy, MirConst, Movability, Pattern, Region, RigidTy, + Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx, }; use stable_mir::{CrateItem, CrateNum, DefId}; @@ -55,7 +55,7 @@ impl RustcInternal for GenericArgKind { let arg: rustc_ty::GenericArg<'tcx> = match self { GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(), GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(), - GenericArgKind::Const(cnst) => ty_const(cnst, tables, tcx).into(), + GenericArgKind::Const(cnst) => cnst.internal(tables, tcx).into(), }; tcx.lift(arg).unwrap() } @@ -76,13 +76,20 @@ impl RustcInternal for Ty { } } +impl RustcInternal for TyConst { + type T<'tcx> = InternalConst<'tcx>; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tcx.lift(tables.ty_consts[self.id]).unwrap() + } +} + impl RustcInternal for Pattern { type T<'tcx> = rustc_ty::Pattern<'tcx>; fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { tcx.mk_pat(match self { Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range { - start: start.as_ref().map(|c| ty_const(c, tables, tcx)), - end: end.as_ref().map(|c| ty_const(c, tables, tcx)), + start: start.as_ref().map(|c| c.internal(tables, tcx)), + end: end.as_ref().map(|c| c.internal(tables, tcx)), include_end: *include_end, }, }) @@ -101,7 +108,7 @@ impl RustcInternal for RigidTy { RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, tcx)), RigidTy::Never => rustc_ty::TyKind::Never, RigidTy::Array(ty, cnst) => { - rustc_ty::TyKind::Array(ty.internal(tables, tcx), ty_const(cnst, tables, tcx)) + rustc_ty::TyKind::Array(ty.internal(tables, tcx), cnst.internal(tables, tcx)) } RigidTy::Pat(ty, pat) => { rustc_ty::TyKind::Pat(ty.internal(tables, tcx), pat.internal(tables, tcx)) @@ -239,23 +246,10 @@ impl RustcInternal for VariantDef { } } -fn ty_const<'tcx>( - constant: &Const, - tables: &mut Tables<'_>, - tcx: TyCtxt<'tcx>, -) -> rustc_ty::Const<'tcx> { - match constant.internal(tables, tcx) { - rustc_middle::mir::Const::Ty(c) => c, - cnst => { - panic!("Trying to convert constant `{constant:?}` to type constant, but found {cnst:?}") - } - } -} - -impl RustcInternal for Const { +impl RustcInternal for MirConst { type T<'tcx> = rustc_middle::mir::Const<'tcx>; fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - let constant = tables.constants[self.id]; + let constant = tables.mir_consts[self.id]; match constant { rustc_middle::mir::Const::Ty(ty) => rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap()), rustc_middle::mir::Const::Unevaluated(uneval, ty) => { @@ -392,7 +386,7 @@ impl RustcInternal for TermKind { fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { match self { TermKind::Type(ty) => ty.internal(tables, tcx).into(), - TermKind::Const(const_) => ty_const(const_, tables, tcx).into(), + TermKind::Const(cnst) => cnst.internal(tables, tcx).into(), } } } diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 6e870728bafc..810ffc142a09 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -214,7 +214,8 @@ where spans: IndexMap::default(), types: IndexMap::default(), instances: IndexMap::default(), - constants: IndexMap::default(), + ty_consts: IndexMap::default(), + mir_consts: IndexMap::default(), layouts: IndexMap::default(), })); stable_mir::compiler_interface::run(&tables, || init(&tables, f)) diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index fa7b2a30ba6c..9822ed79e2bd 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -6,7 +6,6 @@ #![allow(rustc::usage_of_qualified_ty)] use rustc_abi::HasDataLayout; -use rustc_middle::ty; use rustc_middle::ty::layout::{ FnAbiOf, FnAbiOfHelpers, HasParamEnv, HasTyCtxt, LayoutOf, LayoutOfHelpers, }; @@ -14,6 +13,7 @@ use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; use rustc_middle::ty::{ GenericPredicates, Instance, List, ParamEnv, ScalarInt, TyCtxt, TypeVisitableExt, ValTree, }; +use rustc_middle::{mir, ty}; use rustc_span::def_id::LOCAL_CRATE; use stable_mir::abi::{FnAbi, Layout, LayoutShape}; use stable_mir::compiler_interface::Context; @@ -22,9 +22,9 @@ use stable_mir::mir::mono::{InstanceDef, StaticDef}; use stable_mir::mir::{BinOp, Body, Place, UnOp}; use stable_mir::target::{MachineInfo, MachineSize}; use stable_mir::ty::{ - AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef, - ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, - UintTy, VariantDef, + AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef, + ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, Ty, + TyConst, TyKind, UintTy, VariantDef, }; use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol}; use std::cell::RefCell; @@ -360,7 +360,15 @@ impl<'tcx> Context for TablesWrapper<'tcx> { def.internal(&mut *tables, tcx).fields.iter().map(|f| f.stable(&mut *tables)).collect() } - fn eval_target_usize(&self, cnst: &Const) -> Result { + fn eval_target_usize(&self, cnst: &MirConst) -> Result { + let mut tables = self.0.borrow_mut(); + let tcx = tables.tcx; + let mir_const = cnst.internal(&mut *tables, tcx); + mir_const + .try_eval_target_usize(tables.tcx, ParamEnv::empty()) + .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) + } + fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let mir_const = cnst.internal(&mut *tables, tcx); @@ -369,7 +377,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) } - fn try_new_const_zst(&self, ty: Ty) -> Result { + fn try_new_const_zst(&self, ty: Ty) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty_internal = ty.internal(&mut *tables, tcx); @@ -390,25 +398,45 @@ impl<'tcx> Context for TablesWrapper<'tcx> { ))); } - Ok(ty::Const::zero_sized(tables.tcx, ty_internal).stable(&mut *tables)) + Ok(mir::Const::Ty(ty::Const::zero_sized(tables.tcx, ty_internal)).stable(&mut *tables)) } - fn new_const_str(&self, value: &str) -> Const { + fn new_const_str(&self, value: &str) -> MirConst { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty = ty::Ty::new_static_str(tcx); let bytes = value.as_bytes(); let val_tree = ty::ValTree::from_raw_bytes(tcx, bytes); - ty::Const::new_value(tcx, val_tree, ty).stable(&mut *tables) + let ct = ty::Const::new_value(tcx, val_tree, ty); + super::convert::mir_const_from_ty_const(&mut *tables, ct, ty) } - fn new_const_bool(&self, value: bool) -> Const { + fn new_const_bool(&self, value: bool) -> MirConst { let mut tables = self.0.borrow_mut(); - ty::Const::from_bool(tables.tcx, value).stable(&mut *tables) + let ct = ty::Const::from_bool(tables.tcx, value); + let ty = tables.tcx.types.bool; + super::convert::mir_const_from_ty_const(&mut *tables, ct, ty) } - fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { + fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { + let mut tables = self.0.borrow_mut(); + let tcx = tables.tcx; + let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); + let size = tables.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap().size; + + // We don't use Const::from_bits since it doesn't have any error checking. + let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| { + Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`.")) + })?; + let ct = ty::Const::new_value(tables.tcx, ValTree::from_scalar_int(scalar), ty); + Ok(super::convert::mir_const_from_ty_const(&mut *tables, ct, ty)) + } + fn try_new_ty_const_uint( + &self, + value: u128, + uint_ty: UintTy, + ) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); @@ -453,7 +481,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .stable(&mut *tables) } - fn const_pretty(&self, cnst: &stable_mir::ty::Const) -> String { + fn mir_const_pretty(&self, cnst: &stable_mir::ty::MirConst) -> String { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; cnst.internal(&mut *tables, tcx).to_string() @@ -474,6 +502,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> { tables.types[ty].kind().stable(&mut *tables) } + fn ty_const_pretty(&self, ct: stable_mir::ty::TyConstId) -> String { + let tables = self.0.borrow_mut(); + tables.ty_consts[ct].to_string() + } + fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index a1a5c09ef0af..1c87293209c6 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -6,7 +6,7 @@ use rustc_middle::mir::interpret::alloc_range; use rustc_middle::mir::mono::MonoItem; use stable_mir::mir::alloc::GlobalAlloc; use stable_mir::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoFragment}; -use stable_mir::ty::{Allocation, Const, ConstantKind}; +use stable_mir::ty::{Allocation, ConstantKind, MirConst}; use stable_mir::{opaque, Error}; use crate::rustc_smir::{alloc, Stable, Tables}; @@ -724,11 +724,16 @@ impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> { } impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { - type T = stable_mir::ty::Const; + type T = stable_mir::ty::MirConst; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + let id = tables.intern_mir_const(tables.tcx.lift(*self).unwrap()); match *self { - mir::Const::Ty(c) => c.stable(tables), + mir::Const::Ty(c) => MirConst::new( + stable_mir::ty::ConstantKind::Ty(c.stable(tables)), + c.ty().stable(tables), + id, + ), mir::Const::Unevaluated(unev_const, ty) => { let kind = stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { @@ -737,21 +742,18 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { promoted: unev_const.promoted.map(|u| u.as_u32()), }); let ty = ty.stable(tables); - let id = tables.intern_const(tables.tcx.lift(*self).unwrap()); - Const::new(kind, ty, id) + MirConst::new(kind, ty, id) } mir::Const::Val(mir::ConstValue::ZeroSized, ty) => { let ty = ty.stable(tables); - let id = tables.intern_const(tables.tcx.lift(*self).unwrap()); - Const::new(ConstantKind::ZeroSized, ty, id) + MirConst::new(ConstantKind::ZeroSized, ty, id) } mir::Const::Val(val, ty) => { let ty = tables.tcx.lift(ty).unwrap(); let val = tables.tcx.lift(val).unwrap(); let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables)); let ty = ty.stable(tables); - let id = tables.intern_const(tables.tcx.lift(*self).unwrap()); - Const::new(kind, ty, id) + MirConst::new(kind, ty, id) } } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs index 736378a530f0..50687935473a 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs @@ -9,6 +9,8 @@ mod error; mod mir; mod ty; +pub use ty::mir_const_from_ty_const; + impl<'tcx> Stable<'tcx> for rustc_hir::Safety { type T = stable_mir::mir::Safety; fn stable(&self, _: &mut Tables<'_>) -> Self::T { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 66708def00f1..1f3356f579fe 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -3,8 +3,7 @@ use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; use stable_mir::ty::{ - AdtKind, Const, ConstantKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy, - TyKind, UintTy, + AdtKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy, TyKind, UintTy, }; use crate::rustc_smir::{alloc, Stable, Tables}; @@ -410,8 +409,50 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { } } +pub fn mir_const_from_ty_const<'tcx>( + tables: &mut Tables<'tcx>, + ty_const: ty::Const<'tcx>, + ty: Ty<'tcx>, +) -> stable_mir::ty::MirConst { + let kind = match ty_const.kind() { + ty::Value(val) => { + let val = match val { + ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar), + ty::ValTree::Branch(branch) => { + ty::ValTree::Branch(tables.tcx.lift(branch).unwrap()) + } + }; + let ty = tables.tcx.lift(ty).unwrap(); + let const_val = tables.tcx.valtree_to_const_val((ty, val)); + if matches!(const_val, mir::ConstValue::ZeroSized) { + stable_mir::ty::ConstantKind::ZeroSized + } else { + stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( + ty, const_val, tables, + )) + } + } + ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)), + ty::ErrorCt(_) => unreachable!(), + ty::InferCt(_) => unreachable!(), + ty::BoundCt(_, _) => unimplemented!(), + ty::PlaceholderCt(_) => unimplemented!(), + ty::Unevaluated(uv) => { + stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { + def: tables.const_def(uv.def), + args: uv.args.stable(tables), + promoted: None, + }) + } + ty::ExprCt(_) => unimplemented!(), + }; + let stable_ty = tables.intern_ty(ty); + let id = tables.intern_mir_const(mir::Const::Ty(ty_const)); + stable_mir::ty::MirConst::new(kind, stable_ty, id) +} + impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { - type T = stable_mir::ty::Const; + type T = stable_mir::ty::TyConst; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { let kind = match self.kind() { @@ -425,30 +466,27 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { let ty = tables.tcx.lift(self.ty()).unwrap(); let const_val = tables.tcx.valtree_to_const_val((ty, val)); if matches!(const_val, mir::ConstValue::ZeroSized) { - ConstantKind::ZeroSized + stable_mir::ty::TyConstKind::ZSTValue(ty.stable(tables)) } else { - stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( - ty, const_val, tables, - )) + stable_mir::ty::TyConstKind::Value( + ty.stable(tables), + alloc::new_allocation(ty, const_val, tables), + ) } } - ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)), + ty::ParamCt(param) => stable_mir::ty::TyConstKind::Param(param.stable(tables)), + ty::Unevaluated(uv) => stable_mir::ty::TyConstKind::Unevaluated( + tables.const_def(uv.def), + uv.args.stable(tables), + ), ty::ErrorCt(_) => unreachable!(), ty::InferCt(_) => unreachable!(), ty::BoundCt(_, _) => unimplemented!(), ty::PlaceholderCt(_) => unimplemented!(), - ty::Unevaluated(uv) => { - stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { - def: tables.const_def(uv.def), - args: uv.args.stable(tables), - promoted: None, - }) - } ty::ExprCt(_) => unimplemented!(), }; - let ty = self.ty().stable(tables); - let id = tables.intern_const(mir::Const::Ty(tables.tcx.lift(*self).unwrap())); - Const::new(kind, ty, id) + let id = tables.intern_ty_const(tables.tcx.lift(*self).unwrap()); + stable_mir::ty::TyConst::new(kind, id) } } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index aba7e7dc9c21..d13e78033263 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use stable_mir::abi::Layout; use stable_mir::mir::mono::InstanceDef; -use stable_mir::ty::{ConstId, Span}; +use stable_mir::ty::{MirConstId, Span, TyConstId}; use stable_mir::{CtorKind, ItemKind}; use std::ops::RangeInclusive; use tracing::debug; @@ -33,7 +33,8 @@ pub struct Tables<'tcx> { pub(crate) spans: IndexMap, pub(crate) types: IndexMap, stable_mir::ty::Ty>, pub(crate) instances: IndexMap, InstanceDef>, - pub(crate) constants: IndexMap, ConstId>, + pub(crate) ty_consts: IndexMap, TyConstId>, + pub(crate) mir_consts: IndexMap, MirConstId>, pub(crate) layouts: IndexMap, Layout>, } @@ -42,8 +43,12 @@ impl<'tcx> Tables<'tcx> { self.types.create_or_fetch(ty) } - pub(crate) fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId { - self.constants.create_or_fetch(constant) + pub(crate) fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> TyConstId { + self.ty_consts.create_or_fetch(ct) + } + + pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> MirConstId { + self.mir_consts.create_or_fetch(constant) } pub(crate) fn has_body(&self, instance: Instance<'tcx>) -> bool { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 25ecb9a31c6a..61ca0d54ca49 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -429,6 +429,7 @@ symbols! { async_drop, async_drop_chain, async_drop_defer, + async_drop_deferred_drop_in_place, async_drop_either, async_drop_fuse, async_drop_in_place, @@ -1579,6 +1580,7 @@ symbols! { rustc_def_path, rustc_default_body_unstable, rustc_deny_explicit_impl, + rustc_deprecated_safe_2024, rustc_diagnostic_item, rustc_diagnostic_macros, rustc_dirty, diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index fc852293dff0..c95649e2ffb8 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -1,14 +1,12 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::{self, ObligationCtxt, SelectionContext}; +use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt, SelectionContext}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_infer::traits::Obligation; use rustc_macros::extension; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse}; use rustc_middle::traits::query::NoSolution; -use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_middle::ty::{GenericArg, Upcast}; use rustc_span::DUMMY_SP; @@ -94,7 +92,7 @@ impl<'tcx> InferCtxt<'tcx> { ty::TraitRef::new(self.tcx, trait_def_id, [ty]), )) { Ok(Some(selection)) => { - let ocx = ObligationCtxt::new(self); + let ocx = ObligationCtxt::new_with_diagnostics(self); ocx.register_obligations(selection.nested_obligations()); Some(ocx.select_all_or_error()) } diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index 5e0d7da4f06b..5f986e22f513 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -1,3 +1,4 @@ +use crate::traits::ScrubbedTraitError; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{InferCtxt, RegionResolutionError}; use rustc_macros::extension; @@ -27,7 +28,7 @@ impl<'tcx> InferCtxt<'tcx> { ), ty, ) - .map_err(|_| NoSolution) + .map_err(|_: Vec>| NoSolution) } else { Ok(ty) } diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index aae6fa9f635b..b51efd339c4d 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -714,7 +714,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { }; // Do not consider built-in object impls for non-object-safe types. - if bounds.principal_def_id().is_some_and(|def_id| !tcx.check_is_object_safe(def_id)) { + if bounds.principal_def_id().is_some_and(|def_id| !tcx.is_object_safe(def_id)) { return; } diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index 08796ef3109e..98f98d9992d3 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -554,8 +554,8 @@ fn coroutine_closure_to_certain_coroutine<'tcx>( goal_kind: ty::ClosureKind, goal_region: ty::Region<'tcx>, def_id: DefId, - args: ty::CoroutineClosureArgs<'tcx>, - sig: ty::CoroutineClosureSignature<'tcx>, + args: ty::CoroutineClosureArgs>, + sig: ty::CoroutineClosureSignature>, ) -> Ty<'tcx> { sig.to_coroutine_given_kind_and_upvars( tcx, @@ -578,8 +578,8 @@ fn coroutine_closure_to_ambiguous_coroutine<'tcx>( goal_kind: ty::ClosureKind, goal_region: ty::Region<'tcx>, def_id: DefId, - args: ty::CoroutineClosureArgs<'tcx>, - sig: ty::CoroutineClosureSignature<'tcx>, + args: ty::CoroutineClosureArgs>, + sig: ty::CoroutineClosureSignature>, ) -> Ty<'tcx> { let upvars_projection_def_id = tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None); let tupled_upvars_ty = Ty::new_projection( @@ -726,7 +726,7 @@ impl<'tcx> TypeFolder> for ReplaceProjectionWith<'_, 'tcx> { ) .expect("expected to be able to unify goal projection with dyn's projection"), ); - proj.term.ty().unwrap() + proj.term.expect_type() } else { ty.super_fold_with(self) } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index b18b59d9a752..f18f1f4f8f0d 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -12,7 +12,6 @@ use rustc_middle::bug; use rustc_middle::traits::solve::{ inspect, CanonicalInput, CanonicalResponse, Certainty, PredefinedOpaquesData, QueryResult, }; -use rustc_middle::traits::specialization_graph; use rustc_middle::ty::AliasRelationDirection; use rustc_middle::ty::TypeFolder; use rustc_middle::ty::{ @@ -900,16 +899,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { args } - pub(super) fn translate_args( - &self, - param_env: ty::ParamEnv<'tcx>, - source_impl: DefId, - source_args: ty::GenericArgsRef<'tcx>, - target_node: specialization_graph::Node, - ) -> ty::GenericArgsRef<'tcx> { - crate::traits::translate_args(self.infcx, param_env, source_impl, source_args, target_node) - } - pub(super) fn register_ty_outlives(&self, ty: Ty<'tcx>, lt: ty::Region<'tcx>) { self.infcx.register_region_obligation_with_cause(ty, lt, &ObligationCause::dummy()); } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index d28cf834032d..dc13941e5d7b 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -1,3 +1,4 @@ +use std::marker::PhantomData; use std::mem; use std::ops::ControlFlow; @@ -5,14 +6,16 @@ use rustc_infer::infer::InferCtxt; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause}; use rustc_infer::traits::{ - self, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, - ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError, TraitEngine, + self, FromSolverError, MismatchedProjectionTypes, Obligation, ObligationCause, + ObligationCauseCode, PredicateObligation, SelectionError, TraitEngine, }; use rustc_middle::bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::sym; +use crate::traits::{FulfillmentError, FulfillmentErrorCode, ScrubbedTraitError}; + use super::eval_ctxt::GenerateProofTree; use super::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor}; use super::{Certainty, InferCtxtEvalExt}; @@ -28,7 +31,7 @@ use super::{Certainty, InferCtxtEvalExt}; /// /// It is also likely that we want to use slightly different datastructures /// here as this will have to deal with far more root goals than `evaluate_all`. -pub struct FulfillmentCtxt<'tcx> { +pub struct FulfillmentCtxt<'tcx, E: 'tcx> { obligations: ObligationStorage<'tcx>, /// The snapshot in which this context was created. Using the context @@ -36,6 +39,7 @@ pub struct FulfillmentCtxt<'tcx> { /// gets rolled back. Because of this we explicitly check that we only /// use the context in exactly this snapshot. usable_in_snapshot: usize, + _errors: PhantomData, } #[derive(Default)] @@ -89,8 +93,8 @@ impl<'tcx> ObligationStorage<'tcx> { } } -impl<'tcx> FulfillmentCtxt<'tcx> { - pub fn new(infcx: &InferCtxt<'tcx>) -> FulfillmentCtxt<'tcx> { +impl<'tcx, E: 'tcx> FulfillmentCtxt<'tcx, E> { + pub fn new(infcx: &InferCtxt<'tcx>) -> FulfillmentCtxt<'tcx, E> { assert!( infcx.next_trait_solver(), "new trait solver fulfillment context created when \ @@ -99,6 +103,7 @@ impl<'tcx> FulfillmentCtxt<'tcx> { FulfillmentCtxt { obligations: Default::default(), usable_in_snapshot: infcx.num_open_snapshots(), + _errors: PhantomData, } } @@ -118,7 +123,10 @@ impl<'tcx> FulfillmentCtxt<'tcx> { } } -impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { +impl<'tcx, E> TraitEngine<'tcx, E> for FulfillmentCtxt<'tcx, E> +where + E: FromSolverError<'tcx, NextSolverError<'tcx>>, +{ #[instrument(level = "trace", skip(self, infcx))] fn register_predicate_obligation( &mut self, @@ -129,24 +137,22 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { self.obligations.register(obligation); } - fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec> { - let mut errors: Vec<_> = self - .obligations + fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec { + self.obligations .pending .drain(..) - .map(|obligation| fulfillment_error_for_stalled(infcx, obligation)) - .collect(); - - errors.extend(self.obligations.overflowed.drain(..).map(|obligation| FulfillmentError { - obligation: find_best_leaf_obligation(infcx, &obligation, true), - code: FulfillmentErrorCode::Ambiguity { overflow: Some(true) }, - root_obligation: obligation, - })); - - errors + .map(|obligation| NextSolverError::Ambiguity(obligation)) + .chain( + self.obligations + .overflowed + .drain(..) + .map(|obligation| NextSolverError::Overflow(obligation)), + ) + .map(|e| E::from_solver_error(infcx, e)) + .collect() } - fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec> { + fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec { assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); let mut errors = Vec::new(); for i in 0.. { @@ -164,7 +170,10 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { let (changed, certainty) = match result { Ok(result) => result, Err(NoSolution) => { - errors.push(fulfillment_error_for_no_solution(infcx, obligation)); + errors.push(E::from_solver_error( + infcx, + NextSolverError::TrueError(obligation), + )); continue; } }; @@ -195,6 +204,39 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { } } +pub enum NextSolverError<'tcx> { + TrueError(PredicateObligation<'tcx>), + Ambiguity(PredicateObligation<'tcx>), + Overflow(PredicateObligation<'tcx>), +} + +impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for FulfillmentError<'tcx> { + fn from_solver_error(infcx: &InferCtxt<'tcx>, error: NextSolverError<'tcx>) -> Self { + match error { + NextSolverError::TrueError(obligation) => { + fulfillment_error_for_no_solution(infcx, obligation) + } + NextSolverError::Ambiguity(obligation) => { + fulfillment_error_for_stalled(infcx, obligation) + } + NextSolverError::Overflow(obligation) => { + fulfillment_error_for_overflow(infcx, obligation) + } + } + } +} + +impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for ScrubbedTraitError<'tcx> { + fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: NextSolverError<'tcx>) -> Self { + match error { + NextSolverError::TrueError(_) => ScrubbedTraitError::TrueError, + NextSolverError::Ambiguity(_) | NextSolverError::Overflow(_) => { + ScrubbedTraitError::Ambiguity + } + } + } +} + fn fulfillment_error_for_no_solution<'tcx>( infcx: &InferCtxt<'tcx>, root_obligation: PredicateObligation<'tcx>, @@ -280,6 +322,17 @@ fn fulfillment_error_for_stalled<'tcx>( } } +fn fulfillment_error_for_overflow<'tcx>( + infcx: &InferCtxt<'tcx>, + root_obligation: PredicateObligation<'tcx>, +) -> FulfillmentError<'tcx> { + FulfillmentError { + obligation: find_best_leaf_obligation(infcx, &root_obligation, true), + code: FulfillmentErrorCode::Ambiguity { overflow: Some(true) }, + root_obligation, + } +} + fn find_best_leaf_obligation<'tcx>( infcx: &InferCtxt<'tcx>, obligation: &PredicateObligation<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index a432090f78cd..68a4831c3350 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -40,7 +40,7 @@ mod search_graph; mod trait_goals; pub use eval_ctxt::{EvalCtxt, GenerateProofTree, InferCtxtEvalExt, InferCtxtSelectExt}; -pub use fulfill::FulfillmentCtxt; +pub use fulfill::{FulfillmentCtxt, NextSolverError}; pub(crate) use normalize::deeply_normalize_for_diagnostics; pub use normalize::{deeply_normalize, deeply_normalize_with_skipped_universes}; @@ -133,7 +133,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { } fn compute_object_safe_goal(&mut self, trait_def_id: DefId) -> QueryResult<'tcx> { - if self.interner().check_is_object_safe(trait_def_id) { + if self.interner().is_object_safe(trait_def_id) { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } else { Err(NoSolution) @@ -197,8 +197,30 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { goal: Goal<'tcx, (ty::Const<'tcx>, Ty<'tcx>)>, ) -> QueryResult<'tcx> { let (ct, ty) = goal.predicate; - self.eq(goal.param_env, ct.ty(), ty)?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + + // FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant + // other than `ConstKind::Value`. Unfortunately this would require looking in the + // env for any `ConstArgHasType` assumptions for parameters and placeholders. I + // have not yet gotten around to implementing this though. + // + // We do still stall on infer vars though as otherwise a goal like: + // `ConstArgHasType(?x: usize, usize)` can succeed even though it might later + // get unified with some const that is not of type `usize`. + match ct.kind() { + // FIXME: Ignore effect vars because canonicalization doesn't handle them correctly + // and if we stall on the var then we wind up creating ambiguity errors in a probe + // for this goal which contains an effect var. Which then ends up ICEing. + ty::ConstKind::Infer(ty::InferConst::Var(_)) => { + self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + } + ty::ConstKind::Error(_) => { + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } + _ => { + self.eq(goal.param_env, ct.ty(), ty)?; + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } + } } } diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 5d5161e092e3..c60d1aed415a 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -1,24 +1,27 @@ +use std::fmt::Debug; +use std::marker::PhantomData; + use crate::traits::error_reporting::{OverflowCause, TypeErrCtxtExt}; use crate::traits::query::evaluate_obligation::InferCtxtExt; -use crate::traits::{BoundVarReplacer, PlaceholderReplacer}; +use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::at::At; use rustc_infer::infer::InferCtxt; -use rustc_infer::traits::TraitEngineExt; -use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine}; +use rustc_infer::traits::{FromSolverError, Obligation, TraitEngine}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, Ty, TyCtxt, UniverseIndex}; use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{TypeFoldable, TypeVisitableExt}; -use super::FulfillmentCtxt; +use super::{FulfillmentCtxt, NextSolverError}; /// Deeply normalize all aliases in `value`. This does not handle inference and expects /// its input to be already fully resolved. -pub fn deeply_normalize<'tcx, T: TypeFoldable>>( - at: At<'_, 'tcx>, - value: T, -) -> Result>> { +pub fn deeply_normalize<'tcx, T, E>(at: At<'_, 'tcx>, value: T) -> Result> +where + T: TypeFoldable>, + E: FromSolverError<'tcx, NextSolverError<'tcx>>, +{ assert!(!value.has_escaping_bound_vars()); deeply_normalize_with_skipped_universes(at, value, vec![]) } @@ -29,29 +32,35 @@ pub fn deeply_normalize<'tcx, T: TypeFoldable>>( /// Additionally takes a list of universes which represents the binders which have been /// entered before passing `value` to the function. This is currently needed for /// `normalize_erasing_regions`, which skips binders as it walks through a type. -pub fn deeply_normalize_with_skipped_universes<'tcx, T: TypeFoldable>>( +pub fn deeply_normalize_with_skipped_universes<'tcx, T, E>( at: At<'_, 'tcx>, value: T, universes: Vec>, -) -> Result>> { +) -> Result> +where + T: TypeFoldable>, + E: FromSolverError<'tcx, NextSolverError<'tcx>>, +{ let fulfill_cx = FulfillmentCtxt::new(at.infcx); - let mut folder = NormalizationFolder { at, fulfill_cx, depth: 0, universes }; + let mut folder = + NormalizationFolder { at, fulfill_cx, depth: 0, universes, _errors: PhantomData }; value.try_fold_with(&mut folder) } -struct NormalizationFolder<'me, 'tcx> { +struct NormalizationFolder<'me, 'tcx, E> { at: At<'me, 'tcx>, - fulfill_cx: FulfillmentCtxt<'tcx>, + fulfill_cx: FulfillmentCtxt<'tcx, E>, depth: usize, universes: Vec>, + _errors: PhantomData, } -impl<'tcx> NormalizationFolder<'_, 'tcx> { - fn normalize_alias_ty( - &mut self, - alias_ty: Ty<'tcx>, - ) -> Result, Vec>> { +impl<'tcx, E> NormalizationFolder<'_, 'tcx, E> +where + E: FromSolverError<'tcx, NextSolverError<'tcx>>, +{ + fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result, Vec> { assert!(matches!(alias_ty.kind(), ty::Alias(..))); let infcx = self.at.infcx; @@ -102,7 +111,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { &mut self, ty: Ty<'tcx>, uv: ty::UnevaluatedConst<'tcx>, - ) -> Result, Vec>> { + ) -> Result, Vec> { let infcx = self.at.infcx; let tcx = infcx.tcx; let recursion_limit = tcx.recursion_limit(); @@ -142,8 +151,11 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { } } -impl<'tcx> FallibleTypeFolder> for NormalizationFolder<'_, 'tcx> { - type Error = Vec>; +impl<'tcx, E> FallibleTypeFolder> for NormalizationFolder<'_, 'tcx, E> +where + E: FromSolverError<'tcx, NextSolverError<'tcx>> + Debug, +{ + type Error = Vec; fn interner(&self) -> TyCtxt<'tcx> { self.at.infcx.tcx @@ -243,7 +255,7 @@ impl<'tcx> TypeFolder> for DeeplyNormalizeForDiagnosticsFolder<'_, ty, vec![None; ty.outer_exclusive_binder().as_usize()], ) - .unwrap_or_else(|_| ty.super_fold_with(self)) + .unwrap_or_else(|_: Vec>| ty.super_fold_with(self)) } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { @@ -252,6 +264,6 @@ impl<'tcx> TypeFolder> for DeeplyNormalizeForDiagnosticsFolder<'_, ct, vec![None; ct.outer_exclusive_binder().as_usize()], ) - .unwrap_or_else(|_| ct.super_fold_with(self)) + .unwrap_or_else(|_: Vec>| ct.super_fold_with(self)) } } diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index f9e164e1f3f9..8c63bd824bc0 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -1,4 +1,4 @@ -use crate::traits::specialization_graph; +use crate::traits::specialization_graph::{self, LeafDef, Node}; use super::assembly::structural_traits::AsyncCallableRelevantTypes; use super::assembly::{self, structural_traits, Candidate}; @@ -9,7 +9,6 @@ use rustc_infer::infer::InferCtxt; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::inspect::ProbeKind; use rustc_infer::traits::solve::MaybeCause; -use rustc_infer::traits::specialization_graph::LeafDef; use rustc_infer::traits::Reveal; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult}; use rustc_middle::traits::BuiltinImplSource; @@ -189,8 +188,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { // In case the associated item is hidden due to specialization, we have to // return ambiguity this would otherwise be incomplete, resulting in // unsoundness during coherence (#105782). - let Some(assoc_def) = fetch_eligible_assoc_item_def( - ecx, + let Some(assoc_def) = ecx.fetch_eligible_assoc_item_def( goal.param_env, goal_trait_ref, goal.predicate.def_id(), @@ -235,16 +233,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { // // And then map these args to the args of the defining impl of `Assoc`, going // from `[u32, u64]` to `[u32, i32, u64]`. - let impl_args_with_gat = - goal.predicate.alias.args.rebase_onto(tcx, goal_trait_ref.def_id, impl_args); - let args = ecx.translate_args( - goal.param_env, - impl_def_id, - impl_args_with_gat, - assoc_def.defining_node, - ); + let associated_item_args = + ecx.translate_args(&assoc_def, goal, impl_def_id, impl_args, impl_trait_ref)?; - if !tcx.check_args_compatible(assoc_def.item.def_id, args) { + if !tcx.check_args_compatible(assoc_def.item.def_id, associated_item_args) { return error_response( ecx, "associated item has mismatched generic item arguments", @@ -272,7 +264,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ty::AssocKind::Fn => unreachable!("we should never project to a fn"), }; - ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, args)); + ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, associated_item_args)); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } @@ -845,7 +837,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { | ty::Str | ty::Slice(_) | ty::Tuple(_) - | ty::Error(_) => self_ty.async_destructor_ty(ecx.interner(), goal.param_env), + | ty::Error(_) => self_ty.async_destructor_ty(ecx.interner()), // We do not call `Ty::async_destructor_ty` on alias, param, or placeholder // types, which return `::AsyncDestructor` @@ -889,38 +881,79 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { } } -/// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code. -/// -/// FIXME: We should merge these 3 implementations as it's likely that they otherwise -/// diverge. -#[instrument(level = "trace", skip(ecx, param_env), ret)] -fn fetch_eligible_assoc_item_def<'tcx>( - ecx: &EvalCtxt<'_, InferCtxt<'tcx>>, - param_env: ty::ParamEnv<'tcx>, - goal_trait_ref: ty::TraitRef<'tcx>, - trait_assoc_def_id: DefId, - impl_def_id: DefId, -) -> Result, NoSolution> { - let node_item = - specialization_graph::assoc_def(ecx.interner(), impl_def_id, trait_assoc_def_id) - .map_err(|ErrorGuaranteed { .. }| NoSolution)?; +impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { + fn translate_args( + &mut self, + assoc_def: &LeafDef, + goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, + impl_def_id: DefId, + impl_args: ty::GenericArgsRef<'tcx>, + impl_trait_ref: rustc_type_ir::TraitRef>, + ) -> Result, NoSolution> { + let tcx = self.interner(); + Ok(match assoc_def.defining_node { + Node::Trait(_) => goal.predicate.alias.args, + Node::Impl(target_impl_def_id) => { + if target_impl_def_id == impl_def_id { + // Same impl, no need to fully translate, just a rebase from + // the trait is sufficient. + goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, impl_args) + } else { + let target_args = self.fresh_args_for_item(target_impl_def_id); + let target_trait_ref = tcx + .impl_trait_ref(target_impl_def_id) + .unwrap() + .instantiate(tcx, target_args); + // Relate source impl to target impl by equating trait refs. + self.eq(goal.param_env, impl_trait_ref, target_trait_ref)?; + // Also add predicates since they may be needed to constrain the + // target impl's params. + self.add_goals( + GoalSource::Misc, + tcx.predicates_of(target_impl_def_id) + .instantiate(tcx, target_args) + .into_iter() + .map(|(pred, _)| goal.with(tcx, pred)), + ); + goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, target_args) + } + } + }) + } - let eligible = if node_item.is_final() { - // Non-specializable items are always projectable. - true - } else { - // Only reveal a specializable default if we're past type-checking - // and the obligation is monomorphic, otherwise passes such as - // transmute checking and polymorphic MIR optimizations could - // get a result which isn't correct for all monomorphizations. - if param_env.reveal() == Reveal::All { - let poly_trait_ref = ecx.resolve_vars_if_possible(goal_trait_ref); - !poly_trait_ref.still_further_specializable() + /// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code. + /// + /// FIXME: We should merge these 3 implementations as it's likely that they otherwise + /// diverge. + #[instrument(level = "trace", skip(self, param_env), ret)] + fn fetch_eligible_assoc_item_def( + &self, + param_env: ty::ParamEnv<'tcx>, + goal_trait_ref: ty::TraitRef<'tcx>, + trait_assoc_def_id: DefId, + impl_def_id: DefId, + ) -> Result, NoSolution> { + let node_item = + specialization_graph::assoc_def(self.interner(), impl_def_id, trait_assoc_def_id) + .map_err(|ErrorGuaranteed { .. }| NoSolution)?; + + let eligible = if node_item.is_final() { + // Non-specializable items are always projectable. + true } else { - trace!(?node_item.item.def_id, "not eligible due to default"); - false - } - }; + // Only reveal a specializable default if we're past type-checking + // and the obligation is monomorphic, otherwise passes such as + // transmute checking and polymorphic MIR optimizations could + // get a result which isn't correct for all monomorphizations. + if param_env.reveal() == Reveal::All { + let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref); + !poly_trait_ref.still_further_specializable() + } else { + trace!(?node_item.item.def_id, "not eligible due to default"); + false + } + }; - if eligible { Ok(Some(node_item)) } else { Ok(None) } + if eligible { Ok(Some(node_item)) } else { Ok(None) } + } } diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs index 67ec2f3be481..82464470b2a2 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs @@ -17,7 +17,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { ) -> QueryResult<'tcx> { let tcx = self.interner(); let opaque_ty = goal.predicate.alias; - let expected = goal.predicate.term.ty().expect("no such thing as an opaque const"); + let expected = goal.predicate.term.as_type().expect("no such thing as an opaque const"); match (goal.param_env.reveal(), self.solver_mode()) { (Reveal::UserFacing, SolverMode::Normal) => { diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs index f1b8bf4676ee..84878fea1013 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs @@ -281,6 +281,7 @@ impl<'tcx> SearchGraph> { }; if let Some(result) = self.lookup_global_cache(tcx, input, available_depth, inspect) { + debug!("global cache hit"); return result; } @@ -365,7 +366,7 @@ impl<'tcx> SearchGraph> { for _ in 0..FIXPOINT_STEP_LIMIT { match self.fixpoint_step_in_task(tcx, input, inspect, &mut prove_goal) { StepResult::Done(final_entry, result) => return (final_entry, result), - StepResult::HasChanged => {} + StepResult::HasChanged => debug!("fixpoint changed provisional results"), } } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 67dd3fa85fa1..a741f488901e 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -1,7 +1,5 @@ //! Dealing with trait goals, i.e. `T: Trait<'a, U>`. -use crate::traits::supertrait_def_ids; - use super::assembly::structural_traits::AsyncCallableRelevantTypes; use super::assembly::{self, structural_traits, Candidate}; use super::{EvalCtxt, GoalSource, SolverMode}; @@ -791,7 +789,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { let Goal { predicate: (a_ty, _), .. } = goal; // Can only unsize to an object-safe trait. - if b_data.principal_def_id().is_some_and(|def_id| !tcx.check_is_object_safe(def_id)) { + if b_data.principal_def_id().is_some_and(|def_id| !tcx.is_object_safe(def_id)) { return Err(NoSolution); } @@ -837,7 +835,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { let a_auto_traits: FxIndexSet = a_data .auto_traits() .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| { - supertrait_def_ids(self.interner(), principal_def_id) + self.interner() + .supertrait_def_ids(principal_def_id) .filter(|def_id| self.interner().trait_is_auto(*def_id)) })) .collect(); diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 1ea207cc375f..6623a86e69ff 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -553,7 +553,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { } fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'tcx>) -> bool { - if let Some(ty) = p.term().skip_binder().ty() { + if let Some(ty) = p.term().skip_binder().as_type() { matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_term.expect_ty(self.tcx)) } else { false diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index ebdb032dc0e2..7723f2229bf9 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -11,6 +11,7 @@ use crate::solve::{deeply_normalize_for_diagnostics, inspect}; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::NormalizeExt; use crate::traits::SkipLeakCheck; +use crate::traits::{util, FulfillmentErrorCode}; use crate::traits::{ Obligation, ObligationCause, PredicateObligation, PredicateObligations, SelectionContext, }; @@ -19,7 +20,6 @@ use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; -use rustc_infer::traits::{util, FulfillmentErrorCode}; use rustc_middle::bug; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal}; @@ -360,7 +360,7 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>( let infcx = selcx.infcx; if infcx.next_trait_solver() { - let ocx = ObligationCtxt::new(infcx); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); ocx.register_obligations(obligations.iter().cloned()); let errors_and_ambiguities = ocx.select_all_or_error(); // We only care about the obligations that are *definitely* true errors. diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 4684c7171d82..811f61d2bf37 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -1,13 +1,16 @@ use std::cell::RefCell; use std::fmt::Debug; -use super::FulfillmentContext; -use super::TraitEngine; +use super::{FromSolverError, TraitEngine}; +use super::{FulfillmentContext, ScrubbedTraitError}; use crate::regions::InferCtxtRegionExt; use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt; +use crate::solve::NextSolverError; use crate::traits::error_reporting::TypeErrCtxtExt; +use crate::traits::fulfill::OldSolverError; use crate::traits::NormalizeExt; use crate::traits::StructurallyNormalizeExt; +use crate::traits::{FulfillmentError, Obligation, ObligationCause, PredicateObligation}; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -18,9 +21,6 @@ use rustc_infer::infer::canonical::{ use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::RegionResolutionError; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; -use rustc_infer::traits::{ - FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _, -}; use rustc_macros::extension; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::traits::query::NoSolution; @@ -30,8 +30,11 @@ use rustc_middle::ty::Upcast; use rustc_middle::ty::Variance; use rustc_middle::ty::{self, Ty, TyCtxt}; -#[extension(pub trait TraitEngineExt<'tcx>)] -impl<'tcx> dyn TraitEngine<'tcx> { +#[extension(pub trait TraitEngineExt<'tcx, E>)] +impl<'tcx, E> dyn TraitEngine<'tcx, E> +where + E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>, +{ fn new(infcx: &InferCtxt<'tcx>) -> Box { if infcx.next_trait_solver() { Box::new(NextFulfillmentCtxt::new(infcx)) @@ -49,16 +52,27 @@ impl<'tcx> dyn TraitEngine<'tcx> { /// Used if you want to have pleasant experience when dealing /// with obligations outside of hir or mir typeck. -pub struct ObligationCtxt<'a, 'tcx> { +pub struct ObligationCtxt<'a, 'tcx, E = ScrubbedTraitError<'tcx>> { pub infcx: &'a InferCtxt<'tcx>, - engine: RefCell>>, + engine: RefCell>>, } -impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { - pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { - Self { infcx, engine: RefCell::new(>::new(infcx)) } +impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>> { + pub fn new_with_diagnostics(infcx: &'a InferCtxt<'tcx>) -> Self { + Self { infcx, engine: RefCell::new(>::new(infcx)) } } +} +impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, ScrubbedTraitError<'tcx>> { + pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { + Self { infcx, engine: RefCell::new(>::new(infcx)) } + } +} + +impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E> +where + E: 'tcx, +{ pub fn register_obligation(&self, obligation: PredicateObligation<'tcx>) { self.engine.borrow_mut().register_predicate_obligation(self.infcx, obligation); } @@ -110,26 +124,6 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { self.register_infer_ok_obligations(infer_ok) } - pub fn deeply_normalize>>( - &self, - cause: &ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - value: T, - ) -> Result>> { - self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut()) - } - - pub fn structurally_normalize( - &self, - cause: &ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - value: Ty<'tcx>, - ) -> Result, Vec>> { - self.infcx - .at(cause, param_env) - .structurally_normalize(value, &mut **self.engine.borrow_mut()) - } - pub fn eq>( &self, cause: &ObligationCause<'tcx>, @@ -186,12 +180,12 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { } #[must_use] - pub fn select_where_possible(&self) -> Vec> { + pub fn select_where_possible(&self) -> Vec { self.engine.borrow_mut().select_where_possible(self.infcx) } #[must_use] - pub fn select_all_or_error(&self) -> Vec> { + pub fn select_all_or_error(&self) -> Vec { self.engine.borrow_mut().select_all_or_error(self.infcx) } @@ -235,7 +229,9 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { ) -> Vec> { self.infcx.resolve_regions(outlives_env) } +} +impl<'tcx> ObligationCtxt<'_, 'tcx, FulfillmentError<'tcx>> { pub fn assumed_wf_types_and_report_errors( &self, param_env: ty::ParamEnv<'tcx>, @@ -244,12 +240,35 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { self.assumed_wf_types(param_env, def_id) .map_err(|errors| self.infcx.err_ctxt().report_fulfillment_errors(errors)) } +} +impl<'tcx> ObligationCtxt<'_, 'tcx, ScrubbedTraitError<'tcx>> { + pub fn make_canonicalized_query_response( + &self, + inference_vars: CanonicalVarValues<'tcx>, + answer: T, + ) -> Result, NoSolution> + where + T: Debug + TypeFoldable>, + Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, + { + self.infcx.make_canonicalized_query_response( + inference_vars, + answer, + &mut **self.engine.borrow_mut(), + ) + } +} + +impl<'tcx, E> ObligationCtxt<'_, 'tcx, E> +where + E: FromSolverError<'tcx, NextSolverError<'tcx>>, +{ pub fn assumed_wf_types( &self, param_env: ty::ParamEnv<'tcx>, def_id: LocalDefId, - ) -> Result>, Vec>> { + ) -> Result>, Vec> { let tcx = self.infcx.tcx; let mut implied_bounds = FxIndexSet::default(); let mut errors = Vec::new(); @@ -281,19 +300,23 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { if errors.is_empty() { Ok(implied_bounds) } else { Err(errors) } } - pub fn make_canonicalized_query_response( + pub fn deeply_normalize>>( &self, - inference_vars: CanonicalVarValues<'tcx>, - answer: T, - ) -> Result, NoSolution> - where - T: Debug + TypeFoldable>, - Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, - { - self.infcx.make_canonicalized_query_response( - inference_vars, - answer, - &mut **self.engine.borrow_mut(), - ) + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + value: T, + ) -> Result> { + self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut()) + } + + pub fn structurally_normalize( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + value: Ty<'tcx>, + ) -> Result, Vec> { + self.infcx + .at(cause, param_env) + .structurally_normalize(value, &mut **self.engine.borrow_mut()) } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 6c56ebb62aed..6a96a03e047f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -29,10 +29,11 @@ use rustc_macros::extension; use rustc_middle::hir::map; use rustc_middle::traits::IsConstable; use rustc_middle::ty::error::TypeError::{self, Sorts}; +use rustc_middle::ty::print::PrintPolyTraitRefExt; use rustc_middle::ty::{ self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, GenericArgs, - InferTy, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitableExt, TypeckResults, Upcast, + InferTy, IsSuggestable, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, + TypeSuperFoldable, TypeVisitableExt, TypeckResults, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; @@ -219,15 +220,15 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>( (_, None) => predicate_constraint(hir_generics, trait_pred.upcast(tcx)), (None, Some((ident, []))) => ( ident.span.shrink_to_hi(), - format!(": {}", trait_pred.print_modifiers_and_trait_path()), + format!(": {}", trait_pred.to_poly_trait_ref().print_trait_sugared()), ), (_, Some((_, [.., bounds]))) => ( bounds.span().shrink_to_hi(), - format!(" + {}", trait_pred.print_modifiers_and_trait_path()), + format!(" + {}", trait_pred.to_poly_trait_ref().print_trait_sugared()), ), (Some(_), Some((_, []))) => ( hir_generics.span.shrink_to_hi(), - format!(": {}", trait_pred.print_modifiers_and_trait_path()), + format!(": {}", trait_pred.to_poly_trait_ref().print_trait_sugared()), ), }; @@ -450,7 +451,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } /// When after several dereferencing, the reference satisfies the trait - /// binding. This function provides dereference suggestion for this + /// bound. This function provides dereference suggestion for this /// specific situation. fn suggest_dereferences( &self, @@ -777,7 +778,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } /// We tried to apply the bound to an `fn` or closure. Check whether calling it would - /// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling + /// evaluate to a type that *would* satisfy the trait bound. If it would, suggest calling /// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`. fn suggest_fn_call( &self, @@ -907,10 +908,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span.remove_mark(); } let mut expr_finder = FindExprBySpan::new(span, self.tcx); - let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return; }; - let body = self.tcx.hir().body(body_id); expr_finder.visit_expr(body.value); let Some(expr) = expr_finder.result else { return; @@ -1112,7 +1112,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { Some(( DefIdOrName::DefId(def_id), - pred.kind().rebind(proj.term.ty().unwrap()), + pred.kind().rebind(proj.term.expect_type()), pred.kind().rebind(args.as_slice()), )) } else { @@ -1129,7 +1129,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { Some(( DefIdOrName::Name("trait object"), - pred.rebind(proj.term.ty().unwrap()), + pred.rebind(proj.term.expect_type()), pred.rebind(args.as_slice()), )) } else { @@ -1157,7 +1157,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { Some(( name, - pred.kind().rebind(proj.term.ty().unwrap()), + pred.kind().rebind(proj.term.expect_type()), pred.kind().rebind(args.as_slice()), )) } else { @@ -1241,7 +1241,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let param_env = obligation.param_env; - // Try to apply the original trait binding obligation by borrowing. + // Try to apply the original trait bound by borrowing. let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>, blacklist: &[DefId]| -> bool { @@ -1369,12 +1369,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Issue #104961, we need to add parentheses properly for compound expressions // for example, `x.starts_with("hi".to_string() + "you")` // should be `x.starts_with(&("hi".to_string() + "you"))` - let Some(body_id) = + let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return false; }; - let body = self.tcx.hir().body(body_id); let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(body.value); let Some(expr) = expr_finder.result else { @@ -1476,10 +1475,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span.remove_mark(); } let mut expr_finder = super::FindExprBySpan::new(span, self.tcx); - let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return false; }; - let body = self.tcx.hir().body(body_id); expr_finder.visit_expr(body.value); let mut maybe_suggest = |suggested_ty, count, suggestions| { // Remapping bound vars here @@ -1805,10 +1803,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); } - let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(obligation.cause.body_id)); + let body = self.tcx.hir().body_owned_by(obligation.cause.body_id); let mut visitor = ReturnsVisitor::default(); - visitor.visit_body(body); + visitor.visit_body(&body); let mut sugg = vec![(span.shrink_to_lo(), "Box<".to_string()), (span.shrink_to_hi(), ">".to_string())]; @@ -2348,13 +2346,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ?span, ); - let coroutine_body = coroutine_did - .as_local() - .and_then(|def_id| hir.maybe_body_owned_by(def_id)) - .map(|body_id| hir.body(body_id)); + let coroutine_body = + coroutine_did.as_local().and_then(|def_id| hir.maybe_body_owned_by(def_id)); let mut visitor = AwaitsVisitor::default(); if let Some(body) = coroutine_body { - visitor.visit_body(body); + visitor.visit_body(&body); } debug!(awaits = ?visitor.awaits); @@ -3844,7 +3840,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }) } else if let Some(where_pred) = where_pred.as_projection_clause() && let Some(failed_pred) = failed_pred.as_projection_clause() - && let Some(found) = failed_pred.skip_binder().term.ty() + && let Some(found) = failed_pred.skip_binder().term.as_type() { type_diffs = vec![Sorts(ty::error::ExpectedFound { expected: where_pred @@ -4748,7 +4744,7 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> { } } - fn visit_body(&mut self, body: &'v hir::Body<'v>) { + fn visit_body(&mut self, body: &hir::Body<'v>) { assert!(!self.in_block_tail); self.in_block_tail = true; hir::intravisit::walk_body(self, body); @@ -4908,14 +4904,12 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>( // `async fn` should always lower to a single bound... but don't ICE. return None; }; - let Some(hir::PathSegment { args: Some(generics), .. }) = - trait_ref.trait_ref.path.segments.last() + let Some(hir::PathSegment { args: Some(args), .. }) = trait_ref.trait_ref.path.segments.last() else { // desugaring to a single path segment for `Future<...>`. return None; }; - let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) = - generics.bindings.get(0).map(|binding| binding.kind) + let Some(future_output_ty) = args.constraints.first().and_then(|constraint| constraint.ty()) else { // Also should never happen. return None; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 46953a61296a..9a0929baeaf2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -414,7 +414,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => { let trait_predicate = bound_predicate.rebind(trait_predicate); let trait_predicate = self.resolve_vars_if_possible(trait_predicate); - let trait_predicate = self.apply_do_not_recommend(trait_predicate, &mut obligation); // Let's use the root obligation as the main message, when we care about the // most general case ("X doesn't implement Pattern<'_>") over the case that @@ -996,12 +995,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.emit() } - fn apply_do_not_recommend( - &self, - mut trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, - obligation: &'_ mut PredicateObligation<'tcx>, - ) -> ty::Binder<'tcx, ty::TraitPredicate<'tcx>> { + fn apply_do_not_recommend(&self, obligation: &mut PredicateObligation<'tcx>) -> bool { let mut base_cause = obligation.cause.code().clone(); + let mut applied_do_not_recommend = false; loop { if let ObligationCauseCode::ImplDerived(ref c) = base_cause { if self.tcx.has_attrs_with_path( @@ -1011,7 +1007,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let code = (*c.derived.parent_code).clone(); obligation.cause.map_code(|_| code); obligation.predicate = c.derived.parent_trait_pred.upcast(self.tcx); - trait_predicate = c.derived.parent_trait_pred.clone(); + applied_do_not_recommend = true; } } if let Some((parent_cause, _parent_pred)) = base_cause.parent() { @@ -1021,7 +1017,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - trait_predicate + applied_do_not_recommend } fn emit_specialized_closure_kind_error( @@ -1521,6 +1517,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { #[instrument(skip(self), level = "debug")] fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed { + let mut error = FulfillmentError { + obligation: error.obligation.clone(), + code: error.code.clone(), + root_obligation: error.root_obligation.clone(), + }; + if matches!( + error.code, + FulfillmentErrorCode::Select(crate::traits::SelectionError::Unimplemented) + | FulfillmentErrorCode::Project(_) + ) && self.apply_do_not_recommend(&mut error.obligation) + { + error.code = FulfillmentErrorCode::Select(SelectionError::Unimplemented); + } + match error.code { FulfillmentErrorCode::Select(ref selection_error) => self.report_selection_error( error.obligation.clone(), @@ -2451,11 +2461,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } if let Some(ty::GenericArgKind::Type(_)) = arg.map(|arg| arg.unpack()) - && let Some(body_id) = - self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) + && let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) { let mut expr_finder = FindExprBySpan::new(span, self.tcx); - expr_finder.visit_expr(self.tcx.hir().body(body_id).value); + expr_finder.visit_expr(&body.value); if let Some(hir::Expr { kind: @@ -2685,6 +2694,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .with_span_label(span, format!("cannot satisfy `{predicate}`")) } } + + // Given some `ConstArgHasType(?x, usize)`, we should not emit an error such as + // "type annotations needed: cannot satisfy the constant `_` has type `usize`" + // Instead we should emit a normal error suggesting the user to turbofish the + // const parameter that is currently being inferred. Unfortunately we cannot + // nicely emit such an error so we delay an ICE incase nobody else reports it + // for us. + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { + return self.tcx.sess.dcx().span_delayed_bug( + span, + format!( + "`ambiguous ConstArgHasType({:?}, {:?}) unaccompanied by inference error`", + ct, ty + ), + ); + } _ => { if let Some(e) = self.tainted_by_errors() { return e; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 629f6f394af3..a26288efc96d 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -6,7 +6,7 @@ use rustc_data_structures::obligation_forest::ProcessResult; use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome}; use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor}; use rustc_infer::infer::DefineOpaqueTypes; -use rustc_infer::traits::ProjectionCacheKey; +use rustc_infer::traits::{FromSolverError, ProjectionCacheKey}; use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine}; use rustc_middle::bug; use rustc_middle::mir::interpret::ErrorHandled; @@ -16,13 +16,13 @@ use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, Binder, Const, TypeVisitableExt}; use std::marker::PhantomData; -use super::const_evaluatable; use super::project::{self, ProjectAndUnifyResult}; use super::select::SelectionContext; use super::wf; use super::EvaluationResult; use super::PredicateObligation; use super::Unimplemented; +use super::{const_evaluatable, ScrubbedTraitError}; use super::{FulfillmentError, FulfillmentErrorCode}; use crate::traits::project::PolyProjectionObligation; @@ -50,7 +50,7 @@ impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { /// along. Once all type inference constraints have been generated, the /// method `select_all_or_error` can be used to report any remaining /// ambiguous cases as errors. -pub struct FulfillmentContext<'tcx> { +pub struct FulfillmentContext<'tcx, E: 'tcx> { /// A list of all obligations that have been registered with this /// fulfillment context. predicates: ObligationForest>, @@ -60,6 +60,8 @@ pub struct FulfillmentContext<'tcx> { /// gets rolled back. Because of this we explicitly check that we only /// use the context in exactly this snapshot. usable_in_snapshot: usize, + + _errors: PhantomData, } #[derive(Clone, Debug)] @@ -76,9 +78,12 @@ pub struct PendingPredicateObligation<'tcx> { #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(PendingPredicateObligation<'_>, 72); -impl<'tcx> FulfillmentContext<'tcx> { +impl<'tcx, E> FulfillmentContext<'tcx, E> +where + E: FromSolverError<'tcx, OldSolverError<'tcx>>, +{ /// Creates a new fulfillment context. - pub(super) fn new(infcx: &InferCtxt<'tcx>) -> FulfillmentContext<'tcx> { + pub(super) fn new(infcx: &InferCtxt<'tcx>) -> FulfillmentContext<'tcx, E> { assert!( !infcx.next_trait_solver(), "old trait solver fulfillment context created when \ @@ -87,13 +92,15 @@ impl<'tcx> FulfillmentContext<'tcx> { FulfillmentContext { predicates: ObligationForest::new(), usable_in_snapshot: infcx.num_open_snapshots(), + _errors: PhantomData, } } /// Attempts to select obligations using `selcx`. - fn select(&mut self, selcx: SelectionContext<'_, 'tcx>) -> Vec> { + fn select(&mut self, selcx: SelectionContext<'_, 'tcx>) -> Vec { let span = debug_span!("select", obligation_forest_size = ?self.predicates.len()); let _enter = span.enter(); + let infcx = selcx.infcx; // Process pending obligations. let outcome: Outcome<_, _> = @@ -102,8 +109,11 @@ impl<'tcx> FulfillmentContext<'tcx> { // FIXME: if we kept the original cache key, we could mark projection // obligations as complete for the projection cache here. - let errors: Vec> = - outcome.errors.into_iter().map(to_fulfillment_error).collect(); + let errors: Vec = outcome + .errors + .into_iter() + .map(|err| E::from_solver_error(infcx, OldSolverError(err))) + .collect(); debug!( "select({} predicates remaining, {} errors) done", @@ -115,7 +125,10 @@ impl<'tcx> FulfillmentContext<'tcx> { } } -impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { +impl<'tcx, E> TraitEngine<'tcx, E> for FulfillmentContext<'tcx, E> +where + E: FromSolverError<'tcx, OldSolverError<'tcx>>, +{ #[inline] fn register_predicate_obligation( &mut self, @@ -134,18 +147,15 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { .register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] }); } - fn collect_remaining_errors( - &mut self, - _infcx: &InferCtxt<'tcx>, - ) -> Vec> { + fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec { self.predicates .to_errors(FulfillmentErrorCode::Ambiguity { overflow: None }) .into_iter() - .map(to_fulfillment_error) + .map(|err| E::from_solver_error(infcx, OldSolverError(err))) .collect() } - fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec> { + fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec { let selcx = SelectionContext::new(infcx); self.select(selcx) } @@ -411,7 +421,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } ty::PredicateKind::ObjectSafe(trait_def_id) => { - if !self.selcx.tcx().check_is_object_safe(trait_def_id) { + if !self.selcx.tcx().is_object_safe(trait_def_id) { ProcessResult::Error(FulfillmentErrorCode::Select(Unimplemented)) } else { ProcessResult::Changed(vec![]) @@ -429,16 +439,37 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { // This is because this is not ever a useful obligation to report // as the cause of an overflow. ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { - match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq( - // Only really excercised by generic_const_exprs - DefineOpaqueTypes::Yes, - ct.ty(), - ty, - ) { - Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())), - Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select( - SelectionError::Unimplemented, - )), + // FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant + // other than `ConstKind::Value`. Unfortunately this would require looking in the + // env for any `ConstArgHasType` assumptions for parameters and placeholders. I + // don't really want to implement this in the old solver so I haven't. + // + // We do still stall on infer vars though as otherwise a goal like: + // `ConstArgHasType(?x: usize, usize)` can succeed even though it might later + // get unified with some const that is not of type `usize`. + let ct = self.selcx.infcx.shallow_resolve_const(ct); + match ct.kind() { + ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { + pending_obligation.stalled_on.clear(); + pending_obligation.stalled_on.extend([TyOrConstInferVar::Const(vid)]); + ProcessResult::Unchanged + } + ty::ConstKind::Error(_) => return ProcessResult::Changed(vec![]), + _ => { + match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq( + // Only really excercised by generic_const_exprs + DefineOpaqueTypes::Yes, + ct.ty(), + ty, + ) { + Ok(inf_ok) => { + ProcessResult::Changed(mk_pending(inf_ok.into_obligations())) + } + Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select( + SelectionError::Unimplemented, + )), + } + } } } @@ -819,13 +850,31 @@ fn args_infer_vars<'a, 'tcx>( .filter_map(TyOrConstInferVar::maybe_from_generic_arg) } -fn to_fulfillment_error<'tcx>( - error: Error, FulfillmentErrorCode<'tcx>>, -) -> FulfillmentError<'tcx> { - let mut iter = error.backtrace.into_iter(); - let obligation = iter.next().unwrap().obligation; - // The root obligation is the last item in the backtrace - if there's only - // one item, then it's the same as the main obligation - let root_obligation = iter.next_back().map_or_else(|| obligation.clone(), |e| e.obligation); - FulfillmentError::new(obligation, error.error, root_obligation) +#[derive(Debug)] +pub struct OldSolverError<'tcx>( + Error, FulfillmentErrorCode<'tcx>>, +); + +impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for FulfillmentError<'tcx> { + fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self { + let mut iter = error.0.backtrace.into_iter(); + let obligation = iter.next().unwrap().obligation; + // The root obligation is the last item in the backtrace - if there's only + // one item, then it's the same as the main obligation + let root_obligation = iter.next_back().map_or_else(|| obligation.clone(), |e| e.obligation); + FulfillmentError::new(obligation, error.0.error, root_obligation) + } +} + +impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for ScrubbedTraitError<'tcx> { + fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self { + match error.0.error { + FulfillmentErrorCode::Select(_) + | FulfillmentErrorCode::Project(_) + | FulfillmentErrorCode::Subtype(_, _) + | FulfillmentErrorCode::ConstEquate(_, _) => ScrubbedTraitError::TrueError, + FulfillmentErrorCode::Ambiguity { overflow: _ } => ScrubbedTraitError::Ambiguity, + FulfillmentErrorCode::Cycle(cycle) => ScrubbedTraitError::Cycle(cycle), + } + } } diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index a1094d982768..baec2268629d 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -1,13 +1,13 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. use crate::regions::InferCtxtRegionExt; -use crate::traits::{self, ObligationCause}; +use crate::traits::{self, FulfillmentError, ObligationCause}; use hir::LangItem; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; +use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; -use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError}; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt}; use super::outlives_bounds::InferCtxtExt; @@ -137,7 +137,7 @@ pub fn all_fields_implement_trait<'tcx>( for field in &variant.fields { // Do this per-field to get better error messages. let infcx = tcx.infer_ctxt().build(); - let ocx = traits::ObligationCtxt::new(&infcx); + let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx); let unnormalized_ty = field.ty(tcx, args); if unnormalized_ty.references_error() { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index ab4d06f26603..d918945dbed9 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -32,6 +32,7 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; use rustc_middle::query::Providers; use rustc_middle::span_bug; +use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFolder, TypeSuperVisitable, Upcast}; @@ -46,7 +47,7 @@ pub use self::coherence::{add_placeholder_note, orphan_check_trait_ref, overlapp pub use self::coherence::{InCrate, IsFirstInputType, UncoveredTyParams}; pub use self::coherence::{OrphanCheckErr, OrphanCheckMode, OverlapResult}; pub use self::engine::{ObligationCtxt, TraitEngineExt}; -pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation}; +pub use self::fulfill::{FulfillmentContext, OldSolverError, PendingPredicateObligation}; pub use self::normalize::NormalizeExt; pub use self::object_safety::hir_ty_lowering_object_safety_violations; pub use self::object_safety::is_vtable_safe_method; @@ -65,14 +66,85 @@ pub use self::structural_normalize::StructurallyNormalizeExt; pub use self::util::elaborate; pub use self::util::{expand_trait_aliases, TraitAliasExpander, TraitAliasExpansionInfo}; pub use self::util::{get_vtable_index_of_object_method, impl_item_is_final, upcast_choices}; -pub use self::util::{ - supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_item, - SupertraitDefIds, -}; +pub use self::util::{supertraits, transitive_bounds, transitive_bounds_that_define_assoc_item}; pub use self::util::{with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer}; pub use rustc_infer::traits::*; +pub struct FulfillmentError<'tcx> { + pub obligation: PredicateObligation<'tcx>, + pub code: FulfillmentErrorCode<'tcx>, + /// Diagnostics only: the 'root' obligation which resulted in + /// the failure to process `obligation`. This is the obligation + /// that was initially passed to `register_predicate_obligation` + pub root_obligation: PredicateObligation<'tcx>, +} + +impl<'tcx> FulfillmentError<'tcx> { + pub fn new( + obligation: PredicateObligation<'tcx>, + code: FulfillmentErrorCode<'tcx>, + root_obligation: PredicateObligation<'tcx>, + ) -> FulfillmentError<'tcx> { + FulfillmentError { obligation, code, root_obligation } + } + + pub fn is_true_error(&self) -> bool { + match self.code { + FulfillmentErrorCode::Select(_) + | FulfillmentErrorCode::Project(_) + | FulfillmentErrorCode::Subtype(_, _) + | FulfillmentErrorCode::ConstEquate(_, _) => true, + FulfillmentErrorCode::Cycle(_) | FulfillmentErrorCode::Ambiguity { overflow: _ } => { + false + } + } + } +} + +impl<'tcx> Debug for FulfillmentError<'tcx> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "FulfillmentError({:?},{:?})", self.obligation, self.code) + } +} + +#[derive(Clone)] +pub enum FulfillmentErrorCode<'tcx> { + /// Inherently impossible to fulfill; this trait is implemented if and only + /// if it is already implemented. + Cycle(Vec>), + Select(SelectionError<'tcx>), + Project(MismatchedProjectionTypes<'tcx>), + Subtype(ExpectedFound>, TypeError<'tcx>), // always comes from a SubtypePredicate + ConstEquate(ExpectedFound>, TypeError<'tcx>), + Ambiguity { + /// Overflow is only `Some(suggest_recursion_limit)` when using the next generation + /// trait solver `-Znext-solver`. With the old solver overflow is eagerly handled by + /// emitting a fatal error instead. + overflow: Option, + }, +} + +impl<'tcx> Debug for FulfillmentErrorCode<'tcx> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + FulfillmentErrorCode::Select(ref e) => write!(f, "{e:?}"), + FulfillmentErrorCode::Project(ref e) => write!(f, "{e:?}"), + FulfillmentErrorCode::Subtype(ref a, ref b) => { + write!(f, "CodeSubtypeError({a:?}, {b:?})") + } + FulfillmentErrorCode::ConstEquate(ref a, ref b) => { + write!(f, "CodeConstEquateError({a:?}, {b:?})") + } + FulfillmentErrorCode::Ambiguity { overflow: None } => write!(f, "Ambiguity"), + FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) } => { + write!(f, "Overflow({suggest_increasing_limit})") + } + FulfillmentErrorCode::Cycle(ref cycle) => write!(f, "Cycle({cycle:?})"), + } + } +} + /// Whether to skip the leak check, as part of a future compatibility warning step. /// /// The "default" for skip-leak-check corresponds to the current @@ -410,7 +482,7 @@ pub fn fully_normalize<'tcx, T>( where T: TypeFoldable>, { - let ocx = ObligationCtxt::new(infcx); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); debug!(?value); let normalized_value = ocx.normalize(&cause, param_env, value); debug!(?normalized_value); diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index d10aee2d4e29..e7ab0b7791c4 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -3,11 +3,13 @@ use super::error_reporting::OverflowCause; use super::error_reporting::TypeErrCtxtExt; use super::SelectionContext; use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer}; +use crate::solve::NextSolverError; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::at::At; use rustc_infer::infer::InferOk; +use rustc_infer::traits::FromSolverError; use rustc_infer::traits::PredicateObligation; -use rustc_infer::traits::{FulfillmentError, Normalized, Obligation, TraitEngine}; +use rustc_infer::traits::{Normalized, Obligation, TraitEngine}; use rustc_macros::extension; use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFolder}; @@ -44,11 +46,15 @@ impl<'tcx> At<'_, 'tcx> { /// existing fulfillment context in the old solver. Once we also eagerly prove goals with /// the old solver or have removed the old solver, remove `traits::fully_normalize` and /// rename this function to `At::fully_normalize`. - fn deeply_normalize>>( + fn deeply_normalize( self, value: T, - fulfill_cx: &mut dyn TraitEngine<'tcx>, - ) -> Result>> { + fulfill_cx: &mut dyn TraitEngine<'tcx, E>, + ) -> Result> + where + T: TypeFoldable>, + E: FromSolverError<'tcx, NextSolverError<'tcx>>, + { if self.infcx.next_trait_solver() { crate::solve::deeply_normalize(self, value) } else { @@ -253,7 +259,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx obligations.len = ?self.obligations.len(), "AssocTypeNormalizer: normalized type" ); - normalized_ty.ty().unwrap() + normalized_ty.expect_type() } ty::Projection => { @@ -283,7 +289,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx ) .ok() .flatten() - .map(|term| term.ty().unwrap()) + .map(|term| term.expect_type()) .map(|normalized_ty| { PlaceholderReplacer::replace_placeholders( infcx, diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index f4051561dae4..08355ef55c49 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -13,7 +13,7 @@ use super::elaborate; use crate::infer::TyCtxtInferExt; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{self, Obligation, ObligationCause}; -use rustc_errors::{FatalError, MultiSpan}; +use rustc_errors::FatalError; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::query::Providers; @@ -23,9 +23,9 @@ use rustc_middle::ty::{ }; use rustc_middle::ty::{GenericArg, GenericArgs}; use rustc_middle::ty::{TypeVisitableExt, Upcast}; -use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; use rustc_span::symbol::Symbol; use rustc_span::Span; +use rustc_target::abi::Abi; use smallvec::SmallVec; use std::iter; @@ -44,7 +44,8 @@ pub fn hir_ty_lowering_object_safety_violations( trait_def_id: DefId, ) -> Vec { debug_assert!(tcx.generics_of(trait_def_id).has_self); - let violations = traits::supertrait_def_ids(tcx, trait_def_id) + let violations = tcx + .supertrait_def_ids(trait_def_id) .map(|def_id| predicates_reference_self(tcx, def_id, true)) .filter(|spans| !spans.is_empty()) .map(ObjectSafetyViolation::SupertraitSelf) @@ -58,50 +59,19 @@ fn object_safety_violations(tcx: TyCtxt<'_>, trait_def_id: DefId) -> &'_ [Object debug!("object_safety_violations: {:?}", trait_def_id); tcx.arena.alloc_from_iter( - traits::supertrait_def_ids(tcx, trait_def_id) + tcx.supertrait_def_ids(trait_def_id) .flat_map(|def_id| object_safety_violations_for_trait(tcx, def_id)), ) } -fn check_is_object_safe(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { - let violations = tcx.object_safety_violations(trait_def_id); - - if violations.is_empty() { - return true; - } - - // If the trait contains any other violations, then let the error reporting path - // report it instead of emitting a warning here. - if violations.iter().all(|violation| { - matches!( - violation, - ObjectSafetyViolation::Method(_, MethodViolationCode::WhereClauseReferencesSelf, _) - ) - }) { - for violation in violations { - if let ObjectSafetyViolation::Method( - _, - MethodViolationCode::WhereClauseReferencesSelf, - span, - ) = violation - { - lint_object_unsafe_trait(tcx, *span, trait_def_id, violation); - } - } - return true; - } - - false +fn is_object_safe(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { + tcx.object_safety_violations(trait_def_id).is_empty() } /// We say a method is *vtable safe* if it can be invoked on a trait /// object. Note that object-safe traits can have some /// non-vtable-safe methods, so long as they require `Self: Sized` or /// otherwise ensure that they cannot be used when `Self = Trait`. -/// -/// [`MethodViolationCode::WhereClauseReferencesSelf`] is considered object safe due to backwards -/// compatibility, see and -/// [`WHERE_CLAUSES_OBJECT_SAFETY`]. pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::AssocItem) -> bool { debug_assert!(tcx.generics_of(trait_def_id).has_self); debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method); @@ -110,9 +80,7 @@ pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::A return false; } - virtual_call_violations_for_method(tcx, trait_def_id, method) - .iter() - .all(|v| matches!(v, MethodViolationCode::WhereClauseReferencesSelf)) + virtual_call_violations_for_method(tcx, trait_def_id, method).is_empty() } fn object_safety_violations_for_trait( @@ -145,6 +113,14 @@ fn object_safety_violations_for_trait( violations.push(ObjectSafetyViolation::SupertraitNonLifetimeBinder(spans)); } + if violations.is_empty() { + for item in tcx.associated_items(trait_def_id).in_definition_order() { + if let ty::AssocKind::Fn = item.kind { + check_receiver_correct(tcx, trait_def_id, *item); + } + } + } + debug!( "object_safety_violations_for_trait(trait_def_id={:?}) = {:?}", trait_def_id, violations @@ -153,47 +129,6 @@ fn object_safety_violations_for_trait( violations } -/// Lint object-unsafe trait. -fn lint_object_unsafe_trait( - tcx: TyCtxt<'_>, - span: Span, - trait_def_id: DefId, - violation: &ObjectSafetyViolation, -) { - // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. - // It's also hard to get a use site span, so we use the method definition span. - tcx.node_span_lint(WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, span, |err| { - err.primary_message(format!( - "the trait `{}` cannot be made into an object", - tcx.def_path_str(trait_def_id) - )); - let node = tcx.hir().get_if_local(trait_def_id); - let mut spans = MultiSpan::from_span(span); - if let Some(hir::Node::Item(item)) = node { - spans.push_span_label(item.ident.span, "this trait cannot be made into an object..."); - spans.push_span_label(span, format!("...because {}", violation.error_msg())); - } else { - spans.push_span_label( - span, - format!( - "the trait cannot be made into an object because {}", - violation.error_msg() - ), - ); - }; - err.span_note( - spans, - "for a trait to be \"object safe\" it needs to allow building a vtable to allow the \ - call to be resolvable dynamically; for more information visit \ - ", - ); - if node.is_some() { - // Only provide the help if its a local trait, otherwise it's not - violation.solution().add_to(err); - } - }); -} - fn sized_trait_bound_spans<'tcx>( tcx: TyCtxt<'tcx>, bounds: hir::GenericBounds<'tcx>, @@ -493,59 +428,8 @@ fn virtual_call_violations_for_method<'tcx>( }; errors.push(MethodViolationCode::UndispatchableReceiver(span)); } else { - // Do sanity check to make sure the receiver actually has the layout of a pointer. - - use rustc_target::abi::Abi; - - let param_env = tcx.param_env(method.def_id); - - let abi_of_ty = |ty: Ty<'tcx>| -> Option { - match tcx.layout_of(param_env.and(ty)) { - Ok(layout) => Some(layout.abi), - Err(err) => { - // #78372 - tcx.dcx().span_delayed_bug( - tcx.def_span(method.def_id), - format!("error: {err}\n while computing layout for type {ty:?}"), - ); - None - } - } - }; - - // e.g., `Rc<()>` - let unit_receiver_ty = - receiver_for_self_ty(tcx, receiver_ty, tcx.types.unit, method.def_id); - - match abi_of_ty(unit_receiver_ty) { - Some(Abi::Scalar(..)) => (), - abi => { - tcx.dcx().span_delayed_bug( - tcx.def_span(method.def_id), - format!( - "receiver when `Self = ()` should have a Scalar ABI; found {abi:?}" - ), - ); - } - } - - let trait_object_ty = object_ty_for_trait(tcx, trait_def_id, tcx.lifetimes.re_static); - - // e.g., `Rc` - let trait_object_receiver = - receiver_for_self_ty(tcx, receiver_ty, trait_object_ty, method.def_id); - - match abi_of_ty(trait_object_receiver) { - Some(Abi::ScalarPair(..)) => (), - abi => { - tcx.dcx().span_delayed_bug( - tcx.def_span(method.def_id), - format!( - "receiver when `Self = {trait_object_ty}` should have a ScalarPair ABI; found {abi:?}" - ), - ); - } - } + // We confirm that the `receiver_is_dispatchable` is accurate later, + // see `check_receiver_correct`. It should be kept in sync with this code. } } @@ -606,6 +490,55 @@ fn virtual_call_violations_for_method<'tcx>( errors } +/// This code checks that `receiver_is_dispatchable` is correctly implemented. +/// +/// This check is outlined from the object safety check to avoid cycles with +/// layout computation, which relies on knowing whether methods are object safe. +pub fn check_receiver_correct<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, method: ty::AssocItem) { + if !is_vtable_safe_method(tcx, trait_def_id, method) { + return; + } + + let method_def_id = method.def_id; + let sig = tcx.fn_sig(method_def_id).instantiate_identity(); + let param_env = tcx.param_env(method_def_id); + let receiver_ty = tcx.liberate_late_bound_regions(method_def_id, sig.input(0)); + + if receiver_ty == tcx.types.self_param { + // Assumed OK, may change later if unsized_locals permits `self: Self` as dispatchable. + return; + } + + // e.g., `Rc<()>` + let unit_receiver_ty = receiver_for_self_ty(tcx, receiver_ty, tcx.types.unit, method_def_id); + match tcx.layout_of(param_env.and(unit_receiver_ty)).map(|l| l.abi) { + Ok(Abi::Scalar(..)) => (), + abi => { + tcx.dcx().span_delayed_bug( + tcx.def_span(method_def_id), + format!("receiver {unit_receiver_ty:?} when `Self = ()` should have a Scalar ABI; found {abi:?}"), + ); + } + } + + let trait_object_ty = object_ty_for_trait(tcx, trait_def_id, tcx.lifetimes.re_static); + + // e.g., `Rc` + let trait_object_receiver = + receiver_for_self_ty(tcx, receiver_ty, trait_object_ty, method_def_id); + match tcx.layout_of(param_env.and(trait_object_receiver)).map(|l| l.abi) { + Ok(Abi::ScalarPair(..)) => (), + abi => { + tcx.dcx().span_delayed_bug( + tcx.def_span(method_def_id), + format!( + "receiver {trait_object_receiver:?} when `Self = {trait_object_ty}` should have a ScalarPair ABI; found {abi:?}" + ), + ); + } + } +} + /// Performs a type instantiation to produce the version of `receiver_ty` when `Self = self_ty`. /// For example, for `receiver_ty = Rc` and `self_ty = Foo`, returns `Rc`. fn receiver_for_self_ty<'tcx>( @@ -921,7 +854,7 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>( pub fn provide(providers: &mut Providers) { *providers = Providers { object_safety_violations, - check_is_object_safe, + is_object_safe, generics_require_sized_self, ..*providers }; diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index b6557e6c4eb3..501d9c9266e6 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1560,7 +1560,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( let destructor_def_id = tcx.associated_item_def_ids(trait_def_id)[0]; assert_eq!(destructor_def_id, item_def_id); - (self_ty.async_destructor_ty(tcx, obligation.param_env).into(), Vec::new()) + (self_ty.async_destructor_ty(tcx).into(), Vec::new()) } else if lang_items.pointee_trait() == Some(trait_def_id) { let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); assert_eq!(metadata_def_id, item_def_id); diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 1b5ffeebc01f..e170d7cae937 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -8,11 +8,11 @@ use crate::infer::{InferCtxt, InferOk}; use crate::traits::error_reporting::OverflowCause; use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::normalize::needs_normalization; -use crate::traits::{BoundVarReplacer, PlaceholderReplacer}; +use crate::traits::Normalized; +use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError}; use crate::traits::{ObligationCause, PredicateObligation, Reveal}; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_infer::traits::Normalized; use rustc_macros::extension; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; @@ -76,7 +76,9 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { }; if self.infcx.next_trait_solver() { - match crate::solve::deeply_normalize_with_skipped_universes(self, value, universes) { + match crate::solve::deeply_normalize_with_skipped_universes::<_, ScrubbedTraitError<'tcx>>( + self, value, universes, + ) { Ok(value) => return Ok(Normalized { value, obligations: vec![] }), Err(_errors) => { return Err(NoSolution); 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 00cc77e71e72..b38841db9233 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 @@ -1,4 +1,3 @@ -use crate::solve; use crate::traits::query::NoSolution; use crate::traits::wf; use crate::traits::ObligationCtxt; @@ -262,11 +261,9 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>( let mut ty_a = ocx.infcx.resolve_vars_if_possible(ty_a); // Need to manually normalize in the new solver as `wf::obligations` does not. if ocx.infcx.next_trait_solver() { - ty_a = solve::deeply_normalize( - ocx.infcx.at(&ObligationCause::dummy(), param_env), - ty_a, - ) - .map_err(|_errs| NoSolution)?; + ty_a = ocx + .deeply_normalize(&ObligationCause::dummy(), param_env, ty_a) + .map_err(|_| NoSolution)?; } let mut components = smallvec![]; push_outlives_components(tcx, ty_a, &mut components); diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index fd7c47ad6fb3..4d3aa067c6c5 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -870,7 +870,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let Some(principal) = data.principal() { if !self.infcx.tcx.features().object_safe_for_dispatch { principal.with_self_ty(self.tcx(), self_ty) - } else if self.tcx().check_is_object_safe(principal.def_id()) { + } else if self.tcx().is_object_safe(principal.def_id()) { principal.with_self_ty(self.tcx(), self_ty) } else { return; @@ -946,7 +946,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // since we don't actually use them. &mut vec![], ) - .ty() + .as_type() .unwrap(); if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None } @@ -1004,7 +1004,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let a_auto_traits: FxIndexSet = a_data .auto_traits() .chain(principal_def_id_a.into_iter().flat_map(|principal_def_id| { - util::supertrait_def_ids(self.tcx(), principal_def_id) + self.tcx() + .supertrait_def_ids(principal_def_id) .filter(|def_id| self.tcx().trait_is_auto(*def_id)) })) .collect(); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index c684f087d321..ef0d8735d35f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1222,7 +1222,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // `T` -> `Trait` (_, &ty::Dynamic(data, r, ty::Dyn)) => { let mut object_dids = data.auto_traits().chain(data.principal_def_id()); - if let Some(did) = object_dids.find(|did| !tcx.check_is_object_safe(*did)) { + if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) { return Err(TraitNotObjectSafe(did)); } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7aec4e1987ed..2489b8916d18 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -798,7 +798,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::PredicateKind::ObjectSafe(trait_def_id) => { - if self.tcx().check_is_object_safe(trait_def_id) { + if self.tcx().is_object_safe(trait_def_id) { Ok(EvaluatedToOk) } else { Ok(EvaluatedToErr) @@ -995,10 +995,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig), ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { + // FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant + // other than `ConstKind::Value`. Unfortunately this would require looking in the + // env for any `ConstArgHasType` assumptions for parameters and placeholders. I + // don't really want to implement this in the old solver so I haven't. + // + // We do still stall on infer vars though as otherwise a goal like: + // `ConstArgHasType(?x: usize, usize)` can succeed even though it might later + // get unified with some const that is not of type `usize`. + let ct = self.infcx.shallow_resolve_const(ct); + let ct_ty = match ct.kind() { + ty::ConstKind::Infer(ty::InferConst::Var(_)) => { + return Ok(EvaluatedToAmbig); + } + ty::ConstKind::Error(_) => return Ok(EvaluatedToOk), + _ => ct.ty(), + }; + match self.infcx.at(&obligation.cause, obligation.param_env).eq( // Only really excercised by generic_const_exprs DefineOpaqueTypes::Yes, - ct.ty(), + ct_ty, ty, ) { Ok(inf_ok) => self.evaluate_predicates_recursively( @@ -2574,8 +2591,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let a_auto_traits: FxIndexSet = a_data .auto_traits() .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| { - util::supertrait_def_ids(tcx, principal_def_id) - .filter(|def_id| tcx.trait_is_auto(*def_id)) + tcx.supertrait_def_ids(principal_def_id).filter(|def_id| tcx.trait_is_auto(*def_id)) })) .collect(); diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index 96a06e0c1691..9d657ade86bf 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -1,5 +1,5 @@ use rustc_infer::infer::at::At; -use rustc_infer::traits::{FulfillmentError, TraitEngine}; +use rustc_infer::traits::TraitEngine; use rustc_macros::extension; use rustc_middle::ty::{self, Ty}; @@ -7,11 +7,11 @@ use crate::traits::{NormalizeExt, Obligation}; #[extension(pub trait StructurallyNormalizeExt<'tcx>)] impl<'tcx> At<'_, 'tcx> { - fn structurally_normalize( + fn structurally_normalize( &self, ty: Ty<'tcx>, - fulfill_cx: &mut dyn TraitEngine<'tcx>, - ) -> Result, Vec>> { + fulfill_cx: &mut dyn TraitEngine<'tcx, E>, + ) -> Result, Vec> { assert!(!ty.is_ty_var(), "should have resolved vars before calling"); if self.infcx.next_trait_solver() { diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 445fa1761b9f..5d5a22e189ce 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use super::NormalizeExt; use super::{ObligationCause, PredicateObligation, SelectionContext}; -use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; +use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Diag; use rustc_hir::def_id::DefId; use rustc_infer::infer::{InferCtxt, InferOk}; @@ -161,43 +161,6 @@ impl<'tcx> Iterator for TraitAliasExpander<'tcx> { } } -/////////////////////////////////////////////////////////////////////////// -// Iterator over def-IDs of supertraits -/////////////////////////////////////////////////////////////////////////// - -pub struct SupertraitDefIds<'tcx> { - tcx: TyCtxt<'tcx>, - stack: Vec, - visited: FxHashSet, -} - -pub fn supertrait_def_ids(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SupertraitDefIds<'_> { - SupertraitDefIds { - tcx, - stack: vec![trait_def_id], - visited: Some(trait_def_id).into_iter().collect(), - } -} - -impl Iterator for SupertraitDefIds<'_> { - type Item = DefId; - - fn next(&mut self) -> Option { - let def_id = self.stack.pop()?; - let predicates = self.tcx.super_predicates_of(def_id); - let visited = &mut self.visited; - self.stack.extend( - predicates - .predicates - .iter() - .filter_map(|(pred, _)| pred.as_trait_clause()) - .map(|trait_ref| trait_ref.def_id()) - .filter(|&super_def_id| visited.insert(super_def_id)), - ); - Some(def_id) - } -} - /////////////////////////////////////////////////////////////////////////// // Other /////////////////////////////////////////////////////////////////////////// @@ -295,7 +258,7 @@ pub fn coroutine_trait_ref_and_outputs<'tcx>( tcx: TyCtxt<'tcx>, fn_trait_def_id: DefId, self_ty: Ty<'tcx>, - sig: ty::GenSig<'tcx>, + sig: ty::GenSig>, ) -> (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>) { assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef::new(tcx, fn_trait_def_id, [self_ty, sig.resume_ty]); @@ -306,7 +269,7 @@ pub fn future_trait_ref_and_outputs<'tcx>( tcx: TyCtxt<'tcx>, fn_trait_def_id: DefId, self_ty: Ty<'tcx>, - sig: ty::GenSig<'tcx>, + sig: ty::GenSig>, ) -> (ty::TraitRef<'tcx>, Ty<'tcx>) { assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef::new(tcx, fn_trait_def_id, [self_ty]); @@ -317,7 +280,7 @@ pub fn iterator_trait_ref_and_outputs<'tcx>( tcx: TyCtxt<'tcx>, iterator_def_id: DefId, self_ty: Ty<'tcx>, - sig: ty::GenSig<'tcx>, + sig: ty::GenSig>, ) -> (ty::TraitRef<'tcx>, Ty<'tcx>) { assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef::new(tcx, iterator_def_id, [self_ty]); @@ -328,7 +291,7 @@ pub fn async_iterator_trait_ref_and_outputs<'tcx>( tcx: TyCtxt<'tcx>, async_iterator_def_id: DefId, self_ty: Ty<'tcx>, - sig: ty::GenSig<'tcx>, + sig: ty::GenSig>, ) -> (ty::TraitRef<'tcx>, Ty<'tcx>) { assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef::new(tcx, async_iterator_def_id, [self_ty]); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index f4189ff09020..066755f7b3e7 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -286,7 +286,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( // implemented, but rather from a "second order" obligation, where an associated // type has a projection coming from another associated type. // See `tests/ui/traits/assoc-type-in-superbad.rs` for an example. - if let Some(term_ty) = proj.term.ty() + if let Some(term_ty) = proj.term.as_type() && let Some(impl_item_span) = ty_to_impl_span(term_ty) { cause.span = impl_item_span; diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index b96b1b67a740..c73ececd1d15 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -4,13 +4,13 @@ // general routines. use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::FulfillmentErrorCode; use rustc_middle::bug; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::{ - ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext, Unimplemented, + ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext, + Unimplemented, }; use tracing::debug; @@ -50,6 +50,7 @@ pub fn codegen_select_candidate<'tcx>( // Currently, we use a fulfillment context to completely resolve // all nested obligations. This is because they can inform the // inference of the impl's type parameters. + // FIXME(-Znext-solver): Doesn't need diagnostics if new solver. let ocx = ObligationCtxt::new(&infcx); let impl_source = selection.map(|obligation| { ocx.register_obligation(obligation); @@ -64,7 +65,7 @@ pub fn codegen_select_candidate<'tcx>( // Cycle errors are the only post-monomorphization errors possible; emit them now so // `rustc_ty_utils::resolve_associated_item` doesn't return `None` post-monomorphization. for err in errors { - if let FulfillmentErrorCode::Cycle(cycle) = err.code { + if let ScrubbedTraitError::Cycle(cycle) = err { infcx.err_ctxt().report_overflow_obligation_cycle(&cycle); } } diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index fee13078250f..0430e0bb70eb 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -7,9 +7,7 @@ use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::query::{ normalize::NormalizationResult, CanonicalAliasGoal, NoSolution, }; -use rustc_trait_selection::traits::{ - self, FulfillmentErrorCode, ObligationCause, SelectionContext, -}; +use rustc_trait_selection::traits::{self, ObligationCause, ScrubbedTraitError, SelectionContext}; use tracing::debug; pub(crate) fn provide(p: &mut Providers) { @@ -49,7 +47,7 @@ fn normalize_canonicalized_projection_ty<'tcx>( // that impl vars are constrained by the signature, for example). if !tcx.sess.opts.actually_rustdoc { for error in &errors { - if let FulfillmentErrorCode::Cycle(cycle) = &error.code { + if let ScrubbedTraitError::Cycle(cycle) = &error { ocx.infcx.err_ctxt().report_overflow_obligation_cycle(cycle); } } @@ -60,7 +58,7 @@ fn normalize_canonicalized_projection_ty<'tcx>( // FIXME(associated_const_equality): All users of normalize_canonicalized_projection_ty // expected a type, but there is the possibility it could've been a const now. // Maybe change it to a Term later? - Ok(NormalizationResult { normalized_ty: answer.ty().unwrap() }) + Ok(NormalizationResult { normalized_ty: answer.expect_type() }) }, ) } diff --git a/compiler/rustc_ty_utils/src/common_traits.rs b/compiler/rustc_ty_utils/src/common_traits.rs index cb95239e9919..51b908881eb4 100644 --- a/compiler/rustc_ty_utils/src/common_traits.rs +++ b/compiler/rustc_ty_utils/src/common_traits.rs @@ -22,17 +22,6 @@ fn is_unpin_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) is_item_raw(tcx, query, LangItem::Unpin) } -fn has_surface_async_drop_raw<'tcx>( - tcx: TyCtxt<'tcx>, - query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, -) -> bool { - is_item_raw(tcx, query, LangItem::AsyncDrop) -} - -fn has_surface_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - is_item_raw(tcx, query, LangItem::Drop) -} - fn is_item_raw<'tcx>( tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, @@ -45,13 +34,5 @@ fn is_item_raw<'tcx>( } pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { - is_copy_raw, - is_sized_raw, - is_freeze_raw, - is_unpin_raw, - has_surface_async_drop_raw, - has_surface_drop_raw, - ..*providers - }; + *providers = Providers { is_copy_raw, is_sized_raw, is_freeze_raw, is_unpin_raw, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index e9112d232cbd..8a42298f2164 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -148,17 +148,24 @@ fn recurse_build<'tcx>( for &id in args.iter() { new_args.push(recurse_build(tcx, body, id, root_span)?); } - let new_args = tcx.mk_const_list(&new_args); - ty::Const::new_expr(tcx, Expr::FunctionCall(fun, new_args), node.ty) + ty::Const::new_expr( + tcx, + Expr::new_call(tcx, fun.ty(), fun, new_args.into_iter()), + node.ty, + ) } &ExprKind::Binary { op, lhs, rhs } if check_binop(op) => { let lhs = recurse_build(tcx, body, lhs, root_span)?; let rhs = recurse_build(tcx, body, rhs, root_span)?; - ty::Const::new_expr(tcx, Expr::Binop(op, lhs, rhs), node.ty) + ty::Const::new_expr( + tcx, + Expr::new_binop(tcx, op, lhs.ty(), rhs.ty(), lhs, rhs), + node.ty, + ) } &ExprKind::Unary { op, arg } if check_unop(op) => { let arg = recurse_build(tcx, body, arg, root_span)?; - ty::Const::new_expr(tcx, Expr::UnOp(op, arg), node.ty) + ty::Const::new_expr(tcx, Expr::new_unop(tcx, op, arg.ty(), arg), node.ty) } // This is necessary so that the following compiles: // @@ -178,12 +185,22 @@ fn recurse_build<'tcx>( // "coercion cast" i.e. using a coercion or is a no-op. // This is important so that `N as usize as usize` doesn't unify with `N as usize`. (untested) &ExprKind::Use { source } => { - let arg = recurse_build(tcx, body, source, root_span)?; - ty::Const::new_expr(tcx, Expr::Cast(CastKind::Use, arg, node.ty), node.ty) + let value_ty = body.exprs[source].ty; + let value = recurse_build(tcx, body, source, root_span)?; + ty::Const::new_expr( + tcx, + Expr::new_cast(tcx, CastKind::Use, value_ty, value, node.ty), + node.ty, + ) } &ExprKind::Cast { source } => { - let arg = recurse_build(tcx, body, source, root_span)?; - ty::Const::new_expr(tcx, Expr::Cast(CastKind::As, arg, node.ty), node.ty) + let value_ty = body.exprs[source].ty; + let value = recurse_build(tcx, body, source, root_span)?; + ty::Const::new_expr( + tcx, + Expr::new_cast(tcx, CastKind::As, value_ty, value, node.ty), + node.ty, + ) } ExprKind::Borrow { arg, .. } => { let arg_node = &body.exprs[*arg]; diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 0d089205c1ec..e4dcea785d41 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -4,6 +4,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::traits::{BuiltinImplSource, CodegenObligationError}; +use rustc_middle::ty::util::AsyncDropGlueMorphology; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitableExt}; use rustc_span::sym; @@ -59,7 +60,7 @@ fn resolve_instance<'tcx>( } else if Some(def_id) == tcx.lang_items().async_drop_in_place_fn() { let ty = args.type_at(0); - if !ty.is_async_destructor_noop(tcx, param_env) { + if ty.async_drop_glue_morphology(tcx) != AsyncDropGlueMorphology::Noop { match *ty.kind() { ty::Closure(..) | ty::CoroutineClosure(..) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 1dee14fae57e..6045abc50a9d 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -10,7 +10,8 @@ use rustc_middle::ty::layout::{ }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, AdtDef, EarlyBinder, FieldDef, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, + self, AdtDef, CoroutineArgsExt, EarlyBinder, FieldDef, GenericArgsRef, Ty, TyCtxt, + TypeVisitableExt, }; use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use rustc_span::sym; diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 72ee1a482495..205b3f2760f3 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -30,6 +30,21 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx> res } +fn needs_async_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { + // If we don't know a type doesn't need async drop, for example if it's a + // type parameter without a `Copy` bound, then we conservatively return that + // it needs async drop. + let adt_has_async_dtor = + |adt_def: ty::AdtDef<'tcx>| adt_def.async_destructor(tcx).map(|_| DtorType::Significant); + let res = drop_tys_helper(tcx, query.value, query.param_env, adt_has_async_dtor, false) + .filter(filter_array_elements(tcx, query.param_env)) + .next() + .is_some(); + + debug!("needs_drop_raw({:?}) = {:?}", query, res); + res +} + /// HACK: in order to not mistakenly assume that `[PhantomData; N]` requires drop glue /// we check the element type for drop glue. The correct fix would be looking at the /// entirety of the code around `needs_drop_components` and this file and come up with @@ -389,6 +404,7 @@ fn adt_significant_drop_tys( pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { needs_drop_raw, + needs_async_drop_raw, has_significant_drop_raw, adt_drop_tys, adt_significant_drop_tys, diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index ccc522053a65..686f2f04ad9a 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -109,7 +109,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { #[instrument(level = "trace", skip(self))] fn collect_taits_declared_in_body(&mut self) { - let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(self.item)).value; + let body = self.tcx.hir().body_owned_by(self.item).value; struct TaitInBodyFinder<'a, 'tcx> { collector: &'a mut OpaqueTypeCollector<'tcx>, } diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index e50d59ba5f0e..9a2c9059967b 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -8,11 +8,12 @@ use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_serialize::Decodable; use tracing::debug; +use crate::debug::{DebugWithInfcx, WithInfcx}; use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::inherent::*; use crate::lift::Lift; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::{self as ty, Interner, SsoHashSet}; +use crate::{self as ty, InferCtxtLike, Interner, SsoHashSet}; /// Binder is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` @@ -55,6 +56,18 @@ where } } +impl> DebugWithInfcx for ty::Binder { + fn fmt>( + this: WithInfcx<'_, Infcx, &Self>, + f: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + f.debug_tuple("Binder") + .field(&this.map(|data| data.as_ref().skip_binder())) + .field(&this.data.bound_vars()) + .finish() + } +} + macro_rules! impl_binder_encode_decode { ($($t:ty),+ $(,)?) => { $( diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 7b1dfecfee2e..f305ed9b5d77 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -9,7 +9,7 @@ use std::ops::Deref; use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; -use crate::{self as ty, DebugWithInfcx, Interner, UpcastFrom}; +use crate::{self as ty, CollectAndApply, DebugWithInfcx, Interner, UpcastFrom}; pub trait Ty>: Copy @@ -34,6 +34,21 @@ pub trait Ty>: fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self; fn new_alias(interner: I, kind: ty::AliasTyKind, alias_ty: ty::AliasTy) -> Self; + + fn new_coroutine(interner: I, def_id: I::DefId, args: I::GenericArgs) -> Self; + + fn new_tup_from_iter(interner: I, iter: It) -> T::Output + where + It: Iterator, + T: CollectAndApply; + + fn tuple_fields(self) -> I::Tys; + + fn to_opt_closure_kind(self) -> Option; + + fn from_closure_kind(interner: I, kind: ty::ClosureKind) -> Self; + + fn from_coroutine_closure_kind(interner: I, kind: ty::ClosureKind) -> Self; } pub trait Tys>: @@ -43,17 +58,18 @@ pub trait Tys>: + Eq + IntoIterator + Deref> - + TypeVisitable + + TypeFoldable + + Default { fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty); } -pub trait Abi>: Copy + Debug + Hash + Eq { +pub trait Abi>: Copy + Debug + Hash + Eq + TypeVisitable { /// Whether this ABI is `extern "Rust"`. fn is_rust(self) -> bool; } -pub trait Safety>: Copy + Debug + Hash + Eq { +pub trait Safety>: Copy + Debug + Hash + Eq + TypeVisitable { fn is_safe(self) -> bool; fn prefix_str(self) -> &'static str; @@ -129,6 +145,10 @@ pub trait GenericArgs>: def_id: I::DefId, original_args: &[I::GenericArg], ) -> I::GenericArgs; + + fn split_closure_args(self) -> ty::ClosureArgsParts; + fn split_coroutine_closure_args(self) -> ty::CoroutineClosureArgsParts; + fn split_coroutine_args(self) -> ty::CoroutineArgsParts; } pub trait Predicate>: diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 2a228c973d34..6ebb434299b3 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -29,9 +29,7 @@ pub trait Interner: type AdtDef: Copy + Debug + Hash + Eq; type GenericArgs: GenericArgs; - /// The slice of args for a specific item. For a GAT like `type Foo<'a>`, it will be `['a]`, - /// not including the args from the parent item (trait or impl). - type OwnItemArgs: Copy + Debug + Hash + Eq; + type GenericArgsSlice: Copy + Debug + Hash + Eq + Deref; type GenericArg: Copy + DebugWithInfcx + Hash @@ -69,7 +67,6 @@ pub trait Interner: // Things stored inside of tys type ErrorGuaranteed: Copy + Debug + Hash + Eq; type BoundExistentialPredicates: Copy + DebugWithInfcx + Hash + Eq; - type PolyFnSig: Copy + DebugWithInfcx + Hash + Eq; type AllocId: Copy + Debug + Hash + Eq; type Pat: Copy + Debug + Hash + Eq + DebugWithInfcx; type Safety: Safety; @@ -112,7 +109,7 @@ pub trait Interner: self, def_id: Self::DefId, args: Self::GenericArgs, - ) -> (ty::TraitRef, Self::OwnItemArgs); + ) -> (ty::TraitRef, Self::GenericArgsSlice); fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs; fn mk_args_from_iter(self, args: impl Iterator) -> Self::GenericArgs; diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 48a6f79993cc..e7039583c91c 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -604,7 +604,7 @@ impl AliasTerm { /// For example, if this is a projection of `::Item<'a>`, /// then this function would return a `T: StreamingIterator` trait reference and /// `['a]` as the own args. - pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef, I::OwnItemArgs) { + pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef, I::GenericArgsSlice) { interner.trait_ref_and_own_args_for_alias(self.def_id, self.args) } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 38082bf3c16f..71f3862226d8 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -1,19 +1,21 @@ #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] -use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; +use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; use std::fmt; +pub use self::closure::*; +use self::TyKind::*; use crate::inherent::*; use crate::{self as ty, DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx}; -use self::TyKind::*; - use rustc_ast_ir::Mutability; +mod closure; + /// Specifies how a trait object is represented. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] @@ -141,7 +143,7 @@ pub enum TyKind { /// fn foo() -> i32 { 1 } /// let bar: fn() -> i32 = foo; /// ``` - FnPtr(I::PolyFnSig), + FnPtr(ty::Binder>), /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`. Dynamic(I::BoundExistentialPredicates, I::Region, DynKind), @@ -514,7 +516,7 @@ impl AliasTy { /// For example, if this is a projection of `::Item<'a>`, /// then this function would return a `T: StreamingIterator` trait reference and /// `['a]` as the own args. - pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef, I::OwnItemArgs) { + pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef, I::GenericArgsSlice) { debug_assert_eq!(self.kind(interner), AliasTyKind::Projection); interner.trait_ref_and_own_args_for_alias(self.def_id, self.args) } @@ -715,14 +717,44 @@ impl FloatTy { } } -#[derive(Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum IntVarValue { + Unknown, IntType(IntTy), UintType(UintTy), } -#[derive(Clone, Copy, PartialEq, Eq)] -pub struct FloatVarValue(pub FloatTy); +impl IntVarValue { + pub fn is_known(self) -> bool { + match self { + IntVarValue::IntType(_) | IntVarValue::UintType(_) => true, + IntVarValue::Unknown => false, + } + } + + pub fn is_unknown(self) -> bool { + !self.is_known() + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum FloatVarValue { + Unknown, + Known(FloatTy), +} + +impl FloatVarValue { + pub fn is_known(self) -> bool { + match self { + FloatVarValue::Known(_) => true, + FloatVarValue::Unknown => false, + } + } + + pub fn is_unknown(self) -> bool { + !self.is_known() + } +} rustc_index::newtype_index! { /// A **ty**pe **v**ariable **ID**. @@ -807,11 +839,28 @@ impl UnifyKey for TyVid { } #[cfg(feature = "nightly")] -impl EqUnifyValue for IntVarValue {} +impl UnifyValue for IntVarValue { + type Error = NoError; + + fn unify_values(value1: &Self, value2: &Self) -> Result { + match (*value1, *value2) { + (IntVarValue::Unknown, IntVarValue::Unknown) => Ok(IntVarValue::Unknown), + ( + IntVarValue::Unknown, + known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)), + ) + | ( + known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)), + IntVarValue::Unknown, + ) => Ok(known), + _ => panic!("differing ints should have been resolved first"), + } + } +} #[cfg(feature = "nightly")] impl UnifyKey for IntVid { - type Value = Option; + type Value = IntVarValue; #[inline] // make this function eligible for inlining - it is quite hot. fn index(&self) -> u32 { self.as_u32() @@ -826,11 +875,26 @@ impl UnifyKey for IntVid { } #[cfg(feature = "nightly")] -impl EqUnifyValue for FloatVarValue {} +impl UnifyValue for FloatVarValue { + type Error = NoError; + + fn unify_values(value1: &Self, value2: &Self) -> Result { + match (*value1, *value2) { + (FloatVarValue::Unknown, FloatVarValue::Unknown) => Ok(FloatVarValue::Unknown), + (FloatVarValue::Unknown, FloatVarValue::Known(known)) + | (FloatVarValue::Known(known), FloatVarValue::Unknown) => { + Ok(FloatVarValue::Known(known)) + } + (FloatVarValue::Known(_), FloatVarValue::Known(_)) => { + panic!("differing floats should have been resolved first") + } + } + } +} #[cfg(feature = "nightly")] impl UnifyKey for FloatVid { - type Value = Option; + type Value = FloatVarValue; #[inline] fn index(&self) -> u32 { self.as_u32() @@ -858,21 +922,6 @@ impl HashStable for InferTy { } } -impl fmt::Debug for IntVarValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - IntVarValue::IntType(ref v) => v.fmt(f), - IntVarValue::UintType(ref v) => v.fmt(f), - } - } -} - -impl fmt::Debug for FloatVarValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - impl fmt::Display for InferTy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use InferTy::*; diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs new file mode 100644 index 000000000000..97752934632c --- /dev/null +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -0,0 +1,696 @@ +use std::ops::ControlFlow; + +use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; + +use crate::fold::{shift_region, TypeFoldable, TypeFolder, TypeSuperFoldable}; +use crate::inherent::*; +use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use crate::{self as ty, Interner}; + +/// A closure can be modeled as a struct that looks like: +/// ```ignore (illustrative) +/// struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U); +/// ``` +/// where: +/// +/// - 'l0...'li and T0...Tj are the generic parameters +/// in scope on the function that defined the closure, +/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This +/// is rather hackily encoded via a scalar type. See +/// `Ty::to_opt_closure_kind` for details. +/// - CS represents the *closure signature*, representing as a `fn()` +/// type. For example, `fn(u32, u32) -> u32` would mean that the closure +/// implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait +/// specified above. +/// - U is a type parameter representing the types of its upvars, tupled up +/// (borrowed, if appropriate; that is, if a U field represents a by-ref upvar, +/// and the up-var has the type `Foo`, then that field of U will be `&Foo`). +/// +/// So, for example, given this function: +/// ```ignore (illustrative) +/// fn foo<'a, T>(data: &'a mut T) { +/// do(|| data.count += 1) +/// } +/// ``` +/// the type of the closure would be something like: +/// ```ignore (illustrative) +/// struct Closure<'a, T, U>(...U); +/// ``` +/// Note that the type of the upvar is not specified in the struct. +/// You may wonder how the impl would then be able to use the upvar, +/// if it doesn't know it's type? The answer is that the impl is +/// (conceptually) not fully generic over Closure but rather tied to +/// instances with the expected upvar types: +/// ```ignore (illustrative) +/// impl<'b, 'a, T> FnMut() for Closure<'a, T, (&'b mut &'a mut T,)> { +/// ... +/// } +/// ``` +/// You can see that the *impl* fully specified the type of the upvar +/// and thus knows full well that `data` has type `&'b mut &'a mut T`. +/// (Here, I am assuming that `data` is mut-borrowed.) +/// +/// Now, the last question you may ask is: Why include the upvar types +/// in an extra type parameter? The reason for this design is that the +/// upvar types can reference lifetimes that are internal to the +/// creating function. In my example above, for example, the lifetime +/// `'b` represents the scope of the closure itself; this is some +/// subset of `foo`, probably just the scope of the call to the to +/// `do()`. If we just had the lifetime/type parameters from the +/// enclosing function, we couldn't name this lifetime `'b`. Note that +/// there can also be lifetimes in the types of the upvars themselves, +/// if one of them happens to be a reference to something that the +/// creating fn owns. +/// +/// OK, you say, so why not create a more minimal set of parameters +/// that just includes the extra lifetime parameters? The answer is +/// primarily that it would be hard --- we don't know at the time when +/// we create the closure type what the full types of the upvars are, +/// nor do we know which are borrowed and which are not. In this +/// design, we can just supply a fresh type parameter and figure that +/// out later. +/// +/// All right, you say, but why include the type parameters from the +/// original function then? The answer is that codegen may need them +/// when monomorphizing, and they may not appear in the upvars. A +/// closure could capture no variables but still make use of some +/// in-scope type parameter with a bound (e.g., if our example above +/// had an extra `U: Default`, and the closure called `U::default()`). +/// +/// There is another reason. This design (implicitly) prohibits +/// closures from capturing themselves (except via a trait +/// object). This simplifies closure inference considerably, since it +/// means that when we infer the kind of a closure or its upvars, we +/// don't have to handle cycles where the decisions we make for +/// closure C wind up influencing the decisions we ought to make for +/// closure C (which would then require fixed point iteration to +/// handle). Plus it fixes an ICE. :P +/// +/// ## Coroutines +/// +/// Coroutines are handled similarly in `CoroutineArgs`. The set of +/// type parameters is similar, but `CK` and `CS` are replaced by the +/// following type parameters: +/// +/// * `GS`: The coroutine's "resume type", which is the type of the +/// argument passed to `resume`, and the type of `yield` expressions +/// inside the coroutine. +/// * `GY`: The "yield type", which is the type of values passed to +/// `yield` inside the coroutine. +/// * `GR`: The "return type", which is the type of value returned upon +/// completion of the coroutine. +/// * `GW`: The "coroutine witness". +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +pub struct ClosureArgs { + /// Lifetime and type parameters from the enclosing function, + /// concatenated with a tuple containing the types of the upvars. + /// + /// These are separated out because codegen wants to pass them around + /// when monomorphizing. + pub args: I::GenericArgs, +} + +/// Struct returned by `split()`. +pub struct ClosureArgsParts { + /// This is the args of the typeck root. + pub parent_args: I::GenericArgsSlice, + /// Represents the maximum calling capability of the closure. + pub closure_kind_ty: I::Ty, + /// Captures the closure's signature. This closure signature is "tupled", and + /// thus has a peculiar signature of `extern "rust-call" fn((Args, ...)) -> Ty`. + pub closure_sig_as_fn_ptr_ty: I::Ty, + /// The upvars captured by the closure. Remains an inference variable + /// until the upvar analysis, which happens late in HIR typeck. + pub tupled_upvars_ty: I::Ty, +} + +impl ClosureArgs { + /// Construct `ClosureArgs` from `ClosureArgsParts`, containing `Args` + /// for the closure parent, alongside additional closure-specific components. + pub fn new(tcx: I, parts: ClosureArgsParts) -> ClosureArgs { + ClosureArgs { + args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ + parts.closure_kind_ty.into(), + parts.closure_sig_as_fn_ptr_ty.into(), + parts.tupled_upvars_ty.into(), + ])), + } + } + + /// Divides the closure args into their respective components. + /// The ordering assumed here must match that used by `ClosureArgs::new` above. + fn split(self) -> ClosureArgsParts { + self.args.split_closure_args() + } + + /// Returns the generic parameters of the closure's parent. + pub fn parent_args(self) -> I::GenericArgsSlice { + self.split().parent_args + } + + /// Returns an iterator over the list of types of captured paths by the closure. + /// In case there was a type error in figuring out the types of the captured path, an + /// empty iterator is returned. + #[inline] + pub fn upvar_tys(self) -> I::Tys { + match self.tupled_upvars_ty().kind() { + ty::Error(_) => Default::default(), + ty::Tuple(tys) => tys, + ty::Infer(_) => panic!("upvar_tys called before capture types are inferred"), + ty => panic!("Unexpected representation of upvar types tuple {:?}", ty), + } + } + + /// Returns the tuple type representing the upvars for this closure. + #[inline] + pub fn tupled_upvars_ty(self) -> I::Ty { + self.split().tupled_upvars_ty + } + + /// Returns the closure kind for this closure; may return a type + /// variable during inference. To get the closure kind during + /// inference, use `infcx.closure_kind(args)`. + pub fn kind_ty(self) -> I::Ty { + self.split().closure_kind_ty + } + + /// Returns the `fn` pointer type representing the closure signature for this + /// closure. + // FIXME(eddyb) this should be unnecessary, as the shallowly resolved + // type is known at the time of the creation of `ClosureArgs`, + // see `rustc_hir_analysis::check::closure`. + pub fn sig_as_fn_ptr_ty(self) -> I::Ty { + self.split().closure_sig_as_fn_ptr_ty + } + + /// Returns the closure kind for this closure; only usable outside + /// of an inference context, because in that context we know that + /// there are no type variables. + /// + /// If you have an inference context, use `infcx.closure_kind()`. + pub fn kind(self) -> ty::ClosureKind { + self.kind_ty().to_opt_closure_kind().unwrap() + } + + /// Extracts the signature from the closure. + pub fn sig(self) -> ty::Binder> { + match self.sig_as_fn_ptr_ty().kind() { + ty::FnPtr(sig) => sig, + ty => panic!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {ty:?}"), + } + } +} + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +pub struct CoroutineClosureArgs { + pub args: I::GenericArgs, +} + +/// See docs for explanation of how each argument is used. +/// +/// See [`CoroutineClosureSignature`] for how these arguments are put together +/// to make a callable [`ty::FnSig`] suitable for typeck and borrowck. +pub struct CoroutineClosureArgsParts { + /// This is the args of the typeck root. + pub parent_args: I::GenericArgsSlice, + /// Represents the maximum calling capability of the closure. + pub closure_kind_ty: I::Ty, + /// Represents all of the relevant parts of the coroutine returned by this + /// coroutine-closure. This signature parts type will have the general + /// shape of `fn(tupled_inputs, resume_ty) -> (return_ty, yield_ty)`, where + /// `resume_ty`, `return_ty`, and `yield_ty` are the respective types for the + /// coroutine returned by the coroutine-closure. + /// + /// Use `coroutine_closure_sig` to break up this type rather than using it + /// yourself. + pub signature_parts_ty: I::Ty, + /// The upvars captured by the closure. Remains an inference variable + /// until the upvar analysis, which happens late in HIR typeck. + pub tupled_upvars_ty: I::Ty, + /// a function pointer that has the shape `for<'env> fn() -> (&'env T, ...)`. + /// This allows us to represent the binder of the self-captures of the closure. + /// + /// For example, if the coroutine returned by the closure borrows `String` + /// from the closure's upvars, this will be `for<'env> fn() -> (&'env String,)`, + /// while the `tupled_upvars_ty`, representing the by-move version of the same + /// captures, will be `(String,)`. + pub coroutine_captures_by_ref_ty: I::Ty, + /// Witness type returned by the generator produced by this coroutine-closure. + pub coroutine_witness_ty: I::Ty, +} + +impl CoroutineClosureArgs { + pub fn new(tcx: I, parts: CoroutineClosureArgsParts) -> CoroutineClosureArgs { + CoroutineClosureArgs { + args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ + parts.closure_kind_ty.into(), + parts.signature_parts_ty.into(), + parts.tupled_upvars_ty.into(), + parts.coroutine_captures_by_ref_ty.into(), + parts.coroutine_witness_ty.into(), + ])), + } + } + + fn split(self) -> CoroutineClosureArgsParts { + self.args.split_coroutine_closure_args() + } + + pub fn parent_args(self) -> I::GenericArgsSlice { + self.split().parent_args + } + + #[inline] + pub fn upvar_tys(self) -> I::Tys { + match self.tupled_upvars_ty().kind() { + ty::Error(_) => Default::default(), + ty::Tuple(..) => self.tupled_upvars_ty().tuple_fields(), + ty::Infer(_) => panic!("upvar_tys called before capture types are inferred"), + ty => panic!("Unexpected representation of upvar types tuple {:?}", ty), + } + } + + #[inline] + pub fn tupled_upvars_ty(self) -> I::Ty { + self.split().tupled_upvars_ty + } + + pub fn kind_ty(self) -> I::Ty { + self.split().closure_kind_ty + } + + pub fn kind(self) -> ty::ClosureKind { + self.kind_ty().to_opt_closure_kind().unwrap() + } + + pub fn signature_parts_ty(self) -> I::Ty { + self.split().signature_parts_ty + } + + pub fn coroutine_closure_sig(self) -> ty::Binder> { + let interior = self.coroutine_witness_ty(); + let ty::FnPtr(sig) = self.signature_parts_ty().kind() else { panic!() }; + sig.map_bound(|sig| { + let [resume_ty, tupled_inputs_ty] = *sig.inputs() else { + panic!(); + }; + let [yield_ty, return_ty] = **sig.output().tuple_fields() else { panic!() }; + CoroutineClosureSignature { + interior, + tupled_inputs_ty, + resume_ty, + yield_ty, + return_ty, + c_variadic: sig.c_variadic, + safety: sig.safety, + abi: sig.abi, + } + }) + } + + pub fn coroutine_captures_by_ref_ty(self) -> I::Ty { + self.split().coroutine_captures_by_ref_ty + } + + pub fn coroutine_witness_ty(self) -> I::Ty { + self.split().coroutine_witness_ty + } + + pub fn has_self_borrows(&self) -> bool { + match self.coroutine_captures_by_ref_ty().kind() { + ty::FnPtr(sig) => sig + .skip_binder() + .visit_with(&mut HasRegionsBoundAt { binder: ty::INNERMOST }) + .is_break(), + ty::Error(_) => true, + _ => panic!(), + } + } +} + +/// Unlike `has_escaping_bound_vars` or `outermost_exclusive_binder`, this will +/// detect only regions bound *at* the debruijn index. +struct HasRegionsBoundAt { + binder: ty::DebruijnIndex, +} +// FIXME: Could be optimized to not walk into components with no escaping bound vars. +impl TypeVisitor for HasRegionsBoundAt { + type Result = ControlFlow<()>; + fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { + self.binder.shift_in(1); + t.super_visit_with(self)?; + self.binder.shift_out(1); + ControlFlow::Continue(()) + } + + fn visit_region(&mut self, r: I::Region) -> Self::Result { + if matches!(r.kind(), ty::ReBound(binder, _) if self.binder == binder) { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + } +} + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +pub struct CoroutineClosureSignature { + pub interior: I::Ty, + pub tupled_inputs_ty: I::Ty, + pub resume_ty: I::Ty, + pub yield_ty: I::Ty, + pub return_ty: I::Ty, + + // Like the `fn_sig_as_fn_ptr_ty` of a regular closure, these types + // never actually differ. But we save them rather than recreating them + // from scratch just for good measure. + /// Always false + pub c_variadic: bool, + /// Always `Normal` (safe) + pub safety: I::Safety, + /// Always `RustCall` + pub abi: I::Abi, +} + +impl CoroutineClosureSignature { + /// Construct a coroutine from the closure signature. Since a coroutine signature + /// is agnostic to the type of generator that is returned (by-ref/by-move), + /// the caller must specify what "flavor" of generator that they'd like to + /// create. Additionally, they must manually compute the upvars of the closure. + /// + /// This helper is not really meant to be used directly except for early on + /// during typeck, when we want to put inference vars into the kind and upvars tys. + /// When the kind and upvars are known, use the other helper functions. + pub fn to_coroutine( + self, + tcx: I, + parent_args: I::GenericArgsSlice, + coroutine_kind_ty: I::Ty, + coroutine_def_id: I::DefId, + tupled_upvars_ty: I::Ty, + ) -> I::Ty { + let coroutine_args = ty::CoroutineArgs::new( + tcx, + ty::CoroutineArgsParts { + parent_args, + kind_ty: coroutine_kind_ty, + resume_ty: self.resume_ty, + yield_ty: self.yield_ty, + return_ty: self.return_ty, + witness: self.interior, + tupled_upvars_ty, + }, + ); + + Ty::new_coroutine(tcx, coroutine_def_id, coroutine_args.args) + } + + /// Given known upvars and a [`ClosureKind`](ty::ClosureKind), compute the coroutine + /// returned by that corresponding async fn trait. + /// + /// This function expects the upvars to have been computed already, and doesn't check + /// that the `ClosureKind` is actually supported by the coroutine-closure. + pub fn to_coroutine_given_kind_and_upvars( + self, + tcx: I, + parent_args: I::GenericArgsSlice, + coroutine_def_id: I::DefId, + goal_kind: ty::ClosureKind, + env_region: I::Region, + closure_tupled_upvars_ty: I::Ty, + coroutine_captures_by_ref_ty: I::Ty, + ) -> I::Ty { + let tupled_upvars_ty = Self::tupled_upvars_by_closure_kind( + tcx, + goal_kind, + self.tupled_inputs_ty, + closure_tupled_upvars_ty, + coroutine_captures_by_ref_ty, + env_region, + ); + + self.to_coroutine( + tcx, + parent_args, + Ty::from_coroutine_closure_kind(tcx, goal_kind), + coroutine_def_id, + tupled_upvars_ty, + ) + } + + /// Compute the tupled upvars that a coroutine-closure's output coroutine + /// would return for the given `ClosureKind`. + /// + /// When `ClosureKind` is `FnMut`/`Fn`, then this will use the "captures by ref" + /// to return a set of upvars which are borrowed with the given `env_region`. + /// + /// This ensures that the `AsyncFn::call` will return a coroutine whose upvars' + /// lifetimes are related to the lifetime of the borrow on the closure made for + /// the call. This allows borrowck to enforce the self-borrows correctly. + pub fn tupled_upvars_by_closure_kind( + tcx: I, + kind: ty::ClosureKind, + tupled_inputs_ty: I::Ty, + closure_tupled_upvars_ty: I::Ty, + coroutine_captures_by_ref_ty: I::Ty, + env_region: I::Region, + ) -> I::Ty { + match kind { + ty::ClosureKind::Fn | ty::ClosureKind::FnMut => { + let ty::FnPtr(sig) = coroutine_captures_by_ref_ty.kind() else { + panic!(); + }; + let coroutine_captures_by_ref_ty = + sig.output().skip_binder().fold_with(&mut FoldEscapingRegions { + interner: tcx, + region: env_region, + debruijn: ty::INNERMOST, + }); + Ty::new_tup_from_iter( + tcx, + tupled_inputs_ty + .tuple_fields() + .into_iter() + .chain(coroutine_captures_by_ref_ty.tuple_fields()), + ) + } + ty::ClosureKind::FnOnce => Ty::new_tup_from_iter( + tcx, + tupled_inputs_ty + .tuple_fields() + .into_iter() + .chain(closure_tupled_upvars_ty.tuple_fields()), + ), + } + } +} + +/// Instantiates a `for<'env> ...` binder with a specific region. +// FIXME(async_closures): Get rid of this in favor of `BoundVarReplacerDelegate` +// when that is uplifted. +struct FoldEscapingRegions { + interner: I, + debruijn: ty::DebruijnIndex, + region: I::Region, +} + +impl TypeFolder for FoldEscapingRegions { + fn interner(&self) -> I { + self.interner + } + + fn fold_binder(&mut self, t: ty::Binder) -> ty::Binder + where + T: TypeFoldable, + { + self.debruijn.shift_in(1); + let result = t.super_fold_with(self); + self.debruijn.shift_out(1); + result + } + + fn fold_region(&mut self, r: ::Region) -> ::Region { + if let ty::ReBound(debruijn, _) = r.kind() { + assert!( + debruijn <= self.debruijn, + "cannot instantiate binder with escaping bound vars" + ); + if self.debruijn == debruijn { + shift_region(self.interner, self.region, self.debruijn.as_u32()) + } else { + r + } + } else { + r + } + } +} + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +pub struct GenSig { + pub resume_ty: I::Ty, + pub yield_ty: I::Ty, + pub return_ty: I::Ty, +} + +/// Similar to `ClosureArgs`; see the above documentation for more. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +pub struct CoroutineArgs { + pub args: I::GenericArgs, +} + +pub struct CoroutineArgsParts { + /// This is the args of the typeck root. + pub parent_args: I::GenericArgsSlice, + + /// The coroutines returned by a coroutine-closure's `AsyncFnOnce`/`AsyncFnMut` + /// implementations must be distinguished since the former takes the closure's + /// upvars by move, and the latter takes the closure's upvars by ref. + /// + /// This field distinguishes these fields so that codegen can select the right + /// body for the coroutine. This has the same type representation as the closure + /// kind: `i8`/`i16`/`i32`. + /// + /// For regular coroutines, this field will always just be `()`. + pub kind_ty: I::Ty, + + pub resume_ty: I::Ty, + pub yield_ty: I::Ty, + pub return_ty: I::Ty, + + /// The interior type of the coroutine. + /// Represents all types that are stored in locals + /// in the coroutine's body. + pub witness: I::Ty, + + /// The upvars captured by the closure. Remains an inference variable + /// until the upvar analysis, which happens late in HIR typeck. + pub tupled_upvars_ty: I::Ty, +} + +impl CoroutineArgs { + /// Construct `CoroutineArgs` from `CoroutineArgsParts`, containing `Args` + /// for the coroutine parent, alongside additional coroutine-specific components. + pub fn new(tcx: I, parts: CoroutineArgsParts) -> CoroutineArgs { + CoroutineArgs { + args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ + parts.kind_ty.into(), + parts.resume_ty.into(), + parts.yield_ty.into(), + parts.return_ty.into(), + parts.witness.into(), + parts.tupled_upvars_ty.into(), + ])), + } + } + + /// Divides the coroutine args into their respective components. + /// The ordering assumed here must match that used by `CoroutineArgs::new` above. + fn split(self) -> CoroutineArgsParts { + self.args.split_coroutine_args() + } + + /// Returns the generic parameters of the coroutine's parent. + pub fn parent_args(self) -> I::GenericArgsSlice { + self.split().parent_args + } + + // Returns the kind of the coroutine. See docs on the `kind_ty` field. + pub fn kind_ty(self) -> I::Ty { + self.split().kind_ty + } + + /// This describes the types that can be contained in a coroutine. + /// It will be a type variable initially and unified in the last stages of typeck of a body. + /// It contains a tuple of all the types that could end up on a coroutine frame. + /// The state transformation MIR pass may only produce layouts which mention types + /// in this tuple. Upvars are not counted here. + pub fn witness(self) -> I::Ty { + self.split().witness + } + + /// Returns an iterator over the list of types of captured paths by the coroutine. + /// In case there was a type error in figuring out the types of the captured path, an + /// empty iterator is returned. + #[inline] + pub fn upvar_tys(self) -> I::Tys { + match self.tupled_upvars_ty().kind() { + ty::Error(_) => Default::default(), + ty::Tuple(tys) => tys, + ty::Infer(_) => panic!("upvar_tys called before capture types are inferred"), + ty => panic!("Unexpected representation of upvar types tuple {:?}", ty), + } + } + + /// Returns the tuple type representing the upvars for this coroutine. + #[inline] + pub fn tupled_upvars_ty(self) -> I::Ty { + self.split().tupled_upvars_ty + } + + /// Returns the type representing the resume type of the coroutine. + pub fn resume_ty(self) -> I::Ty { + self.split().resume_ty + } + + /// Returns the type representing the yield type of the coroutine. + pub fn yield_ty(self) -> I::Ty { + self.split().yield_ty + } + + /// Returns the type representing the return type of the coroutine. + pub fn return_ty(self) -> I::Ty { + self.split().return_ty + } + + /// Returns the "coroutine signature", which consists of its resume, yield + /// and return types. + pub fn sig(self) -> GenSig { + let parts = self.split(); + GenSig { resume_ty: parts.resume_ty, yield_ty: parts.yield_ty, return_ty: parts.return_ty } + } +} diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs index 858ce5301d84..085dfd9ea890 100644 --- a/compiler/stable_mir/src/compiler_interface.rs +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -11,10 +11,10 @@ use crate::mir::mono::{Instance, InstanceDef, StaticDef}; use crate::mir::{BinOp, Body, Place, UnOp}; use crate::target::MachineInfo; use crate::ty::{ - AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef, + AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef, ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics, - ImplDef, ImplTrait, IntrinsicDef, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, Ty, - TyKind, UintTy, VariantDef, + ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, TraitDecl, + TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef, }; use crate::{ mir, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind, @@ -109,19 +109,21 @@ pub trait Context { fn variant_fields(&self, def: VariantDef) -> Vec; /// Evaluate constant as a target usize. - fn eval_target_usize(&self, cnst: &Const) -> Result; + fn eval_target_usize(&self, cnst: &MirConst) -> Result; + fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result; /// Create a new zero-sized constant. - fn try_new_const_zst(&self, ty: Ty) -> Result; + fn try_new_const_zst(&self, ty: Ty) -> Result; /// Create a new constant that represents the given string value. - fn new_const_str(&self, value: &str) -> Const; + fn new_const_str(&self, value: &str) -> MirConst; /// Create a new constant that represents the given boolean value. - fn new_const_bool(&self, value: bool) -> Const; + fn new_const_bool(&self, value: bool) -> MirConst; /// Create a new constant that represents the given value. - fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result; + fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result; + fn try_new_ty_const_uint(&self, value: u128, uint_ty: UintTy) -> Result; /// Create a new type from the given kind. fn new_rigid_ty(&self, kind: RigidTy) -> Ty; @@ -136,11 +138,13 @@ pub trait Context { fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty; /// Returns literal value of a const as a string. - fn const_pretty(&self, cnst: &Const) -> String; + fn mir_const_pretty(&self, cnst: &MirConst) -> String; /// `Span` of an item fn span_of_an_item(&self, def_id: DefId) -> Span; + fn ty_const_pretty(&self, ct: TyConstId) -> String; + /// Obtain the representation of a type. fn ty_pretty(&self, ty: Ty) -> String; diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 4c779ae96a81..43e4682dc100 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -1,8 +1,8 @@ use crate::compiler_interface::with; use crate::mir::pretty::function_body; use crate::ty::{ - AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind, - VariantIdx, + AdtDef, ClosureDef, CoroutineDef, GenericArgs, MirConst, Movability, Region, RigidTy, Ty, + TyConst, TyKind, VariantIdx, }; use crate::{Error, Opaque, Span, Symbol}; use std::io; @@ -524,7 +524,7 @@ pub enum Rvalue { /// Corresponds to source code like `[x; 32]`. /// /// [#74836]: https://github.com/rust-lang/rust/issues/74836 - Repeat(Operand, Const), + Repeat(Operand, TyConst), /// Transmutes a `*mut u8` into shallow-initialized `Box`. /// @@ -718,7 +718,7 @@ pub enum VarDebugInfoContents { pub struct ConstOperand { pub span: Span, pub user_ty: Option, - pub const_: Const, + pub const_: MirConst, } // In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This @@ -833,7 +833,7 @@ type UserTypeAnnotationIndex = usize; pub struct Constant { pub span: Span, pub user_ty: Option, - pub literal: Const, + pub literal: MirConst, } /// The possible branch sites of a [TerminatorKind::SwitchInt]. diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index bbca3965852a..2fb180b84c7c 100644 --- a/compiler/stable_mir/src/mir/pretty.rs +++ b/compiler/stable_mir/src/mir/pretty.rs @@ -1,5 +1,5 @@ use crate::mir::{Operand, Place, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents}; -use crate::ty::{Const, IndexedVal, Ty}; +use crate::ty::{IndexedVal, MirConst, Ty, TyConst}; use crate::{with, Body, Mutability}; use fmt::{Display, Formatter}; use std::fmt::Debug; @@ -46,7 +46,7 @@ pub(crate) fn function_body(writer: &mut W, body: &Body, name: &str) - VarDebugInfoContents::Place(place) => { format!("{place:?}") } - VarDebugInfoContents::Const(constant) => pretty_const(&constant.const_), + VarDebugInfoContents::Const(constant) => pretty_mir_const(&constant.const_), }; writeln!(writer, " debug {} => {};", info.name, content) })?; @@ -156,7 +156,7 @@ fn pretty_terminator(writer: &mut W, terminator: &TerminatorKind) -> i fn pretty_terminator_head(writer: &mut W, terminator: &TerminatorKind) -> io::Result<()> { use self::TerminatorKind::*; - const INDENT: &'static str = " "; + const INDENT: &str = " "; match terminator { Goto { .. } => write!(writer, "{INDENT}goto"), SwitchInt { discr, .. } => { @@ -310,12 +310,16 @@ fn pretty_operand(operand: &Operand) -> String { Operand::Move(mv) => { format!("move {:?}", mv) } - Operand::Constant(cnst) => pretty_const(&cnst.literal), + Operand::Constant(cnst) => pretty_mir_const(&cnst.literal), } } -fn pretty_const(literal: &Const) -> String { - with(|cx| cx.const_pretty(&literal)) +fn pretty_mir_const(literal: &MirConst) -> String { + with(|cx| cx.mir_const_pretty(literal)) +} + +fn pretty_ty_const(ct: &TyConst) -> String { + with(|cx| cx.ty_const_pretty(ct.id)) } fn pretty_rvalue(writer: &mut W, rval: &Rvalue) -> io::Result<()> { @@ -359,7 +363,7 @@ fn pretty_rvalue(writer: &mut W, rval: &Rvalue) -> io::Result<()> { write!(writer, "{kind}{:?}", place) } Rvalue::Repeat(op, cnst) => { - write!(writer, "{} \" \" {}", &pretty_operand(op), cnst.ty()) + write!(writer, "{} \" \" {}", &pretty_operand(op), &pretty_ty_const(cnst)) } Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::ThreadLocalRef(item) => { diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index 24296e9e8778..10f30083dc2d 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -36,7 +36,7 @@ //! variant argument) that does not require visiting. use crate::mir::*; -use crate::ty::{Const, GenericArgs, Region, Ty}; +use crate::ty::{GenericArgs, MirConst, Region, Ty, TyConst}; use crate::{Error, Opaque, Span}; pub trait MirVisitor { @@ -112,8 +112,13 @@ pub trait MirVisitor { self.super_constant(constant, location) } - fn visit_const(&mut self, constant: &Const, location: Location) { - self.super_const(constant, location) + fn visit_mir_const(&mut self, constant: &MirConst, location: Location) { + self.super_mir_const(constant, location) + } + + fn visit_ty_const(&mut self, constant: &TyConst, location: Location) { + let _ = location; + self.super_ty_const(constant) } fn visit_region(&mut self, region: &Region, location: Location) { @@ -339,7 +344,7 @@ pub trait MirVisitor { } Rvalue::Repeat(op, constant) => { self.visit_operand(op, location); - self.visit_const(constant, location); + self.visit_ty_const(constant, location); } Rvalue::ShallowInitBox(op, ty) => { self.visit_ty(ty, location); @@ -378,14 +383,18 @@ pub trait MirVisitor { fn super_constant(&mut self, constant: &Constant, location: Location) { let Constant { span, user_ty: _, literal } = constant; self.visit_span(span); - self.visit_const(literal, location); + self.visit_mir_const(literal, location); } - fn super_const(&mut self, constant: &Const, location: Location) { - let Const { kind: _, ty, id: _ } = constant; + fn super_mir_const(&mut self, constant: &MirConst, location: Location) { + let MirConst { kind: _, ty, id: _ } = constant; self.visit_ty(ty, location); } + fn super_ty_const(&mut self, constant: &TyConst) { + let _ = constant; + } + fn super_region(&mut self, region: &Region) { let _ = region; } @@ -407,7 +416,7 @@ pub trait MirVisitor { self.visit_place(place, PlaceContext::NON_USE, location); } VarDebugInfoContents::Const(constant) => { - self.visit_const(&constant.const_, location); + self.visit_mir_const(&constant.const_, location); } } } diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index d62054eff609..bcbe87f7303b 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -28,11 +28,11 @@ impl Ty { /// Create a new array type. pub fn try_new_array(elem_ty: Ty, size: u64) -> Result { - Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, Const::try_from_target_usize(size)?))) + Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, TyConst::try_from_target_usize(size)?))) } /// Create a new array type from Const length. - pub fn new_array_with_const_len(elem_ty: Ty, len: Const) -> Ty { + pub fn new_array_with_const_len(elem_ty: Ty, len: TyConst) -> Ty { Ty::from_rigid_kind(RigidTy::Array(elem_ty, len)) } @@ -101,24 +101,66 @@ impl Ty { /// Represents a pattern in the type system #[derive(Clone, Debug, Eq, PartialEq)] pub enum Pattern { - Range { start: Option, end: Option, include_end: bool }, + Range { start: Option, end: Option, include_end: bool }, } -/// Represents a constant in MIR or from the Type system. +/// Represents a constant in the type system #[derive(Clone, Debug, Eq, PartialEq)] -pub struct Const { +pub struct TyConst { + pub(crate) kind: TyConstKind, + pub id: TyConstId, +} + +impl TyConst { + pub fn new(kind: TyConstKind, id: TyConstId) -> TyConst { + Self { kind, id } + } + + /// Retrieve the constant kind. + pub fn kind(&self) -> &TyConstKind { + &self.kind + } + + /// Creates an interned usize constant. + fn try_from_target_usize(val: u64) -> Result { + with(|cx| cx.try_new_ty_const_uint(val.into(), UintTy::Usize)) + } + + /// Try to evaluate to a target `usize`. + pub fn eval_target_usize(&self) -> Result { + with(|cx| cx.eval_target_usize_ty(self)) + } +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum TyConstKind { + Param(ParamConst), + Bound(DebruijnIndex, BoundVar), + Unevaluated(ConstDef, GenericArgs), + + // FIXME: These should be a valtree + Value(Ty, Allocation), + ZSTValue(Ty), +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct TyConstId(usize); + +/// Represents a constant in MIR +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MirConst { /// The constant kind. pub(crate) kind: ConstantKind, /// The constant type. pub(crate) ty: Ty, /// Used for internal tracking of the internal constant. - pub id: ConstId, + pub id: MirConstId, } -impl Const { +impl MirConst { /// Build a constant. Note that this should only be used by the compiler. - pub fn new(kind: ConstantKind, ty: Ty, id: ConstId) -> Const { - Const { kind, ty, id } + pub fn new(kind: ConstantKind, ty: Ty, id: MirConstId) -> MirConst { + MirConst { kind, ty, id } } /// Retrieve the constant kind. @@ -131,11 +173,6 @@ impl Const { self.ty } - /// Creates an interned usize constant. - fn try_from_target_usize(val: u64) -> Result { - with(|cx| cx.try_new_const_uint(val.into(), UintTy::Usize)) - } - /// Try to evaluate to a target `usize`. pub fn eval_target_usize(&self) -> Result { with(|cx| cx.eval_target_usize(self)) @@ -143,7 +180,7 @@ impl Const { /// Create a constant that represents a new zero-sized constant of type T. /// Fails if the type is not a ZST or if it doesn't have a known size. - pub fn try_new_zero_sized(ty: Ty) -> Result { + pub fn try_new_zero_sized(ty: Ty) -> Result { with(|cx| cx.try_new_const_zst(ty)) } @@ -152,23 +189,23 @@ impl Const { /// Note that there is no guarantee today about duplication of the same constant. /// I.e.: Calling this function multiple times with the same argument may or may not return /// the same allocation. - pub fn from_str(value: &str) -> Const { + pub fn from_str(value: &str) -> MirConst { with(|cx| cx.new_const_str(value)) } /// Build a new constant that represents the given boolean value. - pub fn from_bool(value: bool) -> Const { + pub fn from_bool(value: bool) -> MirConst { with(|cx| cx.new_const_bool(value)) } /// Build a new constant that represents the given unsigned integer. - pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result { + pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result { with(|cx| cx.try_new_const_uint(value, uint_ty)) } } #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct ConstId(usize); +pub struct MirConstId(usize); type Ident = Opaque; @@ -484,7 +521,7 @@ pub enum RigidTy { Adt(AdtDef, GenericArgs), Foreign(ForeignDef), Str, - Array(Ty, Const), + Array(Ty, TyConst), Pat(Ty, Pattern), Slice(Ty), RawPtr(Ty, Mutability), @@ -526,7 +563,7 @@ pub enum IntTy { impl IntTy { pub fn num_bytes(self) -> usize { match self { - IntTy::Isize => crate::target::MachineInfo::target_pointer_width().bytes().into(), + IntTy::Isize => crate::target::MachineInfo::target_pointer_width().bytes(), IntTy::I8 => 1, IntTy::I16 => 2, IntTy::I32 => 4, @@ -549,7 +586,7 @@ pub enum UintTy { impl UintTy { pub fn num_bytes(self) -> usize { match self { - UintTy::Usize => crate::target::MachineInfo::target_pointer_width().bytes().into(), + UintTy::Usize => crate::target::MachineInfo::target_pointer_width().bytes(), UintTy::U8 => 1, UintTy::U16 => 2, UintTy::U32 => 4, @@ -866,7 +903,7 @@ impl std::ops::Index for GenericArgs { } impl std::ops::Index for GenericArgs { - type Output = Const; + type Output = TyConst; fn index(&self, index: ParamConst) -> &Self::Output { self.0[index.index as usize].expect_const() @@ -877,7 +914,7 @@ impl std::ops::Index for GenericArgs { pub enum GenericArgKind { Lifetime(Region), Type(Ty), - Const(Const), + Const(TyConst), } impl GenericArgKind { @@ -894,7 +931,7 @@ impl GenericArgKind { /// Panic if this generic argument is not a const, otherwise /// return the const. #[track_caller] - pub fn expect_const(&self) -> &Const { + pub fn expect_const(&self) -> &TyConst { match self { GenericArgKind::Const(c) => c, _ => panic!("{self:?}"), @@ -913,7 +950,7 @@ impl GenericArgKind { #[derive(Clone, Debug, Eq, PartialEq)] pub enum TermKind { Type(Ty), - Const(Const), + Const(TyConst), } #[derive(Clone, Debug, Eq, PartialEq)] @@ -1185,7 +1222,7 @@ impl Allocation { match self.read_int()? { 0 => Ok(false), 1 => Ok(true), - val @ _ => Err(error!("Unexpected value for bool: `{val}`")), + val => Err(error!("Unexpected value for bool: `{val}`")), } } @@ -1202,6 +1239,7 @@ impl Allocation { #[derive(Clone, Debug, Eq, PartialEq)] pub enum ConstantKind { + Ty(TyConst), Allocated(Allocation), Unevaluated(UnevaluatedConst), Param(ParamConst), @@ -1335,7 +1373,7 @@ pub enum PredicateKind { ObjectSafe(TraitDef), SubType(SubtypePredicate), Coerce(CoercePredicate), - ConstEquate(Const, Const), + ConstEquate(TyConst, TyConst), Ambiguous, AliasRelate(TermKind, TermKind, AliasRelationDirection), } @@ -1346,9 +1384,9 @@ pub enum ClauseKind { RegionOutlives(RegionOutlivesPredicate), TypeOutlives(TypeOutlivesPredicate), Projection(ProjectionPredicate), - ConstArgHasType(Const, Ty), + ConstArgHasType(TyConst, Ty), WellFormed(GenericArgKind), - ConstEvaluatable(Const), + ConstEvaluatable(TyConst), } #[derive(Clone, Debug, Eq, PartialEq)] @@ -1426,7 +1464,8 @@ macro_rules! index_impl { }; } -index_impl!(ConstId); +index_impl!(TyConstId); +index_impl!(MirConstId); index_impl!(Ty); index_impl!(Span); diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index 2d7159f87fec..fc1da8fafe48 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -1,10 +1,10 @@ use std::ops::ControlFlow; -use crate::Opaque; +use crate::{ty::TyConst, Opaque}; use super::ty::{ - Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, - Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst, + Allocation, Binder, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, + MirConst, Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst, }; pub trait Visitor: Sized { @@ -12,7 +12,7 @@ pub trait Visitor: Sized { fn visit_ty(&mut self, ty: &Ty) -> ControlFlow { ty.super_visit(self) } - fn visit_const(&mut self, c: &Const) -> ControlFlow { + fn visit_const(&mut self, c: &TyConst) -> ControlFlow { c.super_visit(self) } fn visit_reg(&mut self, reg: &Region) -> ControlFlow { @@ -42,12 +42,32 @@ impl Visitable for Ty { } } -impl Visitable for Const { +impl Visitable for TyConst { fn visit(&self, visitor: &mut V) -> ControlFlow { visitor.visit_const(self) } + fn super_visit(&self, visitor: &mut V) -> ControlFlow { + match &self.kind { + crate::ty::TyConstKind::Param(_) => {} + crate::ty::TyConstKind::Bound(_, _) => {} + crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?, + crate::ty::TyConstKind::Value(ty, alloc) => { + alloc.visit(visitor)?; + ty.visit(visitor)?; + } + crate::ty::TyConstKind::ZSTValue(ty) => ty.visit(visitor)?, + } + ControlFlow::Continue(()) + } +} + +impl Visitable for MirConst { + fn visit(&self, visitor: &mut V) -> ControlFlow { + self.super_visit(visitor) + } fn super_visit(&self, visitor: &mut V) -> ControlFlow { match &self.kind() { + super::ty::ConstantKind::Ty(ct) => ct.visit(visitor)?, super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor)?, super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?, super::ty::ConstantKind::Param(_) | super::ty::ConstantKind::ZeroSized => {} diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 846b9a1404d2..0b04fb4a2744 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -440,7 +440,10 @@ impl BinaryHeap { /// heap.push(4); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_binary_heap_constructor", issue = "112353")] + #[rustc_const_stable( + feature = "const_binary_heap_constructor", + since = "CURRENT_RUSTC_VERSION" + )] #[must_use] pub const fn new() -> BinaryHeap { BinaryHeap { data: vec![] } @@ -484,7 +487,7 @@ impl BinaryHeap { /// heap.push(4); /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_binary_heap_constructor", issue = "112353")] + #[rustc_const_unstable(feature = "const_binary_heap_new_in", issue = "112353")] #[must_use] pub const fn new_in(alloc: A) -> BinaryHeap { BinaryHeap { data: Vec::new_in(alloc) } diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index a7c3dfc982d1..872b4da4dbfd 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -2,12 +2,12 @@ use crate::cell::UnsafeCell; use crate::fmt; use crate::mem; -/// A cell which can be written to only once. +/// A cell which can nominally be written to only once. /// /// This allows obtaining a shared `&T` reference to its inner value without copying or replacing /// it (unlike [`Cell`]), and without runtime borrow checks (unlike [`RefCell`]). However, /// only immutable references can be obtained unless one has a mutable reference to the cell -/// itself. +/// itself. In the same vein, the cell can only be re-initialized with such a mutable reference. /// /// For a thread-safe version of this struct, see [`std::sync::OnceLock`]. /// diff --git a/library/core/src/future/async_drop.rs b/library/core/src/future/async_drop.rs index 0eb8d7bb3289..25138c445c43 100644 --- a/library/core/src/future/async_drop.rs +++ b/library/core/src/future/async_drop.rs @@ -161,6 +161,11 @@ async unsafe fn surface_drop_in_place(ptr: *mut T) { /// wrapped future completes by returning `Poll::Ready(())` on poll. This /// is useful for constructing async destructors to guarantee this /// "fuse" property +// +// FIXME: Consider optimizing combinators to not have to use fuse in majority +// of cases, perhaps by adding `#[(rustc_)idempotent(_future)]` attribute for +// async functions and blocks with the unit return type. However current layout +// optimizations currently encode `None` case into the async block's discriminant. struct Fuse { inner: Option, } @@ -251,6 +256,14 @@ async unsafe fn either, M: IntoFuture, T } } +#[cfg(not(bootstrap))] +#[lang = "async_drop_deferred_drop_in_place"] +async unsafe fn deferred_drop_in_place(to_drop: *mut T) { + // SAFETY: same safety requirements as with drop_in_place (implied by + // function's name) + unsafe { crate::ptr::drop_in_place(to_drop) } +} + /// Used for noop async destructors. We don't use [`core::future::Ready`] /// because it panics after its second poll, which could be potentially /// bad if that would happen during the cleanup. diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index fa5bb28adff9..ec8488009b96 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -20,7 +20,7 @@ //! //! #[custom_mir(dialect = "built")] //! pub fn simple(x: i32) -> i32 { -//! mir!( +//! mir! { //! let temp2: i32; //! //! { @@ -33,7 +33,7 @@ //! RET = temp2; //! Return() //! } -//! ) +//! } //! } //! ``` //! @@ -71,7 +71,7 @@ //! //! #[custom_mir(dialect = "built")] //! pub fn choose_load(a: &i32, b: &i32, c: bool) -> i32 { -//! mir!( +//! mir! { //! { //! match c { //! true => t, @@ -93,20 +93,22 @@ //! RET = *temp; //! Return() //! } -//! ) +//! } //! } //! //! #[custom_mir(dialect = "built")] //! fn unwrap_unchecked(opt: Option) -> T { -//! mir!({ -//! RET = Move(Field(Variant(opt, 1), 0)); -//! Return() -//! }) +//! mir! { +//! { +//! RET = Move(Field(Variant(opt, 1), 0)); +//! Return() +//! } +//! } //! } //! //! #[custom_mir(dialect = "runtime", phase = "optimized")] //! fn push_and_pop(v: &mut Vec, value: T) { -//! mir!( +//! mir! { //! let _unused; //! let popped; //! @@ -125,19 +127,19 @@ //! ret = { //! Return() //! } -//! ) +//! } //! } //! //! #[custom_mir(dialect = "runtime", phase = "optimized")] //! fn annotated_return_type() -> (i32, bool) { -//! mir!( +//! mir! { //! type RET = (i32, bool); //! { //! RET.0 = 1; //! RET.1 = true; //! Return() //! } -//! ) +//! } //! } //! ``` //! @@ -152,7 +154,7 @@ //! //! #[custom_mir(dialect = "built")] //! fn borrow_error(should_init: bool) -> i32 { -//! mir!( +//! mir! { //! let temp: i32; //! //! { @@ -171,7 +173,7 @@ //! RET = temp; //! Return() //! } -//! ) +//! } //! } //! ``` //! @@ -179,7 +181,7 @@ //! error[E0381]: used binding is possibly-uninitialized //! --> test.rs:24:13 //! | -//! 8 | / mir!( +//! 8 | / mir! { //! 9 | | let temp: i32; //! 10 | | //! 11 | | { @@ -191,7 +193,7 @@ //! | | ^^^^^^^^^^ value used here but it is possibly-uninitialized //! 25 | | Return() //! 26 | | } -//! 27 | | ) +//! 27 | | } //! | |_____- binding declared here but left uninitialized //! //! error: aborting due to 1 previous error @@ -407,18 +409,22 @@ define!( /// /// #[custom_mir(dialect = "built")] /// fn unwrap_deref(opt: Option<&i32>) -> i32 { - /// mir!({ - /// RET = *Field::<&i32>(Variant(opt, 1), 0); - /// Return() - /// }) + /// mir! { + /// { + /// RET = *Field::<&i32>(Variant(opt, 1), 0); + /// Return() + /// } + /// } /// } /// /// #[custom_mir(dialect = "built")] /// fn set(opt: &mut Option) { - /// mir!({ - /// place!(Field(Variant(*opt, 1), 0)) = 5; - /// Return() - /// }) + /// mir! { + /// { + /// place!(Field(Variant(*opt, 1), 0)) = 5; + /// Return() + /// } + /// } /// } /// ``` fn Field(place: (), field: u32) -> F @@ -455,7 +461,7 @@ define!( /// your MIR into something that is easier to parse in the compiler. #[rustc_macro_transparency = "transparent"] pub macro mir { - ( + { $(type RET = $ret_ty:ty ;)? $(let $local_decl:ident $(: $local_decl_ty:ty)? ;)* $(debug $dbg_name:ident => $dbg_data:expr ;)* @@ -469,7 +475,7 @@ pub macro mir { $($block:tt)* } )* - ) => {{ + } => {{ // First, we declare all basic blocks. __internal_declare_basic_blocks!($( $block_name $(($block_cleanup))? diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 19fc4489618f..22b24937cbce 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1030,25 +1030,42 @@ impl f32 { /// ``` #[unstable(feature = "num_midpoint", issue = "110840")] pub fn midpoint(self, other: f32) -> f32 { - const LO: f32 = f32::MIN_POSITIVE * 2.; - const HI: f32 = f32::MAX / 2.; + cfg_if! { + if #[cfg(any( + target_arch = "x86_64", + target_arch = "aarch64", + all(any(target_arch="riscv32", target_arch= "riscv64"), target_feature="d"), + all(target_arch = "arm", target_feature="vfp2"), + target_arch = "wasm32", + target_arch = "wasm64", + ))] { + // whitelist the faster implementation to targets that have known good 64-bit float + // implementations. Falling back to the branchy code on targets that don't have + // 64-bit hardware floats or buggy implementations. + // see: https://github.com/rust-lang/rust/pull/121062#issuecomment-2123408114 + ((f64::from(self) + f64::from(other)) / 2.0) as f32 + } else { + const LO: f32 = f32::MIN_POSITIVE * 2.; + const HI: f32 = f32::MAX / 2.; - let (a, b) = (self, other); - let abs_a = a.abs_private(); - let abs_b = b.abs_private(); + let (a, b) = (self, other); + let abs_a = a.abs_private(); + let abs_b = b.abs_private(); - if abs_a <= HI && abs_b <= HI { - // Overflow is impossible - (a + b) / 2. - } else if abs_a < LO { - // Not safe to halve a - a + (b / 2.) - } else if abs_b < LO { - // Not safe to halve b - (a / 2.) + b - } else { - // Not safe to halve a and b - (a / 2.) + (b / 2.) + if abs_a <= HI && abs_b <= HI { + // Overflow is impossible + (a + b) / 2. + } else if abs_a < LO { + // Not safe to halve a + a + (b / 2.) + } else if abs_b < LO { + // Not safe to halve b + (a / 2.) + b + } else { + // Not safe to halve a and b + (a / 2.) + (b / 2.) + } + } } } diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index c9c6e34eaad8..96510ee4dca6 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -183,6 +183,30 @@ macro_rules! int_impl { (self as $UnsignedT).trailing_ones() } + /// Returns the bit pattern of `self` reinterpreted as an unsigned integer of the same size. + /// + /// This produces the same result as an `as` cast, but ensures that the bit-width remains + /// the same. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(integer_sign_cast)] + /// + #[doc = concat!("let n = -1", stringify!($SelfT), ";")] + /// + #[doc = concat!("assert_eq!(n.cast_unsigned(), ", stringify!($UnsignedT), "::MAX);")] + /// ``` + #[unstable(feature = "integer_sign_cast", issue = "125882")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline(always)] + pub const fn cast_unsigned(self) -> $UnsignedT { + self as $UnsignedT + } + /// Shifts the bits to the left by a specified amount, `n`, /// wrapping the truncated bits to the end of the resulting integer. /// diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index f70c34199ace..1491c27372bf 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -184,6 +184,30 @@ macro_rules! uint_impl { (!self).trailing_zeros() } + /// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size. + /// + /// This produces the same result as an `as` cast, but ensures that the bit-width remains + /// the same. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(integer_sign_cast)] + /// + #[doc = concat!("let n = ", stringify!($SelfT), "::MAX;")] + /// + #[doc = concat!("assert_eq!(n.cast_signed(), -1", stringify!($SignedT), ");")] + /// ``` + #[unstable(feature = "integer_sign_cast", issue = "125882")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline(always)] + pub const fn cast_signed(self) -> $SignedT { + self as $SignedT + } + /// Shifts the bits to the left by a specified amount, `n`, /// wrapping the truncated bits to the end of the resulting integer. /// @@ -1148,9 +1172,12 @@ macro_rules! uint_impl { pub const fn checked_ilog(self, base: Self) -> Option { if self <= 0 || base <= 1 { None + } else if self < base { + Some(0) } else { - let mut n = 0; - let mut r = 1; + // Since base >= self, n >= 1 + let mut n = 1; + let mut r = base; // Optimization for 128 bit wide integers. if Self::BITS == 128 { diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 4213a9dedfe4..8e3447d0b1b2 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -450,8 +450,13 @@ mod mut_ptr; /// Executes the destructor (if any) of the pointed-to value. /// -/// This is semantically equivalent to calling [`ptr::read`] and discarding +/// This is almost the same as calling [`ptr::read`] and discarding /// the result, but has the following advantages: +// FIXME: say something more useful than "almost the same"? +// There are open questions here: `read` requires the value to be fully valid, e.g. if `T` is a +// `bool` it must be 0 or 1, if it is a reference then it must be dereferenceable. `drop_in_place` +// only requires that `*to_drop` be "valid for dropping" and we have not defined what that means. In +// Miri it currently (May 2024) requires nothing at all for types without drop glue. /// /// * It is *required* to use `drop_in_place` to drop unsized types like /// trait objects, because they can't be read out onto the stack and diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs index cc66da25795d..8988229be2e5 100644 --- a/library/core/src/str/pattern.rs +++ b/library/core/src/str/pattern.rs @@ -342,7 +342,7 @@ pub unsafe trait ReverseSearcher<'a>: Searcher<'a> { /// /// `(&str)::Searcher` is not a `DoubleEndedSearcher` because /// the pattern `"aa"` in the haystack `"aaa"` matches as either -/// `"[aa]a"` or `"a[aa]"`, depending from which side it is searched. +/// `"[aa]a"` or `"a[aa]"`, depending on which side it is searched. pub trait DoubleEndedSearcher<'a>: ReverseSearcher<'a> {} ///////////////////////////////////////////////////////////////////////////// diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 89202e7bb8dd..dfa58e4f46d0 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -348,7 +348,7 @@ impl Duration { #[inline] pub const fn from_weeks(weeks: u64) -> Duration { if weeks > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY * DAYS_PER_WEEK) { - panic!("overflow in Duration::from_days"); + panic!("overflow in Duration::from_weeks"); } Duration::from_secs(weeks * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY * DAYS_PER_WEEK) diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs index 0fed854318d5..9d2912c4b22d 100644 --- a/library/core/tests/num/mod.rs +++ b/library/core/tests/num/mod.rs @@ -729,7 +729,7 @@ assume_usize_width! { } macro_rules! test_float { - ($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr, $min: expr, $max: expr, $min_pos: expr) => { + ($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr, $min: expr, $max: expr, $min_pos: expr, $max_exp:expr) => { mod $modname { #[test] fn min() { @@ -880,6 +880,27 @@ macro_rules! test_float { assert!(($nan as $fty).midpoint(1.0).is_nan()); assert!((1.0 as $fty).midpoint($nan).is_nan()); assert!(($nan as $fty).midpoint($nan).is_nan()); + + // test if large differences in magnitude are still correctly computed. + // NOTE: that because of how small x and y are, x + y can never overflow + // so (x + y) / 2.0 is always correct + // in particular, `2.pow(i)` will never be at the max exponent, so it could + // be safely doubled, while j is significantly smaller. + for i in $max_exp.saturating_sub(64)..$max_exp { + for j in 0..64u8 { + let large = <$fty>::from(2.0f32).powi(i); + // a much smaller number, such that there is no chance of overflow to test + // potential double rounding in midpoint's implementation. + let small = <$fty>::from(2.0f32).powi($max_exp - 1) + * <$fty>::EPSILON + * <$fty>::from(j); + + let naive = (large + small) / 2.0; + let midpoint = large.midpoint(small); + + assert_eq!(naive, midpoint); + } + } } #[test] fn rem_euclid() { @@ -912,7 +933,8 @@ test_float!( f32::NAN, f32::MIN, f32::MAX, - f32::MIN_POSITIVE + f32::MIN_POSITIVE, + f32::MAX_EXP ); test_float!( f64, @@ -922,5 +944,6 @@ test_float!( f64::NAN, f64::MIN, f64::MAX, - f64::MIN_POSITIVE + f64::MIN_POSITIVE, + f64::MAX_EXP ); diff --git a/library/proc_macro/src/bridge/fxhash.rs b/library/proc_macro/src/bridge/fxhash.rs index f4e905441972..f9f74c63fc4f 100644 --- a/library/proc_macro/src/bridge/fxhash.rs +++ b/library/proc_macro/src/bridge/fxhash.rs @@ -69,7 +69,7 @@ impl Hasher for FxHasher { hash.add_to_hash(u16::from_ne_bytes(bytes[..2].try_into().unwrap()) as usize); bytes = &bytes[2..]; } - if (size_of::() > 1) && bytes.len() >= 1 { + if (size_of::() > 1) && !bytes.is_empty() { hash.add_to_hash(bytes[0] as usize); } self.hash = hash.hash; diff --git a/library/proc_macro/src/bridge/rpc.rs b/library/proc_macro/src/bridge/rpc.rs index 6d75a5a627c8..202a8e04543b 100644 --- a/library/proc_macro/src/bridge/rpc.rs +++ b/library/proc_macro/src/bridge/rpc.rs @@ -264,9 +264,9 @@ impl From> for PanicMessage { } } -impl Into> for PanicMessage { - fn into(self) -> Box { - match self { +impl From for Box { + fn from(val: PanicMessage) -> Self { + match val { PanicMessage::StaticStr(s) => Box::new(s), PanicMessage::String(s) => Box::new(s), PanicMessage::Unknown => { diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 6f8ac17f12c7..4d649f8a6f13 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -318,22 +318,25 @@ impl Error for VarError { /// /// # Safety /// -/// Even though this function is currently not marked as `unsafe`, it needs to -/// be because invoking it can cause undefined behaviour. The function will be -/// marked `unsafe` in a future version of Rust. This is tracked in -/// [rust#27970](https://github.com/rust-lang/rust/issues/27970). -/// /// This function is safe to call in a single-threaded program. /// -/// In multi-threaded programs, you must ensure that are no other threads -/// concurrently writing or *reading*(!) from the environment through functions -/// other than the ones in this module. You are responsible for figuring out -/// how to achieve this, but we strongly suggest not using `set_var` or -/// `remove_var` in multi-threaded programs at all. +/// This function is also always safe to call on Windows, in single-threaded +/// and multi-threaded programs. /// -/// Most C libraries, including libc itself do not advertise which functions -/// read from the environment. Even functions from the Rust standard library do -/// that, e.g. for DNS lookups from [`std::net::ToSocketAddrs`]. +/// In multi-threaded programs on other operating systems, we strongly suggest +/// not using `set_var` or `remove_var` at all. The exact requirement is: you +/// must ensure that there are no other threads concurrently writing or +/// *reading*(!) the environment through functions or global variables other +/// than the ones in this module. The problem is that these operating systems +/// do not provide a thread-safe way to read the environment, and most C +/// libraries, including libc itself, do not advertise which functions read +/// from the environment. Even functions from the Rust standard library may +/// read the environment without going through this module, e.g. for DNS +/// lookups from [`std::net::ToSocketAddrs`]. No stable guarantee is made about +/// which functions may read from the environment in future versions of a +/// library. All this makes it not practically possible for you to guarantee +/// that no other thread will read the environment, so the only safe option is +/// to not use `set_var` or `remove_var` in multi-threaded programs at all. /// /// Discussion of this unsafety on Unix may be found in: /// @@ -353,15 +356,26 @@ impl Error for VarError { /// use std::env; /// /// let key = "KEY"; -/// env::set_var(key, "VALUE"); +/// unsafe { +/// env::set_var(key, "VALUE"); +/// } /// assert_eq!(env::var(key), Ok("VALUE".to_string())); /// ``` +#[cfg(not(bootstrap))] +#[rustc_deprecated_safe_2024] #[stable(feature = "env", since = "1.0.0")] -pub fn set_var, V: AsRef>(key: K, value: V) { +pub unsafe fn set_var, V: AsRef>(key: K, value: V) { _set_var(key.as_ref(), value.as_ref()) } -fn _set_var(key: &OsStr, value: &OsStr) { +#[cfg(bootstrap)] +#[allow(missing_docs)] +#[stable(feature = "env", since = "1.0.0")] +pub fn set_var, V: AsRef>(key: K, value: V) { + unsafe { _set_var(key.as_ref(), value.as_ref()) } +} + +unsafe fn _set_var(key: &OsStr, value: &OsStr) { os_imp::setenv(key, value).unwrap_or_else(|e| { panic!("failed to set environment variable `{key:?}` to `{value:?}`: {e}") }) @@ -371,22 +385,25 @@ fn _set_var(key: &OsStr, value: &OsStr) { /// /// # Safety /// -/// Even though this function is currently not marked as `unsafe`, it needs to -/// be because invoking it can cause undefined behaviour. The function will be -/// marked `unsafe` in a future version of Rust. This is tracked in -/// [rust#27970](https://github.com/rust-lang/rust/issues/27970). -/// /// This function is safe to call in a single-threaded program. /// -/// In multi-threaded programs, you must ensure that are no other threads -/// concurrently writing or *reading*(!) from the environment through functions -/// other than the ones in this module. You are responsible for figuring out -/// how to achieve this, but we strongly suggest not using `set_var` or -/// `remove_var` in multi-threaded programs at all. +/// This function is also always safe to call on Windows, in single-threaded +/// and multi-threaded programs. /// -/// Most C libraries, including libc itself do not advertise which functions -/// read from the environment. Even functions from the Rust standard library do -/// that, e.g. for DNS lookups from [`std::net::ToSocketAddrs`]. +/// In multi-threaded programs on other operating systems, we strongly suggest +/// not using `set_var` or `remove_var` at all. The exact requirement is: you +/// must ensure that there are no other threads concurrently writing or +/// *reading*(!) the environment through functions or global variables other +/// than the ones in this module. The problem is that these operating systems +/// do not provide a thread-safe way to read the environment, and most C +/// libraries, including libc itself, do not advertise which functions read +/// from the environment. Even functions from the Rust standard library may +/// read the environment without going through this module, e.g. for DNS +/// lookups from [`std::net::ToSocketAddrs`]. No stable guarantee is made about +/// which functions may read from the environment in future versions of a +/// library. All this makes it not practically possible for you to guarantee +/// that no other thread will read the environment, so the only safe option is +/// to not use `set_var` or `remove_var` in multi-threaded programs at all. /// /// Discussion of this unsafety on Unix may be found in: /// @@ -403,22 +420,35 @@ fn _set_var(key: &OsStr, value: &OsStr) { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::env; /// /// let key = "KEY"; -/// env::set_var(key, "VALUE"); +/// unsafe { +/// env::set_var(key, "VALUE"); +/// } /// assert_eq!(env::var(key), Ok("VALUE".to_string())); /// -/// env::remove_var(key); +/// unsafe { +/// env::remove_var(key); +/// } /// assert!(env::var(key).is_err()); /// ``` +#[cfg(not(bootstrap))] +#[rustc_deprecated_safe_2024] #[stable(feature = "env", since = "1.0.0")] -pub fn remove_var>(key: K) { +pub unsafe fn remove_var>(key: K) { _remove_var(key.as_ref()) } -fn _remove_var(key: &OsStr) { +#[cfg(bootstrap)] +#[allow(missing_docs)] +#[stable(feature = "env", since = "1.0.0")] +pub fn remove_var>(key: K) { + unsafe { _remove_var(key.as_ref()) } +} + +unsafe fn _remove_var(key: &OsStr) { os_imp::unsetenv(key) .unwrap_or_else(|e| panic!("failed to remove environment variable `{key:?}`: {e}")) } diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 77e94365b08e..0dcf554770c5 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -767,11 +767,33 @@ fn buffer_capacity_required(mut file: &File) -> Option { #[stable(feature = "rust1", since = "1.0.0")] impl Read for &File { + /// Read some bytes from the file. + /// + /// See [`Read::read`] docs for more info. + /// + /// # Platform-specific behavior + /// + /// This function currently corresponds to the `read` function on Unix and + /// the `NtReadFile` function on Windows. Note that this [may change in + /// the future][changes]. + /// + /// [changes]: io#platform-specific-behavior #[inline] fn read(&mut self, buf: &mut [u8]) -> io::Result { self.inner.read(buf) } + /// Like `read`, except that it reads into a slice of buffers. + /// + /// See [`Read::read_vectored`] docs for more info. + /// + /// # Platform-specific behavior + /// + /// This function currently corresponds to the `readv` function on Unix and + /// falls back to the `read` implementation on Windows. Note that this + /// [may change in the future][changes]. + /// + /// [changes]: io#platform-specific-behavior #[inline] fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { self.inner.read_vectored(bufs) @@ -782,6 +804,16 @@ impl Read for &File { self.inner.read_buf(cursor) } + /// Determines if `File` has an efficient `read_vectored` implementation. + /// + /// See [`Read::is_read_vectored`] docs for more info. + /// + /// # Platform-specific behavior + /// + /// This function currently returns `true` on Unix an `false` on Windows. + /// Note that this [may change in the future][changes]. + /// + /// [changes]: io#platform-specific-behavior #[inline] fn is_read_vectored(&self) -> bool { self.inner.is_read_vectored() @@ -803,19 +835,63 @@ impl Read for &File { } #[stable(feature = "rust1", since = "1.0.0")] impl Write for &File { + /// Write some bytes from the file. + /// + /// See [`Write::write`] docs for more info. + /// + /// # Platform-specific behavior + /// + /// This function currently corresponds to the `write` function on Unix and + /// the `NtWriteFile` function on Windows. Note that this [may change in + /// the future][changes]. + /// + /// [changes]: io#platform-specific-behavior fn write(&mut self, buf: &[u8]) -> io::Result { self.inner.write(buf) } + /// Like `write`, except that it writes into a slice of buffers. + /// + /// See [`Write::write_vectored`] docs for more info. + /// + /// # Platform-specific behavior + /// + /// This function currently corresponds to the `writev` function on Unix + /// and falls back to the `write` implementation on Windows. Note that this + /// [may change in the future][changes]. + /// + /// [changes]: io#platform-specific-behavior fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { self.inner.write_vectored(bufs) } + /// Determines if `File` has an efficient `write_vectored` implementation. + /// + /// See [`Write::is_write_vectored`] docs for more info. + /// + /// # Platform-specific behavior + /// + /// This function currently returns `true` on Unix an `false` on Windows. + /// Note that this [may change in the future][changes]. + /// + /// [changes]: io#platform-specific-behavior #[inline] fn is_write_vectored(&self) -> bool { self.inner.is_write_vectored() } + /// Flushes the file, ensuring that all intermediately buffered contents + /// reach their destination. + /// + /// See [`Write::flush`] docs for more info. + /// + /// # Platform-specific behavior + /// + /// Since a `File` structure doesn't contain any buffers, this function is + /// currently a no-op on Unix and Windows. Note that this [may change in + /// the future][changes]. + /// + /// [changes]: io#platform-specific-behavior #[inline] fn flush(&mut self) -> io::Result<()> { self.inner.flush() diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index fc830baccedd..6b9f70da8547 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -5,7 +5,7 @@ use crate::mem::MaybeUninit; use crate::panic::{RefUnwindSafe, UnwindSafe}; use crate::sync::Once; -/// A synchronization primitive which can be written to only once. +/// A synchronization primitive which can nominally be written to only once. /// /// This type is a thread-safe [`OnceCell`], and can be used in statics. /// diff --git a/library/std/src/sys/pal/hermit/os.rs b/library/std/src/sys/pal/hermit/os.rs index cc6781238319..91247d30462f 100644 --- a/library/std/src/sys/pal/hermit/os.rs +++ b/library/std/src/sys/pal/hermit/os.rs @@ -172,18 +172,14 @@ pub fn getenv(k: &OsStr) -> Option { unsafe { ENV.as_ref().unwrap().lock().unwrap().get_mut(k).cloned() } } -pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { - unsafe { - let (k, v) = (k.to_owned(), v.to_owned()); - ENV.as_ref().unwrap().lock().unwrap().insert(k, v); - } +pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { + let (k, v) = (k.to_owned(), v.to_owned()); + ENV.as_ref().unwrap().lock().unwrap().insert(k, v); Ok(()) } -pub fn unsetenv(k: &OsStr) -> io::Result<()> { - unsafe { - ENV.as_ref().unwrap().lock().unwrap().remove(k); - } +pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> { + ENV.as_ref().unwrap().lock().unwrap().remove(k); Ok(()) } diff --git a/library/std/src/sys/pal/sgx/os.rs b/library/std/src/sys/pal/sgx/os.rs index 86f4c7d3d56d..c021300d4ae3 100644 --- a/library/std/src/sys/pal/sgx/os.rs +++ b/library/std/src/sys/pal/sgx/os.rs @@ -157,13 +157,13 @@ pub fn getenv(k: &OsStr) -> Option { get_env_store().and_then(|s| s.lock().unwrap().get(k).cloned()) } -pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { +pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { let (k, v) = (k.to_owned(), v.to_owned()); create_env_store().lock().unwrap().insert(k, v); Ok(()) } -pub fn unsetenv(k: &OsStr) -> io::Result<()> { +pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> { if let Some(env) = get_env_store() { env.lock().unwrap().remove(k); } diff --git a/library/std/src/sys/pal/solid/os.rs b/library/std/src/sys/pal/solid/os.rs index ef35d8788a23..ac90aae4ebe4 100644 --- a/library/std/src/sys/pal/solid/os.rs +++ b/library/std/src/sys/pal/solid/os.rs @@ -191,7 +191,7 @@ pub fn getenv(k: &OsStr) -> Option { .flatten() } -pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { +pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { run_with_cstr(k.as_bytes(), &|k| { run_with_cstr(v.as_bytes(), &|v| { let _guard = ENV_LOCK.write(); @@ -200,7 +200,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { }) } -pub fn unsetenv(n: &OsStr) -> io::Result<()> { +pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> { run_with_cstr(n.as_bytes(), &|nbuf| { let _guard = ENV_LOCK.write(); cvt_env(unsafe { libc::unsetenv(nbuf.as_ptr()) }).map(drop) diff --git a/library/std/src/sys/pal/teeos/os.rs b/library/std/src/sys/pal/teeos/os.rs index e54a92f01f86..3be0846a6dd4 100644 --- a/library/std/src/sys/pal/teeos/os.rs +++ b/library/std/src/sys/pal/teeos/os.rs @@ -109,11 +109,11 @@ pub fn getenv(_: &OsStr) -> Option { None } -pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { +pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { Err(io::Error::new(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) } -pub fn unsetenv(_: &OsStr) -> io::Result<()> { +pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { Err(io::Error::new(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) } diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs index 58838c5876eb..0b27977df2fd 100644 --- a/library/std/src/sys/pal/uefi/os.rs +++ b/library/std/src/sys/pal/uefi/os.rs @@ -203,11 +203,11 @@ pub fn getenv(_: &OsStr) -> Option { None } -pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { +pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) } -pub fn unsetenv(_: &OsStr) -> io::Result<()> { +pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) } diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index fbbd40bfb796..dbaf86d73a61 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -1557,6 +1557,8 @@ impl fmt::Debug for File { target_os = "netbsd", target_os = "openbsd", target_os = "vxworks", + target_os = "solaris", + target_os = "illumos", target_vendor = "apple", ))] fn get_mode(fd: c_int) -> Option<(bool, bool)> { @@ -1579,6 +1581,8 @@ impl fmt::Debug for File { target_os = "netbsd", target_os = "openbsd", target_os = "vxworks", + target_os = "solaris", + target_os = "illumos", target_vendor = "apple", )))] fn get_mode(_fd: c_int) -> Option<(bool, bool)> { @@ -1910,8 +1914,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { // The code below ensures that `FreeOnDrop` is never a null pointer unsafe { // `copyfile_state_free` returns -1 if the `to` or `from` files - // cannot be closed. However, this is not considered this an - // error. + // cannot be closed. However, this is not considered an error. libc::copyfile_state_free(self.0); } } diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index 8afc49f52274..b5c7d30da7bc 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -675,19 +675,19 @@ pub fn getenv(k: &OsStr) -> Option { .flatten() } -pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { +pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { run_with_cstr(k.as_bytes(), &|k| { run_with_cstr(v.as_bytes(), &|v| { let _guard = ENV_LOCK.write(); - cvt(unsafe { libc::setenv(k.as_ptr(), v.as_ptr(), 1) }).map(drop) + cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop) }) }) } -pub fn unsetenv(n: &OsStr) -> io::Result<()> { +pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> { run_with_cstr(n.as_bytes(), &|nbuf| { let _guard = ENV_LOCK.write(); - cvt(unsafe { libc::unsetenv(nbuf.as_ptr()) }).map(drop) + cvt(libc::unsetenv(nbuf.as_ptr())).map(drop) }) } diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 853ef8736de2..1ab54ec57c3b 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -717,5 +717,14 @@ unsafe fn min_stack_size(_: *const libc::pthread_attr_t) -> usize { #[cfg(target_os = "netbsd")] unsafe fn min_stack_size(_: *const libc::pthread_attr_t) -> usize { - 2048 // just a guess + static STACK: crate::sync::OnceLock = crate::sync::OnceLock::new(); + + *STACK.get_or_init(|| { + let mut stack = unsafe { libc::sysconf(libc::_SC_THREAD_STACK_MIN) }; + if stack < 0 { + stack = 2048; // just a guess + } + + stack as usize + }) } diff --git a/library/std/src/sys/pal/unsupported/os.rs b/library/std/src/sys/pal/unsupported/os.rs index 248b34829f2e..3be98898bbeb 100644 --- a/library/std/src/sys/pal/unsupported/os.rs +++ b/library/std/src/sys/pal/unsupported/os.rs @@ -96,11 +96,11 @@ pub fn getenv(_: &OsStr) -> Option { None } -pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { +pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) } -pub fn unsetenv(_: &OsStr) -> io::Result<()> { +pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) } diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs index ee377b6ef791..e96296997e6a 100644 --- a/library/std/src/sys/pal/wasi/os.rs +++ b/library/std/src/sys/pal/wasi/os.rs @@ -244,7 +244,7 @@ pub fn getenv(k: &OsStr) -> Option { .flatten() } -pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { +pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { run_with_cstr(k.as_bytes(), &|k| { run_with_cstr(v.as_bytes(), &|v| unsafe { let _guard = env_write_lock(); @@ -253,7 +253,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { }) } -pub fn unsetenv(n: &OsStr) -> io::Result<()> { +pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> { run_with_cstr(n.as_bytes(), &|nbuf| unsafe { let _guard = env_write_lock(); cvt(libc::unsetenv(nbuf.as_ptr())).map(drop) diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs index 64d8b72aed28..483b8b0072c8 100644 --- a/library/std/src/sys/pal/windows/os.rs +++ b/library/std/src/sys/pal/windows/os.rs @@ -302,16 +302,16 @@ pub fn getenv(k: &OsStr) -> Option { .ok() } -pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { +pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { let k = to_u16s(k)?; let v = to_u16s(v)?; - cvt(unsafe { c::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr()) }).map(drop) + cvt(c::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr())).map(drop) } -pub fn unsetenv(n: &OsStr) -> io::Result<()> { +pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> { let v = to_u16s(n)?; - cvt(unsafe { c::SetEnvironmentVariableW(v.as_ptr(), ptr::null()) }).map(drop) + cvt(c::SetEnvironmentVariableW(v.as_ptr(), ptr::null())).map(drop) } pub fn temp_dir() -> PathBuf { diff --git a/library/std/src/sys/pal/xous/os.rs b/library/std/src/sys/pal/xous/os.rs index 8d2eaee8aa61..9be09eed6298 100644 --- a/library/std/src/sys/pal/xous/os.rs +++ b/library/std/src/sys/pal/xous/os.rs @@ -149,11 +149,11 @@ pub fn getenv(_: &OsStr) -> Option { None } -pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { +pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) } -pub fn unsetenv(_: &OsStr) -> io::Result<()> { +pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) } diff --git a/library/std/src/sys/pal/zkvm/os.rs b/library/std/src/sys/pal/zkvm/os.rs index 759beb2d306b..e7d6cd52a258 100644 --- a/library/std/src/sys/pal/zkvm/os.rs +++ b/library/std/src/sys/pal/zkvm/os.rs @@ -115,11 +115,11 @@ pub fn getenv(varname: &OsStr) -> Option { Some(OsString::from_inner(os_str::Buf { inner: u8s.to_vec() })) } -pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { +pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) } -pub fn unsetenv(_: &OsStr) -> io::Result<()> { +pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) } diff --git a/library/std/src/sys/thread_local/fast_local/eager.rs b/library/std/src/sys/thread_local/fast_local/eager.rs index c2bc580530ba..b97bd9cc88ce 100644 --- a/library/std/src/sys/thread_local/fast_local/eager.rs +++ b/library/std/src/sys/thread_local/fast_local/eager.rs @@ -21,43 +21,35 @@ impl Storage { Storage { state: Cell::new(State::Initial), val: UnsafeCell::new(val) } } - /// Get a reference to the TLS value. If the TLS variable has been destroyed, - /// `None` is returned. + /// Get a pointer to the TLS value. If the TLS variable has been destroyed, + /// a null pointer is returned. + /// + /// The resulting pointer may not be used after thread destruction has + /// occurred. /// /// # Safety - /// * The `self` reference must remain valid until the TLS destructor has been - /// run. - /// * The returned reference may only be used until thread destruction occurs - /// and may not be used after reentrant initialization has occurred. - /// - // FIXME(#110897): return NonNull instead of lying about the lifetime. + /// The `self` reference must remain valid until the TLS destructor is run. #[inline] - pub unsafe fn get(&self) -> Option<&'static T> { + pub unsafe fn get(&self) -> *const T { match self.state.get() { - // SAFETY: as the state is not `Destroyed`, the value cannot have - // been destroyed yet. The reference fulfills the terms outlined - // above. - State::Alive => unsafe { Some(&*self.val.get()) }, - State::Destroyed => None, + State::Alive => self.val.get(), + State::Destroyed => ptr::null(), State::Initial => unsafe { self.initialize() }, } } #[cold] - unsafe fn initialize(&self) -> Option<&'static T> { + unsafe fn initialize(&self) -> *const T { // Register the destructor // SAFETY: - // * the destructor will be called at thread destruction. - // * the caller guarantees that `self` will be valid until that time. + // The caller guarantees that `self` will be valid until thread destruction. unsafe { register_dtor(ptr::from_ref(self).cast_mut().cast(), destroy::); } + self.state.set(State::Alive); - // SAFETY: as the state is not `Destroyed`, the value cannot have - // been destroyed yet. The reference fulfills the terms outlined - // above. - unsafe { Some(&*self.val.get()) } + self.val.get() } } diff --git a/library/std/src/sys/thread_local/fast_local/lazy.rs b/library/std/src/sys/thread_local/fast_local/lazy.rs index c2e9a1714546..c1ada35d484d 100644 --- a/library/std/src/sys/thread_local/fast_local/lazy.rs +++ b/library/std/src/sys/thread_local/fast_local/lazy.rs @@ -39,49 +39,31 @@ where Storage { state: UnsafeCell::new(State::Initial) } } - /// Get a reference to the TLS value, potentially initializing it with the - /// provided parameters. If the TLS variable has been destroyed, `None` is - /// returned. + /// Get a pointer to the TLS value, potentially initializing it with the + /// provided parameters. If the TLS variable has been destroyed, a null + /// pointer is returned. + /// + /// The resulting pointer may not be used after reentrant inialialization + /// or thread destruction has occurred. /// /// # Safety - /// * The `self` reference must remain valid until the TLS destructor is run, - /// at which point the returned reference is invalidated. - /// * The returned reference may only be used until thread destruction occurs - /// and may not be used after reentrant initialization has occurred. - /// - // FIXME(#110897): return NonNull instead of lying about the lifetime. + /// The `self` reference must remain valid until the TLS destructor is run. #[inline] - pub unsafe fn get_or_init( - &self, - i: Option<&mut Option>, - f: impl FnOnce() -> T, - ) -> Option<&'static T> { - // SAFETY: - // No mutable reference to the inner value exists outside the calls to - // `replace`. The lifetime of the returned reference fulfills the terms - // outlined above. + pub unsafe fn get_or_init(&self, i: Option<&mut Option>, f: impl FnOnce() -> T) -> *const T { let state = unsafe { &*self.state.get() }; match state { - State::Alive(v) => Some(v), - State::Destroyed(_) => None, + State::Alive(v) => v, + State::Destroyed(_) => ptr::null(), State::Initial => unsafe { self.initialize(i, f) }, } } #[cold] - unsafe fn initialize( - &self, - i: Option<&mut Option>, - f: impl FnOnce() -> T, - ) -> Option<&'static T> { + unsafe fn initialize(&self, i: Option<&mut Option>, f: impl FnOnce() -> T) -> *const T { // Perform initialization let v = i.and_then(Option::take).unwrap_or_else(f); - // SAFETY: - // If references to the inner value exist, they were created in `f` - // and are invalidated here. The caller promises to never use them - // after this. let old = unsafe { self.state.get().replace(State::Alive(v)) }; match old { // If the variable is not being recursively initialized, register @@ -92,12 +74,10 @@ where val => drop(val), } - // SAFETY: - // Initialization was completed and the state was set to `Alive`, so the - // reference fulfills the terms outlined above. + // SAFETY: the state was just set to `Alive` unsafe { let State::Alive(v) = &*self.state.get() else { unreachable_unchecked() }; - Some(v) + v } } } diff --git a/library/std/src/sys/thread_local/fast_local/mod.rs b/library/std/src/sys/thread_local/fast_local/mod.rs index 25379071cb7a..575d60de4ee9 100644 --- a/library/std/src/sys/thread_local/fast_local/mod.rs +++ b/library/std/src/sys/thread_local/fast_local/mod.rs @@ -1,7 +1,7 @@ //! Thread local support for platforms with native TLS. //! //! To achieve the best performance, we choose from four different types for -//! the TLS variable, depending from the method of initialization used (`const` +//! the TLS variable, depending on the method of initialization used (`const` //! or lazy) and the drop requirements of the stored type: //! //! | | `Drop` | `!Drop` | @@ -52,32 +52,26 @@ pub macro thread_local_inner { (@key $t:ty, const $init:expr) => {{ const __INIT: $t = $init; - #[inline] - #[deny(unsafe_op_in_unsafe_fn)] - unsafe fn __getit( - _init: $crate::option::Option<&mut $crate::option::Option<$t>>, - ) -> $crate::option::Option<&'static $t> { - use $crate::thread::local_impl::EagerStorage; - use $crate::mem::needs_drop; - use $crate::ptr::addr_of; - - if needs_drop::<$t>() { - #[thread_local] - static VAL: EagerStorage<$t> = EagerStorage::new(__INIT); - unsafe { - VAL.get() - } - } else { - #[thread_local] - static VAL: $t = __INIT; - unsafe { - $crate::option::Option::Some(&*addr_of!(VAL)) - } - } - } - unsafe { - $crate::thread::LocalKey::new(__getit) + use $crate::mem::needs_drop; + use $crate::thread::LocalKey; + use $crate::thread::local_impl::EagerStorage; + + LocalKey::new(const { + if needs_drop::<$t>() { + |_| { + #[thread_local] + static VAL: EagerStorage<$t> = EagerStorage::new(__INIT); + VAL.get() + } + } else { + |_| { + #[thread_local] + static VAL: $t = __INIT; + &VAL + } + } + }) } }}, @@ -88,31 +82,26 @@ pub macro thread_local_inner { $init } - #[inline] - #[deny(unsafe_op_in_unsafe_fn)] - unsafe fn __getit( - init: $crate::option::Option<&mut $crate::option::Option<$t>>, - ) -> $crate::option::Option<&'static $t> { - use $crate::thread::local_impl::LazyStorage; - use $crate::mem::needs_drop; - - if needs_drop::<$t>() { - #[thread_local] - static VAL: LazyStorage<$t, ()> = LazyStorage::new(); - unsafe { - VAL.get_or_init(init, __init) - } - } else { - #[thread_local] - static VAL: LazyStorage<$t, !> = LazyStorage::new(); - unsafe { - VAL.get_or_init(init, __init) - } - } - } - unsafe { - $crate::thread::LocalKey::new(__getit) + use $crate::mem::needs_drop; + use $crate::thread::LocalKey; + use $crate::thread::local_impl::LazyStorage; + + LocalKey::new(const { + if needs_drop::<$t>() { + |init| { + #[thread_local] + static VAL: LazyStorage<$t, ()> = LazyStorage::new(); + VAL.get_or_init(init, __init) + } + } else { + |init| { + #[thread_local] + static VAL: LazyStorage<$t, !> = LazyStorage::new(); + VAL.get_or_init(init, __init) + } + } + }) } }}, ($(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $($init:tt)*) => { diff --git a/library/std/src/sys/thread_local/os_local.rs b/library/std/src/sys/thread_local/os_local.rs index d6ddbb78a9c8..ee5adef66eac 100644 --- a/library/std/src/sys/thread_local/os_local.rs +++ b/library/std/src/sys/thread_local/os_local.rs @@ -16,30 +16,22 @@ pub macro thread_local_inner { }, // used to generate the `LocalKey` value for `thread_local!` - (@key $t:ty, $init:expr) => { - { - #[inline] - fn __init() -> $t { $init } + (@key $t:ty, $init:expr) => {{ + #[inline] + fn __init() -> $t { $init } - // `#[inline] does not work on windows-gnu due to linking errors around dllimports. - // See https://github.com/rust-lang/rust/issues/109797. - #[cfg_attr(not(windows), inline)] - unsafe fn __getit( - init: $crate::option::Option<&mut $crate::option::Option<$t>>, - ) -> $crate::option::Option<&'static $t> { - use $crate::thread::local_impl::Key; + unsafe { + use $crate::thread::LocalKey; + use $crate::thread::local_impl::Key; - static __KEY: Key<$t> = Key::new(); - unsafe { - __KEY.get(init, __init) - } - } - - unsafe { - $crate::thread::LocalKey::new(__getit) - } + // Inlining does not work on windows-gnu due to linking errors around + // dllimports. See https://github.com/rust-lang/rust/issues/109797. + LocalKey::new(#[cfg_attr(windows, inline(never))] |init| { + static VAL: Key<$t> = Key::new(); + VAL.get(init, __init) + }) } - }, + }}, ($(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $($init:tt)*) => { $(#[$attr])* $vis const $name: $crate::thread::LocalKey<$t> = $crate::thread::local_impl::thread_local_inner!(@key $t, $($init)*); @@ -67,38 +59,33 @@ impl Key { Key { os: OsKey::new(Some(destroy_value::)), marker: PhantomData } } - /// Get the value associated with this key, initializating it if necessary. + /// Get a pointer to the TLS value, potentially initializing it with the + /// provided parameters. If the TLS variable has been destroyed, a null + /// pointer is returned. /// - /// # Safety - /// * the returned reference must not be used after recursive initialization - /// or thread destruction occurs. - pub unsafe fn get( - &'static self, - i: Option<&mut Option>, - f: impl FnOnce() -> T, - ) -> Option<&'static T> { + /// The resulting pointer may not be used after reentrant inialialization + /// or thread destruction has occurred. + pub fn get(&'static self, i: Option<&mut Option>, f: impl FnOnce() -> T) -> *const T { // SAFETY: (FIXME: get should actually be safe) let ptr = unsafe { self.os.get() as *mut Value }; if ptr.addr() > 1 { // SAFETY: the check ensured the pointer is safe (its destructor // is not running) + it is coming from a trusted source (self). - unsafe { Some(&(*ptr).value) } + unsafe { &(*ptr).value } } else { - // SAFETY: At this point we are sure we have no value and so - // initializing (or trying to) is safe. - unsafe { self.try_initialize(ptr, i, f) } + self.try_initialize(ptr, i, f) } } - unsafe fn try_initialize( + fn try_initialize( &'static self, ptr: *mut Value, i: Option<&mut Option>, f: impl FnOnce() -> T, - ) -> Option<&'static T> { + ) -> *const T { if ptr.addr() == 1 { // destructor is running - return None; + return ptr::null(); } let value = i.and_then(Option::take).unwrap_or_else(f); @@ -119,7 +106,7 @@ impl Key { } // SAFETY: We just created this value above. - unsafe { Some(&(*ptr).value) } + unsafe { &(*ptr).value } } } diff --git a/library/std/src/sys/thread_local/static_local.rs b/library/std/src/sys/thread_local/static_local.rs index 6beda2e71880..0f08cab1ae4f 100644 --- a/library/std/src/sys/thread_local/static_local.rs +++ b/library/std/src/sys/thread_local/static_local.rs @@ -13,19 +13,14 @@ pub macro thread_local_inner { (@key $t:ty, const $init:expr) => {{ const __INIT: $t = $init; - #[inline] - #[deny(unsafe_op_in_unsafe_fn)] - unsafe fn __getit( - _init: $crate::option::Option<&mut $crate::option::Option<$t>>, - ) -> $crate::option::Option<&'static $t> { + unsafe { + use $crate::thread::LocalKey; use $crate::thread::local_impl::EagerStorage; - static VAL: EagerStorage<$t> = EagerStorage { value: __INIT }; - $crate::option::Option::Some(&VAL.value) - } - - unsafe { - $crate::thread::LocalKey::new(__getit) + LocalKey::new(|_| { + static VAL: EagerStorage<$t> = EagerStorage { value: __INIT }; + &VAL.value + }) } }}, @@ -34,19 +29,14 @@ pub macro thread_local_inner { #[inline] fn __init() -> $t { $init } - #[inline] - #[deny(unsafe_op_in_unsafe_fn)] - unsafe fn __getit( - init: $crate::option::Option<&mut $crate::option::Option<$t>>, - ) -> $crate::option::Option<&'static $t> { + unsafe { + use $crate::thread::LocalKey; use $crate::thread::local_impl::LazyStorage; - static VAL: LazyStorage<$t> = LazyStorage::new(); - unsafe { $crate::option::Option::Some(VAL.get(init, __init)) } - } - - unsafe { - $crate::thread::LocalKey::new(__getit) + LocalKey::new(|init| { + static VAL: LazyStorage<$t> = LazyStorage::new(); + VAL.get(init, __init) + }) } }}, ($(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $($init:tt)*) => { @@ -73,16 +63,13 @@ impl LazyStorage { LazyStorage { value: UnsafeCell::new(None) } } - /// Gets a reference to the contained value, initializing it if necessary. + /// Get a pointer to the TLS value, potentially initializing it with the + /// provided parameters. /// - /// # Safety - /// The returned reference may not be used after reentrant initialization has occurred. + /// The resulting pointer may not be used after reentrant inialialization + /// has occurred. #[inline] - pub unsafe fn get( - &'static self, - i: Option<&mut Option>, - f: impl FnOnce() -> T, - ) -> &'static T { + pub fn get(&'static self, i: Option<&mut Option>, f: impl FnOnce() -> T) -> *const T { let value = unsafe { &*self.value.get() }; match value { Some(v) => v, @@ -91,11 +78,7 @@ impl LazyStorage { } #[cold] - unsafe fn initialize( - &'static self, - i: Option<&mut Option>, - f: impl FnOnce() -> T, - ) -> &'static T { + fn initialize(&'static self, i: Option<&mut Option>, f: impl FnOnce() -> T) -> *const T { let value = i.and_then(Option::take).unwrap_or_else(f); // Destroy the old value, after updating the TLS variable as the // destructor might reference it. diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index c1b4440e5608..aed185637fd1 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -123,7 +123,7 @@ pub struct LocalKey { // trivially devirtualizable by LLVM because the value of `inner` never // changes and the constant should be readonly within a crate. This mainly // only runs into problems when TLS statics are exported across crates. - inner: unsafe fn(Option<&mut Option>) -> Option<&'static T>, + inner: fn(Option<&mut Option>) -> *const T, } #[stable(feature = "std_debug", since = "1.16.0")] @@ -238,9 +238,7 @@ impl LocalKey { issue = "none" )] #[rustc_const_unstable(feature = "thread_local_internals", issue = "none")] - pub const unsafe fn new( - inner: unsafe fn(Option<&mut Option>) -> Option<&'static T>, - ) -> LocalKey { + pub const unsafe fn new(inner: fn(Option<&mut Option>) -> *const T) -> LocalKey { LocalKey { inner } } @@ -281,8 +279,7 @@ impl LocalKey { where F: FnOnce(&T) -> R, { - // SAFETY: `inner` is safe to call within the lifetime of the thread - let thread_local = unsafe { (self.inner)(None).ok_or(AccessError)? }; + let thread_local = unsafe { (self.inner)(None).as_ref().ok_or(AccessError)? }; Ok(f(thread_local)) } @@ -304,9 +301,8 @@ impl LocalKey { { let mut init = Some(init); - // SAFETY: `inner` is safe to call within the lifetime of the thread let reference = unsafe { - (self.inner)(Some(&mut init)).expect( + (self.inner)(Some(&mut init)).as_ref().expect( "cannot access a Thread Local Storage value \ during or after destruction", ) diff --git a/library/test/src/cli.rs b/library/test/src/cli.rs index 6ac3b3eaa797..b7d24405b775 100644 --- a/library/test/src/cli.rs +++ b/library/test/src/cli.rs @@ -200,7 +200,7 @@ Test Attributes: pub fn parse_opts(args: &[String]) -> Option { // Parse matches. let opts = optgroups(); - let binary = args.get(0).map(|c| &**c).unwrap_or("..."); + let binary = args.first().map(|c| &**c).unwrap_or("..."); let args = args.get(1..).unwrap_or(args); let matches = match opts.parse(args) { Ok(m) => m, diff --git a/library/test/src/term/terminfo/parm.rs b/library/test/src/term/terminfo/parm.rs index 2815f6cfc77f..c5b4ef01893c 100644 --- a/library/test/src/term/terminfo/parm.rs +++ b/library/test/src/term/terminfo/parm.rs @@ -524,7 +524,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result, String> { } else { let mut s_ = Vec::with_capacity(flags.width); s_.extend(repeat(b' ').take(n)); - s_.extend(s.into_iter()); + s_.extend(s); s = s_; } } diff --git a/rustfmt.toml b/rustfmt.toml index b78e96d5872f..b15ffdca38a0 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -10,9 +10,18 @@ ignore = [ "/build-*/", "/vendor/", - # Tests for now are not formatted, as they are sometimes pretty-printing constrained - # (and generally rustfmt can move around comments in UI-testing incompatible ways). - "/tests/", + # Some tests are not formatted, for various reasons. + "/tests/codegen/simd-intrinsic/", # Many types like `u8x64` are better hand-formatted. + "/tests/crashes/", # Many of these tests contain syntax errors. + "/tests/debuginfo/", # These tests are somewhat sensitive to source code layout. + "/tests/incremental/", # These tests are somewhat sensitive to source code layout. + "/tests/pretty/", # These tests are very sensitive to source code layout. + "/tests/run-make/translation/test.rs", # This test contains syntax errors. + "/tests/rustdoc/", # Some have syntax errors, some are whitespace-sensitive. + "/tests/rustdoc-gui/", # Some tests are sensitive to source code layout. + "/tests/rustdoc-ui/", # Some have syntax errors, some are whitespace-sensitive. + "/tests/ui/", # Some have syntax errors, some are whitespace-sensitive. + "/tests/ui-fulldeps/", # Some are whitespace-sensitive (e.g. `// ~ERROR` comments). # Do not format submodules. # FIXME: sync submodule list with tidy/bootstrap/etc diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 215886863624..29b3d1669b4b 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1781,25 +1781,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the .arg(builder.ensure(tool::JsonDocLint { compiler: json_compiler, target })); } - if mode == "coverage-map" { - let coverage_dump = builder.ensure(tool::CoverageDump { - compiler: compiler.with_stage(0), - target: compiler.host, - }); + if matches!(mode, "coverage-map" | "coverage-run") { + let coverage_dump = builder.tool_exe(Tool::CoverageDump); cmd.arg("--coverage-dump-path").arg(coverage_dump); } - if mode == "coverage-run" { - // The demangler doesn't need the current compiler, so we can avoid - // unnecessary rebuilds by using the bootstrap compiler instead. - let rust_demangler = builder.ensure(tool::RustDemangler { - compiler: compiler.with_stage(0), - target: compiler.host, - extra_features: Vec::new(), - }); - cmd.arg("--rust-demangler-path").arg(rust_demangler); - } - cmd.arg("--src-base").arg(builder.src.join("tests").join(suite)); cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite)); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 8312885915c5..cde090637e01 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -469,7 +469,8 @@ impl Build { // Make sure we update these before gathering metadata so we don't get an error about missing // Cargo.toml files. - let rust_submodules = ["src/tools/cargo", "library/backtrace", "library/stdarch"]; + let rust_submodules = + ["src/tools/cargo", "src/doc/book", "library/backtrace", "library/stdarch"]; for s in rust_submodules { build.update_submodule(Path::new(s)); } diff --git a/src/ci/run.sh b/src/ci/run.sh index 2e36b7e5962e..efaf70078c4a 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -90,7 +90,7 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --dist-compression-formats=xz" if [ "$EXTERNAL_LLVM" = "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.optimized-compiler-builtins" # Likewise, only demand we test all LLVM components if we know we built LLVM with them - export COMPILETEST_NEEDS_ALL_LLVM_COMPONENTS=1 + export COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS=1 elif [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then echo "error: dist builds should always use optimized compiler-rt!" >&2 exit 1 diff --git a/src/doc/book b/src/doc/book index 5e9051f71638..85442a608426 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 5e9051f71638aa941cd5dda465e25c61cde9594f +Subproject commit 85442a608426d3667f1c9458ad457b241a36b569 diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 4ef2fcebe928..201ace5ce3a7 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -30,10 +30,15 @@ - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md) - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md) - [arm-none-eabi](platform-support/arm-none-eabi.md) - - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md) - - [armv5te-none-eabi](platform-support/armv5te-none-eabi.md) - - [armv7r-none-eabi](platform-support/armv7r-none-eabi.md) - - [armv8r-none-eabihf](platform-support/armv8r-none-eabihf.md) + - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md) + - [armv5te-none-eabi](platform-support/armv5te-none-eabi.md) + - [armv7r-none-eabi](platform-support/armv7r-none-eabi.md) + - [armv8r-none-eabihf](platform-support/armv8r-none-eabihf.md) + - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md) + - [thumbv7em-none-eabi\*](./platform-support/thumbv7em-none-eabi.md) + - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md) + - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md) + - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md) - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md) - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) @@ -60,11 +65,6 @@ - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) - [riscv32*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md) - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md) - - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md) - - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md) - - [thumbv7em-none-eabi\*](./platform-support/thumbv7em-none-eabi.md) - - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md) - - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md) - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md) - [\*-nto-qnx-\*](platform-support/nto-qnx.md) - [*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md) diff --git a/src/doc/rustc/src/json.md b/src/doc/rustc/src/json.md index 32083b2f731d..c853f34ee036 100644 --- a/src/doc/rustc/src/json.md +++ b/src/doc/rustc/src/json.md @@ -217,7 +217,8 @@ Diagnostics have the following format: Artifact notifications are emitted when the [`--json=artifacts` flag][option-json] is used. They indicate that a file artifact has been saved to disk. More information about emit kinds may be found in the [`--emit` -flag][option-emit] documentation. +flag][option-emit] documentation. Notifications can contain more than one file +for each type, for example when using multiple codegen units. ```javascript { @@ -229,6 +230,11 @@ flag][option-emit] documentation. - "link": The generated crate as specified by the crate-type. - "dep-info": The `.d` file with dependency information in a Makefile-like syntax. - "metadata": The Rust `.rmeta` file containing metadata about the crate. + - "asm": The `.s` file with generated assembly + - "llvm-ir": The `.ll` file with generated textual LLVM IR + - "llvm-bc": The `.bc` file with generated LLVM bitcode + - "mir": The `.mir` file with rustc's mid-level intermediate representation. + - "obj": The `.o` file with generated native object code */ "emit": "link" } diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md index 0b1b10e4762e..de0ef322fa67 100644 --- a/src/doc/rustc/src/platform-support/arm-none-eabi.md +++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md @@ -1,6 +1,15 @@ # `{arm,thumb}*-none-eabi(hf)?` -## Tier 2 Target List +## Common Target Details + +This documentation covers details that apply to a range of bare-metal targets +for 32-bit Arm CPUs. The `arm-none-eabi` flavor of the GNU compiler toolchain is +often used to assist compilation to these targets. + +Details that apply only to only a specific target in this group are covered in +their own document. + +### Tier 2 Target List - Arm A-Profile Architectures - `armv7a-none-eabi` @@ -16,7 +25,7 @@ - *Legacy* Arm Architectures - None -## Tier 3 Target List +### Tier 3 Target List - Arm A-Profile Architectures - `armv7a-none-eabihf` @@ -28,24 +37,21 @@ - [`armv4t-none-eabi` and `thumbv4t-none-eabi`](armv4t-none-eabi.md) - [`armv5te-none-eabi` and `thumbv5te-none-eabi`](armv5te-none-eabi.md) -## Common Target Details - -This documentation covers details that apply to a range of bare-metal targets -for 32-bit Arm CPUs. In addition, target specific details may be covered in -their own document. +## Instruction Sets There are two 32-bit instruction set architectures (ISAs) defined by Arm: - The [*A32 ISA*][a32-isa], with fixed-width 32-bit instructions. Previously - known as the *Arm* ISA, this originated with the original ARM1 of 1985 and has + known as the *Arm* ISA, this originated with the original Arm1 of 1985 and has been updated by various revisions to the architecture specifications ever since. - The [*T32 ISA*][t32-isa], with a mix of 16-bit and 32-bit width instructions. Note that this term includes both the original 16-bit width *Thumb* ISA introduced with the Armv4T architecture in 1994, and the later 16/32-bit sized - *Thumb-2* ISA introduced with the Armv6T2 architecture in 2003. Again, these - ISAs have been revised by subsequent revisions to the relevant Arm - architecture specifications. + *Thumb-2* ISA introduced with the Armv6T2 architecture in 2003. + +Again, these ISAs have been revised by subsequent revisions to the relevant Arm +architecture specifications. There is also a 64-bit ISA with fixed-width 32-bit instructions called the *A64 ISA*, but targets which implement that instruction set generally start with diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md index f4c8dd46f1d0..ab8b4caaadff 100644 --- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md @@ -1,16 +1,13 @@ -# armv4t-none-eabi +# armv4t-none-eabi / thumbv4t-none-eabi Tier 3 -Bare-metal target for any cpu in the Armv4T architecture family, supporting -ARM/Thumb code interworking (aka `A32`/`T32`), with ARM code as the default code -generation. +These two targets are part of the [`arm-none-eabi`](arm-none-eabi.md) target +group, and all the information there applies. -In particular this supports the Game Boy Advance (GBA), but there's nothing -GBA-specific with this target, so any Armv4T device should work fine. - -See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all -`arm-none-eabi` targets. +Both of these targets can be used on the Game Boy Advance (GBA), among other +things. On the GBA, one should usually use the `thumb` target to get the best +overall performance. ## Target Maintainers @@ -23,6 +20,6 @@ This is a cross-compiled target that you will need to emulate during testing. Because this is a device-agnostic target, and the exact emulator that you'll need depends on the specific device you want to run your code on. -For example, when programming for the Gameboy Advance, the -[mgba-test-runner](https://github.com/agbrs/agb) program could be used to make a -normal set of rust tests be run within the `mgba` emulator. +* When building for the GBA, [mgba-test-runner](https://github.com/agbrs/agb) + can be used to make a normal set of rust tests be run within the `mgba` + emulator. diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index bdb55de8d634..39f24a13143c 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -624,47 +624,3 @@ add the `--scrape-tests` flag. This flag enables the generation of links in the source code pages which allow the reader to jump to a type definition. - -### Custom CSS classes for code blocks - -```rust -#![feature(custom_code_classes_in_docs)] - -/// ```custom,{class=language-c} -/// int main(void) { return 0; } -/// ``` -pub struct Bar; -``` - -The text `int main(void) { return 0; }` is rendered without highlighting in a code block -with the class `language-c`. This can be used to highlight other languages through JavaScript -libraries for example. - -Without the `custom` attribute, it would be generated as a Rust code example with an additional -`language-C` CSS class. Therefore, if you specifically don't want it to be a Rust code example, -don't forget to add the `custom` attribute. - -To be noted that you can replace `class=` with `.` to achieve the same result: - -```rust -#![feature(custom_code_classes_in_docs)] - -/// ```custom,{.language-c} -/// int main(void) { return 0; } -/// ``` -pub struct Bar; -``` - -To be noted, `rust` and `.rust`/`class=rust` have different effects: `rust` indicates that this is -a Rust code block whereas the two others add a "rust" CSS class on the code block. - -You can also use double quotes: - -```rust -#![feature(custom_code_classes_in_docs)] - -/// ```"not rust" {."hello everyone"} -/// int main(void) { return 0; } -/// ``` -pub struct Bar; -``` diff --git a/src/doc/rustdoc/src/write-documentation/documentation-tests.md b/src/doc/rustdoc/src/write-documentation/documentation-tests.md index a7d3186fb78b..9526f33359e4 100644 --- a/src/doc/rustdoc/src/write-documentation/documentation-tests.md +++ b/src/doc/rustdoc/src/write-documentation/documentation-tests.md @@ -376,6 +376,44 @@ that the code sample should be compiled using the respective edition of Rust. # fn foo() {} ``` +### Custom CSS classes for code blocks + +```rust +/// ```custom,{class=language-c} +/// int main(void) { return 0; } +/// ``` +pub struct Bar; +``` + +The text `int main(void) { return 0; }` is rendered without highlighting in a code block +with the class `language-c`. This can be used to highlight other languages through JavaScript +libraries for example. + +Without the `custom` attribute, it would be generated as a Rust code example with an additional +`language-C` CSS class. Therefore, if you specifically don't want it to be a Rust code example, +don't forget to add the `custom` attribute. + +To be noted that you can replace `class=` with `.` to achieve the same result: + +```rust +/// ```custom,{.language-c} +/// int main(void) { return 0; } +/// ``` +pub struct Bar; +``` + +To be noted, `rust` and `.rust`/`class=rust` have different effects: `rust` indicates that this is +a Rust code block whereas the two others add a "rust" CSS class on the code block. + +You can also use double quotes: + +```rust +/// ```"not rust" {."hello everyone"} +/// int main(void) { return 0; } +/// ``` +pub struct Bar; +``` + ## Syntax reference The *exact* syntax for code blocks, including the edge cases, can be found diff --git a/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md b/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md index e55165b53740..ab63c986e856 100644 --- a/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md +++ b/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md @@ -1,6 +1,6 @@ # `print=check-cfg` -The tracking issue for this feature is: [#XXXXXX](https://github.com/rust-lang/rust/issues/XXXXXX). +The tracking issue for this feature is: [#125704](https://github.com/rust-lang/rust/issues/125704). ------------------------ @@ -15,6 +15,7 @@ This print option works similarly to `--print=cfg` (modulo check-cfg specifics): - `cfg(feature, values("foo", "bar"))`: `feature="foo"` and `feature="bar"` - `cfg(feature, values(none(), ""))`: `feature` and `feature=""` - `cfg(feature, values(any()))`: `feature=any()` + - `cfg(feature, values())`: `feature=` - `cfg(any())`: `any()` - *nothing*: `any()=any()` diff --git a/src/doc/unstable-book/src/language-features/abi-vectorcall.md b/src/doc/unstable-book/src/language-features/abi-vectorcall.md new file mode 100644 index 000000000000..56273bfdb791 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/abi-vectorcall.md @@ -0,0 +1,19 @@ +# `abi_vectorcall` + +The tracking issue for this feature is: [#124485] + +[#124485]: https://github.com/rust-lang/rust/issues/124485 + +------------------------ + +Adds support for the Windows `"vectorcall"` ABI, the equivalent of `__vectorcall` in MSVC. + +```rust,ignore (only-windows-or-x86-or-x86-64) +extern "vectorcall" { + fn add_f64s(x: f64, y: f64) -> f64; +} + +fn main() { + println!("{}", add_f64s(2.0, 4.0)); +} +``` diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index bccad29e0a98..ac927e9a1942 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -11,7 +11,7 @@ use thin_vec::ThinVec; use crate::clean::{self, simplify, Lifetime}; use crate::clean::{ - clean_generic_param_def, clean_middle_ty, clean_predicate, clean_trait_ref_with_bindings, + clean_generic_param_def, clean_middle_ty, clean_predicate, clean_trait_ref_with_constraints, clean_ty_generics, }; use crate::core::DocContext; @@ -121,7 +121,7 @@ fn synthesize_auto_trait_impl<'tcx>( kind: Box::new(clean::ImplItem(Box::new(clean::Impl { safety: hir::Safety::Safe, generics, - trait_: Some(clean_trait_ref_with_bindings(cx, trait_ref, ThinVec::new())), + trait_: Some(clean_trait_ref_with_constraints(cx, trait_ref, ThinVec::new())), for_: clean_middle_ty(ty::Binder::dummy(ty), cx, None, None), items: Vec::new(), polarity, diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 29be3a70d54b..4c7a2ecdb53f 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -10,7 +10,7 @@ use thin_vec::ThinVec; use crate::clean; use crate::clean::{ - clean_middle_assoc_item, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty_generics, + clean_middle_assoc_item, clean_middle_ty, clean_trait_ref_with_constraints, clean_ty_generics, }; use crate::core::DocContext; @@ -95,7 +95,7 @@ pub(crate) fn synthesize_blanket_impls( ), // FIXME(eddyb) compute both `trait_` and `for_` from // the post-inference `trait_ref`, as it's more accurate. - trait_: Some(clean_trait_ref_with_bindings( + trait_: Some(clean_trait_ref_with_constraints( cx, ty::Binder::dummy(trait_ref.instantiate_identity()), ThinVec::new(), diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 2919a4c4beb0..c7366ce1a68c 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -20,7 +20,7 @@ use rustc_span::symbol::{kw, sym, Symbol}; use crate::clean::{ self, clean_bound_vars, clean_generics, clean_impl_item, clean_middle_assoc_item, - clean_middle_field, clean_middle_ty, clean_poly_fn_sig, clean_trait_ref_with_bindings, + clean_middle_field, clean_middle_ty, clean_poly_fn_sig, clean_trait_ref_with_constraints, clean_ty, clean_ty_alias_inner_type, clean_ty_generics, clean_variant_def, utils, Attributes, AttributesExt, ImplKind, ItemId, Type, }; @@ -566,7 +566,7 @@ pub(crate) fn build_impl( }; let polarity = tcx.impl_polarity(did); let trait_ = associated_trait - .map(|t| clean_trait_ref_with_bindings(cx, ty::Binder::dummy(t), ThinVec::new())); + .map(|t| clean_trait_ref_with_constraints(cx, ty::Binder::dummy(t), ThinVec::new())); if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() { super::build_deref_target_impls(cx, &trait_items, ret); } @@ -688,7 +688,7 @@ fn build_module_items( name: prim_ty.as_sym(), args: clean::GenericArgs::AngleBracketed { args: Default::default(), - bindings: ThinVec::new(), + constraints: ThinVec::new(), }, }], }, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 73737da482d0..839bfdf44af1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -231,10 +231,10 @@ fn clean_generic_bound<'tcx>( }) } -pub(crate) fn clean_trait_ref_with_bindings<'tcx>( +pub(crate) fn clean_trait_ref_with_constraints<'tcx>( cx: &mut DocContext<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, - bindings: ThinVec, + constraints: ThinVec, ) -> Path { let kind = cx.tcx.def_kind(trait_ref.def_id()).into(); if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) { @@ -245,7 +245,7 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>( cx, trait_ref.def_id(), true, - bindings, + constraints, trait_ref.map_bound(|tr| tr.args), ); @@ -254,14 +254,14 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>( path } -fn clean_poly_trait_ref_with_bindings<'tcx>( +fn clean_poly_trait_ref_with_constraints<'tcx>( cx: &mut DocContext<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, - bindings: ThinVec, + constraints: ThinVec, ) -> GenericBound { GenericBound::TraitBound( PolyTrait { - trait_: clean_trait_ref_with_bindings(cx, poly_trait_ref, bindings), + trait_: clean_trait_ref_with_constraints(cx, poly_trait_ref, constraints), generic_params: clean_bound_vars(poly_trait_ref.bound_vars()), }, hir::TraitBoundModifier::None, @@ -395,7 +395,7 @@ fn clean_poly_trait_predicate<'tcx>( let poly_trait_ref = pred.map_bound(|pred| pred.trait_ref); Some(WherePredicate::BoundPredicate { ty: clean_middle_ty(poly_trait_ref.self_ty(), cx, None, None), - bounds: vec![clean_poly_trait_ref_with_bindings(cx, poly_trait_ref, ThinVec::new())], + bounds: vec![clean_poly_trait_ref_with_constraints(cx, poly_trait_ref, ThinVec::new())], bound_params: Vec::new(), }) } @@ -481,8 +481,11 @@ fn clean_projection<'tcx>( return clean_middle_opaque_bounds(cx, bounds); } - let trait_ = - clean_trait_ref_with_bindings(cx, ty.map_bound(|ty| ty.trait_ref(cx.tcx)), ThinVec::new()); + let trait_ = clean_trait_ref_with_constraints( + cx, + ty.map_bound(|ty| ty.trait_ref(cx.tcx)), + ThinVec::new(), + ); let self_type = clean_middle_ty(ty.map_bound(|ty| ty.self_ty()), cx, None, None); let self_def_id = if let Some(def_id) = def_id { cx.tcx.opt_parent(def_id).or(Some(def_id)) @@ -522,7 +525,7 @@ fn projection_to_path_segment<'tcx>( def_id, ) .into(), - bindings: Default::default(), + constraints: Default::default(), }, } } @@ -1453,8 +1456,8 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( _ => return true, } match &assoc.args { - GenericArgs::AngleBracketed { args, bindings } => { - if !bindings.is_empty() + GenericArgs::AngleBracketed { args, constraints } => { + if !constraints.is_empty() || generics .params .iter() @@ -2135,7 +2138,7 @@ pub(crate) fn clean_middle_ty<'tcx>( let bindings = obj .projection_bounds() - .map(|pb| TypeBinding { + .map(|pb| AssocItemConstraint { assoc: projection_to_path_segment( pb.map_bound(|pb| { pb @@ -2149,7 +2152,7 @@ pub(crate) fn clean_middle_ty<'tcx>( }), cx, ), - kind: TypeBindingKind::Equality { + kind: AssocItemConstraintKind::Equality { term: clean_middle_term(pb.map_bound(|pb| pb.term), cx), }, }) @@ -2198,7 +2201,7 @@ pub(crate) fn clean_middle_ty<'tcx>( def_id, ) .into(), - bindings: Default::default(), + constraints: Default::default(), }, }, should_show_cast: false, @@ -2304,14 +2307,14 @@ fn clean_middle_opaque_bounds<'tcx>( .filter_map(|bound| { if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() { if proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder() { - Some(TypeBinding { + Some(AssocItemConstraint { assoc: projection_to_path_segment( // FIXME: This needs to be made resilient for `AliasTerm`s that // are associated consts. bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)), cx, ), - kind: TypeBindingKind::Equality { + kind: AssocItemConstraintKind::Equality { term: clean_middle_term(bound.kind().rebind(proj.term), cx), }, }) @@ -2324,7 +2327,7 @@ fn clean_middle_opaque_bounds<'tcx>( }) .collect(); - Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, bindings)) + Some(clean_poly_trait_ref_with_constraints(cx, trait_ref, bindings)) }) .collect::>(); @@ -2505,11 +2508,12 @@ fn clean_generic_args<'tcx>( cx: &mut DocContext<'tcx>, ) -> GenericArgs { // FIXME(return_type_notation): Fix RTN parens rendering - if generic_args.parenthesized == hir::GenericArgsParentheses::ParenSugar { - let output = clean_ty(generic_args.bindings[0].ty(), cx); - let output = if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None }; - let inputs = - generic_args.inputs().iter().map(|x| clean_ty(x, cx)).collect::>().into(); + if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() { + let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect::>().into(); + let output = match output.kind { + hir::TyKind::Tup(&[]) => None, + _ => Some(Box::new(clean_ty(output, cx))), + }; GenericArgs::Parenthesized { inputs, output } } else { let args = generic_args @@ -2536,9 +2540,12 @@ fn clean_generic_args<'tcx>( }) .collect::>() .into(); - let bindings = - generic_args.bindings.iter().map(|x| clean_type_binding(x, cx)).collect::>(); - GenericArgs::AngleBracketed { args, bindings } + let constraints = generic_args + .constraints + .iter() + .map(|c| clean_assoc_item_constraint(c, cx)) + .collect::>(); + GenericArgs::AngleBracketed { args, constraints } } } @@ -3107,20 +3114,20 @@ fn clean_maybe_renamed_foreign_item<'tcx>( }) } -fn clean_type_binding<'tcx>( - type_binding: &hir::TypeBinding<'tcx>, +fn clean_assoc_item_constraint<'tcx>( + constraint: &hir::AssocItemConstraint<'tcx>, cx: &mut DocContext<'tcx>, -) -> TypeBinding { - TypeBinding { +) -> AssocItemConstraint { + AssocItemConstraint { assoc: PathSegment { - name: type_binding.ident.name, - args: clean_generic_args(type_binding.gen_args, cx), + name: constraint.ident.name, + args: clean_generic_args(constraint.gen_args, cx), }, - kind: match type_binding.kind { - hir::TypeBindingKind::Equality { ref term } => { - TypeBindingKind::Equality { term: clean_hir_term(term, cx) } + kind: match constraint.kind { + hir::AssocItemConstraintKind::Equality { ref term } => { + AssocItemConstraintKind::Equality { term: clean_hir_term(term, cx) } } - hir::TypeBindingKind::Constraint { bounds } => TypeBindingKind::Constraint { + hir::AssocItemConstraintKind::Bound { bounds } => AssocItemConstraintKind::Bound { bounds: bounds.iter().filter_map(|b| clean_generic_bound(b, cx)).collect(), }, }, diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 5a3ccb6239a0..af61eb6ae8de 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -90,10 +90,10 @@ pub(crate) fn merge_bounds( let last = trait_ref.trait_.segments.last_mut().expect("segments were empty"); match last.args { - PP::AngleBracketed { ref mut bindings, .. } => { - bindings.push(clean::TypeBinding { + PP::AngleBracketed { ref mut constraints, .. } => { + constraints.push(clean::AssocItemConstraint { assoc: assoc.clone(), - kind: clean::TypeBindingKind::Equality { term: rhs.clone() }, + kind: clean::AssocItemConstraintKind::Equality { term: rhs.clone() }, }); } PP::Parenthesized { ref mut output, .. } => match output { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 7490688e36c5..b387809cc717 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1451,7 +1451,7 @@ impl Trait { tcx.trait_def(self.def_id).safety } pub(crate) fn is_object_safe(&self, tcx: TyCtxt<'_>) -> bool { - tcx.check_is_object_safe(self.def_id) + tcx.is_object_safe(self.def_id) } } @@ -1626,9 +1626,9 @@ impl Type { if let Type::ImplTrait(mut v) = self && let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _)) = v.pop() && let Some(segment) = trait_.segments.pop() - && let GenericArgs::AngleBracketed { mut bindings, .. } = segment.args - && let Some(binding) = bindings.pop() - && let TypeBindingKind::Equality { term } = binding.kind + && let GenericArgs::AngleBracketed { mut constraints, .. } = segment.args + && let Some(constraint) = constraints.pop() + && let AssocItemConstraintKind::Equality { term } = constraint.kind && let Term::Type(ty) = term { ty @@ -2133,7 +2133,9 @@ impl Discriminant { /// Will be `None` in the case of cross-crate reexports, and may be /// simplified pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> Option { - self.expr.map(|body| rendered_const(tcx, body)) + self.expr.map(|body| { + rendered_const(tcx, tcx.hir().body(body), tcx.hir().body_owner_def_id(body)) + }) } pub(crate) fn value(&self, tcx: TyCtxt<'_>, with_underscores: bool) -> String { print_evaluated_const(tcx, self.value, with_underscores, false).unwrap() @@ -2258,34 +2260,38 @@ impl GenericArg { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) enum GenericArgs { - AngleBracketed { args: Box<[GenericArg]>, bindings: ThinVec }, + AngleBracketed { args: Box<[GenericArg]>, constraints: ThinVec }, Parenthesized { inputs: Box<[Type]>, output: Option> }, } impl GenericArgs { pub(crate) fn is_empty(&self) -> bool { match self { - GenericArgs::AngleBracketed { args, bindings } => { - args.is_empty() && bindings.is_empty() + GenericArgs::AngleBracketed { args, constraints } => { + args.is_empty() && constraints.is_empty() } GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(), } } - pub(crate) fn bindings<'a>(&'a self) -> Box + 'a> { + pub(crate) fn constraints<'a>(&'a self) -> Box + 'a> { match self { - GenericArgs::AngleBracketed { bindings, .. } => Box::new(bindings.iter().cloned()), + GenericArgs::AngleBracketed { constraints, .. } => { + Box::new(constraints.iter().cloned()) + } GenericArgs::Parenthesized { output, .. } => Box::new( output .as_ref() - .map(|ty| TypeBinding { + .map(|ty| AssocItemConstraint { assoc: PathSegment { name: sym::Output, args: GenericArgs::AngleBracketed { args: Vec::new().into_boxed_slice(), - bindings: ThinVec::new(), + constraints: ThinVec::new(), }, }, - kind: TypeBindingKind::Equality { term: Term::Type((**ty).clone()) }, + kind: AssocItemConstraintKind::Equality { + term: Term::Type((**ty).clone()), + }, }) .into_iter(), ), @@ -2419,7 +2425,7 @@ impl ConstantKind { ConstantKind::TyConst { ref expr } => expr.to_string(), ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id), ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { - rendered_const(tcx, body) + rendered_const(tcx, tcx.hir().body(body), tcx.hir().body_owner_def_id(body)) } } } @@ -2544,18 +2550,27 @@ pub(crate) struct ProcMacro { pub(crate) helpers: Vec, } -/// An type binding on an associated type (e.g., `A = Bar` in `Foo` or -/// `A: Send + Sync` in `Foo`). +/// A constraint on an associated item. +/// +/// ### Examples +/// +/// * the `A = Ty` and `B = Ty` in `Trait` +/// * the `G = Ty` in `Trait = Ty>` +/// * the `A: Bound` in `Trait` +/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy` +/// * the `C = { Ct }` in `Trait` (feature `associated_const_equality`) +/// * the `f(): Bound` in `Trait` (feature `return_type_notation`) #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub(crate) struct TypeBinding { +pub(crate) struct AssocItemConstraint { pub(crate) assoc: PathSegment, - pub(crate) kind: TypeBindingKind, + pub(crate) kind: AssocItemConstraintKind, } +/// The kind of [associated item constraint][AssocItemConstraint]. #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub(crate) enum TypeBindingKind { +pub(crate) enum AssocItemConstraintKind { Equality { term: Term }, - Constraint { bounds: Vec }, + Bound { bounds: Vec }, } // Some nodes are used a lot. Make sure they don't unintentionally get bigger. diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index aa923cc61173..24a01414c70c 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -2,9 +2,10 @@ use crate::clean::auto_trait::synthesize_auto_trait_impls; use crate::clean::blanket_impl::synthesize_blanket_impls; use crate::clean::render_macro_matchers::render_macro_matcher; use crate::clean::{ - clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, Crate, - ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path, - PathSegment, Primitive, PrimitiveType, Term, Type, TypeBinding, TypeBindingKind, + clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, + AssocItemConstraint, AssocItemConstraintKind, Crate, ExternalCrate, Generic, GenericArg, + GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path, PathSegment, Primitive, + PrimitiveType, Term, Type, }; use crate::core::DocContext; use crate::html::format::visibility_to_src_with_space; @@ -200,11 +201,11 @@ fn can_elide_generic_arg<'tcx>( actual.skip_binder() == default.skip_binder() } -fn clean_middle_generic_args_with_bindings<'tcx>( +fn clean_middle_generic_args_with_constraints<'tcx>( cx: &mut DocContext<'tcx>, did: DefId, has_self: bool, - bindings: ThinVec, + constraints: ThinVec, ty_args: ty::Binder<'tcx, GenericArgsRef<'tcx>>, ) -> GenericArgs { let args = clean_middle_generic_args(cx, ty_args.map_bound(|args| &args[..]), has_self, did); @@ -219,17 +220,19 @@ fn clean_middle_generic_args_with_bindings<'tcx>( // The trait's first substitution is the one after self, if there is one. match ty.skip_binder().kind() { ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None, None)).collect::>().into(), - _ => return GenericArgs::AngleBracketed { args: args.into(), bindings }, + _ => return GenericArgs::AngleBracketed { args: args.into(), constraints }, }; - let output = bindings.into_iter().next().and_then(|binding| match binding.kind { - TypeBindingKind::Equality { term: Term::Type(ty) } if ty != Type::Tuple(Vec::new()) => { + let output = constraints.into_iter().next().and_then(|binding| match binding.kind { + AssocItemConstraintKind::Equality { term: Term::Type(ty) } + if ty != Type::Tuple(Vec::new()) => + { Some(Box::new(ty)) } _ => None, }); GenericArgs::Parenthesized { inputs, output } } else { - GenericArgs::AngleBracketed { args: args.into(), bindings } + GenericArgs::AngleBracketed { args: args.into(), constraints } } } @@ -237,7 +240,7 @@ pub(super) fn clean_middle_path<'tcx>( cx: &mut DocContext<'tcx>, did: DefId, has_self: bool, - bindings: ThinVec, + constraints: ThinVec, args: ty::Binder<'tcx, GenericArgsRef<'tcx>>, ) -> Path { let def_kind = cx.tcx.def_kind(did); @@ -246,7 +249,7 @@ pub(super) fn clean_middle_path<'tcx>( res: Res::Def(def_kind, did), segments: thin_vec![PathSegment { name, - args: clean_middle_generic_args_with_bindings(cx, did, has_self, bindings, args), + args: clean_middle_generic_args_with_constraints(cx, did, has_self, constraints, args), }], } } @@ -342,7 +345,7 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => { let s = if let Some(def) = def.as_local() { - rendered_const(cx.tcx, cx.tcx.hir().body_owned_by(def)) + rendered_const(cx.tcx, &cx.tcx.hir().body_owned_by(def), def) } else { inline::print_inlined_const(cx.tcx, def) }; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 932295270765..ccd5dadb20a0 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -284,9 +284,9 @@ pub(crate) fn create_config( } let hir = tcx.hir(); - let body = hir.body(hir.body_owned_by(def_id)); + let body = hir.body_owned_by(def_id); debug!("visiting body for {def_id:?}"); - EmitIgnoredResolutionErrors::new(tcx).visit_body(body); + EmitIgnoredResolutionErrors::new(tcx).visit_body(&body); (rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id) }; }), diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 82f9cf1feaeb..a536a7139219 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1343,7 +1343,6 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> { def_id.to_def_id(), span_of_fragments(&attrs.doc_strings).unwrap_or(sp), )), - self.tcx.features().custom_code_classes_in_docs, ); } diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 6beca8bdb3a6..03ee042aa8d0 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -46,8 +46,6 @@ impl ExternalHtml { edition, playground, heading_offset: HeadingOffset::H2, - // For external files, it'll be disabled until the feature is enabled by default. - custom_code_classes_in_docs: false, } .into_string() ); @@ -63,8 +61,6 @@ impl ExternalHtml { edition, playground, heading_offset: HeadingOffset::H2, - // For external files, it'll be disabled until the feature is enabled by default. - custom_code_classes_in_docs: false, } .into_string() ); diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 57949001774f..d20cef745ab0 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -420,8 +420,8 @@ impl clean::GenericArgs { fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> { display_fn(move |f| { match self { - clean::GenericArgs::AngleBracketed { args, bindings } => { - if !args.is_empty() || !bindings.is_empty() { + clean::GenericArgs::AngleBracketed { args, constraints } => { + if !args.is_empty() || !constraints.is_empty() { if f.alternate() { f.write_str("<")?; } else { @@ -439,15 +439,15 @@ impl clean::GenericArgs { write!(f, "{}", arg.print(cx))?; } } - for binding in bindings.iter() { + for constraint in constraints.iter() { if comma { f.write_str(", ")?; } comma = true; if f.alternate() { - write!(f, "{:#}", binding.print(cx))?; + write!(f, "{:#}", constraint.print(cx))?; } else { - write!(f, "{}", binding.print(cx))?; + write!(f, "{}", constraint.print(cx))?; } } if f.alternate() { @@ -1706,7 +1706,7 @@ impl clean::ImportSource { } } -impl clean::TypeBinding { +impl clean::AssocItemConstraint { pub(crate) fn print<'a, 'tcx: 'a>( &'a self, cx: &'a Context<'tcx>, @@ -1715,11 +1715,11 @@ impl clean::TypeBinding { f.write_str(self.assoc.name.as_str())?; self.assoc.args.print(cx).fmt(f)?; match self.kind { - clean::TypeBindingKind::Equality { ref term } => { + clean::AssocItemConstraintKind::Equality { ref term } => { f.write_str(" = ")?; term.print(cx).fmt(f)?; } - clean::TypeBindingKind::Constraint { ref bounds } => { + clean::AssocItemConstraintKind::Bound { ref bounds } => { if !bounds.is_empty() { f.write_str(": ")?; print_generic_bounds(bounds, cx).fmt(f)?; diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 362f9021671f..11cc81700ff5 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -20,7 +20,6 @@ //! edition: Edition::Edition2015, //! playground: &None, //! heading_offset: HeadingOffset::H2, -//! custom_code_classes_in_docs: true, //! }; //! let html = md.into_string(); //! // ... something using html @@ -97,8 +96,6 @@ pub struct Markdown<'a> { /// Offset at which we render headings. /// E.g. if `heading_offset: HeadingOffset::H2`, then `# something` renders an `

`. pub heading_offset: HeadingOffset, - /// `true` if the `custom_code_classes_in_docs` feature is enabled. - pub custom_code_classes_in_docs: bool, } /// A struct like `Markdown` that renders the markdown with a table of contents. pub(crate) struct MarkdownWithToc<'a> { @@ -107,8 +104,6 @@ pub(crate) struct MarkdownWithToc<'a> { pub(crate) error_codes: ErrorCodes, pub(crate) edition: Edition, pub(crate) playground: &'a Option, - /// `true` if the `custom_code_classes_in_docs` feature is enabled. - pub(crate) custom_code_classes_in_docs: bool, } /// A tuple struct like `Markdown` that renders the markdown escaping HTML tags /// and includes no paragraph tags. @@ -209,7 +204,6 @@ struct CodeBlocks<'p, 'a, I: Iterator>> { // Information about the playground if a URL has been specified, containing an // optional crate name and the URL. playground: &'p Option, - custom_code_classes_in_docs: bool, } impl<'p, 'a, I: Iterator>> CodeBlocks<'p, 'a, I> { @@ -218,15 +212,8 @@ impl<'p, 'a, I: Iterator>> CodeBlocks<'p, 'a, I> { error_codes: ErrorCodes, edition: Edition, playground: &'p Option, - custom_code_classes_in_docs: bool, ) -> Self { - CodeBlocks { - inner: iter, - check_error_codes: error_codes, - edition, - playground, - custom_code_classes_in_docs, - } + CodeBlocks { inner: iter, check_error_codes: error_codes, edition, playground } } } @@ -253,12 +240,8 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { let LangString { added_classes, compile_fail, should_panic, ignore, edition, .. } = match kind { CodeBlockKind::Fenced(ref lang) => { - let parse_result = LangString::parse_without_check( - lang, - self.check_error_codes, - false, - self.custom_code_classes_in_docs, - ); + let parse_result = + LangString::parse_without_check(lang, self.check_error_codes, false); if !parse_result.rust { let added_classes = parse_result.added_classes; let lang_string = if let Some(lang) = parse_result.unknown.first() { @@ -733,17 +716,8 @@ pub(crate) fn find_testable_code( error_codes: ErrorCodes, enable_per_target_ignores: bool, extra_info: Option<&ExtraInfo<'_>>, - custom_code_classes_in_docs: bool, ) { - find_codes( - doc, - tests, - error_codes, - enable_per_target_ignores, - extra_info, - false, - custom_code_classes_in_docs, - ) + find_codes(doc, tests, error_codes, enable_per_target_ignores, extra_info, false) } pub(crate) fn find_codes( @@ -753,7 +727,6 @@ pub(crate) fn find_codes( enable_per_target_ignores: bool, extra_info: Option<&ExtraInfo<'_>>, include_non_rust: bool, - custom_code_classes_in_docs: bool, ) { let mut parser = Parser::new(doc).into_offset_iter(); let mut prev_offset = 0; @@ -772,7 +745,6 @@ pub(crate) fn find_codes( error_codes, enable_per_target_ignores, extra_info, - custom_code_classes_in_docs, ) } } @@ -1170,29 +1142,6 @@ impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> { } } -fn tokens(string: &str) -> impl Iterator> { - // Pandoc, which Rust once used for generating documentation, - // expects lang strings to be surrounded by `{}` and for each token - // to be proceeded by a `.`. Since some of these lang strings are still - // loose in the wild, we strip a pair of surrounding `{}` from the lang - // string and a leading `.` from each token. - - let string = string.trim(); - - let first = string.chars().next(); - let last = string.chars().last(); - - let string = - if first == Some('{') && last == Some('}') { &string[1..string.len() - 1] } else { string }; - - string - .split(|c| c == ',' || c == ' ' || c == '\t') - .map(str::trim) - .map(|token| token.strip_prefix('.').unwrap_or(token)) - .filter(|token| !token.is_empty()) - .map(|token| LangStringToken::LangToken(token)) -} - impl Default for LangString { fn default() -> Self { Self { @@ -1216,15 +1165,8 @@ impl LangString { string: &str, allow_error_code_check: ErrorCodes, enable_per_target_ignores: bool, - custom_code_classes_in_docs: bool, ) -> Self { - Self::parse( - string, - allow_error_code_check, - enable_per_target_ignores, - None, - custom_code_classes_in_docs, - ) + Self::parse(string, allow_error_code_check, enable_per_target_ignores, None) } fn parse( @@ -1232,7 +1174,6 @@ impl LangString { allow_error_code_check: ErrorCodes, enable_per_target_ignores: bool, extra: Option<&ExtraInfo<'_>>, - custom_code_classes_in_docs: bool, ) -> Self { let allow_error_code_check = allow_error_code_check.as_bool(); let mut seen_rust_tags = false; @@ -1269,11 +1210,7 @@ impl LangString { seen_rust_tags = true; } LangStringToken::LangToken("custom") => { - if custom_code_classes_in_docs { - seen_custom_tag = true; - } else { - seen_other_tags = true; - } + seen_custom_tag = true; } LangStringToken::LangToken("test_harness") => { data.test_harness = true; @@ -1364,16 +1301,12 @@ impl LangString { data.unknown.push(x.to_owned()); } LangStringToken::KeyValueAttribute(key, value) => { - if custom_code_classes_in_docs { - if key == "class" { - data.added_classes.push(value.to_owned()); - } else if let Some(extra) = extra { - extra.error_invalid_codeblock_attr(format!( - "unsupported attribute `{key}`" - )); - } - } else { - seen_other_tags = true; + if key == "class" { + data.added_classes.push(value.to_owned()); + } else if let Some(extra) = extra { + extra.error_invalid_codeblock_attr(format!( + "unsupported attribute `{key}`" + )); } } LangStringToken::ClassAttribute(class) => { @@ -1383,11 +1316,7 @@ impl LangString { } }; - if custom_code_classes_in_docs { - call(&mut TagIterator::new(string, extra)) - } else { - call(&mut tokens(string)) - } + call(&mut TagIterator::new(string, extra)); // ignore-foo overrides ignore if !ignores.is_empty() { @@ -1410,7 +1339,6 @@ impl Markdown<'_> { edition, playground, heading_offset, - custom_code_classes_in_docs, } = self; // This is actually common enough to special-case @@ -1433,7 +1361,7 @@ impl Markdown<'_> { let p = Footnotes::new(p); let p = LinkReplacer::new(p.map(|(ev, _)| ev), links); let p = TableWrapper::new(p); - let p = CodeBlocks::new(p, codes, edition, playground, custom_code_classes_in_docs); + let p = CodeBlocks::new(p, codes, edition, playground); html::push_html(&mut s, p); s @@ -1442,14 +1370,7 @@ impl Markdown<'_> { impl MarkdownWithToc<'_> { pub(crate) fn into_string(self) -> String { - let MarkdownWithToc { - content: md, - ids, - error_codes: codes, - edition, - playground, - custom_code_classes_in_docs, - } = self; + let MarkdownWithToc { content: md, ids, error_codes: codes, edition, playground } = self; let p = Parser::new_ext(md, main_body_opts()).into_offset_iter(); @@ -1461,7 +1382,7 @@ impl MarkdownWithToc<'_> { let p = HeadingLinks::new(p, Some(&mut toc), ids, HeadingOffset::H1); let p = Footnotes::new(p); let p = TableWrapper::new(p.map(|(ev, _)| ev)); - let p = CodeBlocks::new(p, codes, edition, playground, custom_code_classes_in_docs); + let p = CodeBlocks::new(p, codes, edition, playground); html::push_html(&mut s, p); } @@ -1902,11 +1823,7 @@ pub(crate) struct RustCodeBlock { /// Returns a range of bytes for each code block in the markdown that is tagged as `rust` or /// untagged (and assumed to be rust). -pub(crate) fn rust_code_blocks( - md: &str, - extra_info: &ExtraInfo<'_>, - custom_code_classes_in_docs: bool, -) -> Vec { +pub(crate) fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec { let mut code_blocks = vec![]; if md.is_empty() { @@ -1923,13 +1840,7 @@ pub(crate) fn rust_code_blocks( let lang_string = if syntax.is_empty() { Default::default() } else { - LangString::parse( - &*syntax, - ErrorCodes::Yes, - false, - Some(extra_info), - custom_code_classes_in_docs, - ) + LangString::parse(&*syntax, ErrorCodes::Yes, false, Some(extra_info)) }; if !lang_string.rust { continue; diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index 1de97e49b830..fb74c079c9a4 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -49,7 +49,7 @@ fn test_unique_id() { fn test_lang_string_parse() { fn t(lg: LangString) { let s = &lg.original; - assert_eq!(LangString::parse(s, ErrorCodes::Yes, true, None, true), lg) + assert_eq!(LangString::parse(s, ErrorCodes::Yes, true, None), lg) } t(Default::default()); @@ -305,7 +305,6 @@ fn test_header() { edition: DEFAULT_EDITION, playground: &None, heading_offset: HeadingOffset::H2, - custom_code_classes_in_docs: true, } .into_string(); assert_eq!(output, expect, "original: {}", input); @@ -357,7 +356,6 @@ fn test_header_ids_multiple_blocks() { edition: DEFAULT_EDITION, playground: &None, heading_offset: HeadingOffset::H2, - custom_code_classes_in_docs: true, } .into_string(); assert_eq!(output, expect, "original: {}", input); @@ -481,7 +479,7 @@ fn test_markdown_html_escape() { fn test_find_testable_code_line() { fn t(input: &str, expect: &[usize]) { let mut lines = Vec::::new(); - find_testable_code(input, &mut lines, ErrorCodes::No, false, None, true); + find_testable_code(input, &mut lines, ErrorCodes::No, false, None); assert_eq!(lines, expect); } @@ -506,7 +504,6 @@ fn test_ascii_with_prepending_hashtag() { edition: DEFAULT_EDITION, playground: &None, heading_offset: HeadingOffset::H2, - custom_code_classes_in_docs: true, } .into_string(); assert_eq!(output, expect, "original: {}", input); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 8ee4cc5c75e4..877a00e206d1 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -506,7 +506,6 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String { edition: shared.edition(), playground: &shared.playground, heading_offset: HeadingOffset::H1, - custom_code_classes_in_docs: false, } .into_string() ) @@ -540,7 +539,6 @@ fn render_markdown<'a, 'cx: 'a>( heading_offset: HeadingOffset, ) -> impl fmt::Display + 'a + Captures<'cx> { display_fn(move |f| { - let custom_code_classes_in_docs = cx.tcx().features().custom_code_classes_in_docs; write!( f, "
{}
", @@ -552,7 +550,6 @@ fn render_markdown<'a, 'cx: 'a>( edition: cx.shared.edition(), playground: &cx.shared.playground, heading_offset, - custom_code_classes_in_docs, } .into_string() ) @@ -1885,7 +1882,6 @@ fn render_impl( ", ); } - let custom_code_classes_in_docs = cx.tcx().features().custom_code_classes_in_docs; write!( w, "
{}
", @@ -1897,7 +1893,6 @@ fn render_impl( edition: cx.shared.edition(), playground: &cx.shared.playground, heading_offset: HeadingOffset::H4, - custom_code_classes_in_docs, } .into_string() ); diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index e635c1e611de..bc8bdffc3314 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -727,7 +727,7 @@ pub(crate) fn get_function_type_for_search<'tcx>( name: *name, args: clean::GenericArgs::AngleBracketed { args: Vec::new().into_boxed_slice(), - bindings: ThinVec::new(), + constraints: ThinVec::new(), }, }) .collect(), @@ -1049,7 +1049,7 @@ fn simplify_fn_type<'tcx, 'a>( // So in here, we can add it directly and look for its own type parameters (so for `Option`, // we will look for them but not for `T`). let mut ty_generics = Vec::new(); - let mut ty_bindings = Vec::new(); + let mut ty_constraints = Vec::new(); if let Some(arg_generics) = arg.generic_args() { for ty in arg_generics.into_iter().filter_map(|gen| match gen { clean::GenericArg::Type(ty) => Some(ty), @@ -1067,14 +1067,14 @@ fn simplify_fn_type<'tcx, 'a>( cache, ); } - for binding in arg_generics.bindings() { - simplify_fn_binding( + for constraint in arg_generics.constraints() { + simplify_fn_constraint( self_, generics, - &binding, + &constraint, tcx, recurse + 1, - &mut ty_bindings, + &mut ty_constraints, rgen, is_return, cache, @@ -1137,7 +1137,7 @@ fn simplify_fn_type<'tcx, 'a>( *stored_bounds = type_bounds; } } - ty_bindings.push(( + ty_constraints.push(( RenderTypeId::AssociatedType(name), vec![RenderType { id: Some(RenderTypeId::Index(idx)), @@ -1152,17 +1152,17 @@ fn simplify_fn_type<'tcx, 'a>( if id.is_some() || !ty_generics.is_empty() { res.push(RenderType { id, - bindings: if ty_bindings.is_empty() { None } else { Some(ty_bindings) }, + bindings: if ty_constraints.is_empty() { None } else { Some(ty_constraints) }, generics: if ty_generics.is_empty() { None } else { Some(ty_generics) }, }); } } } -fn simplify_fn_binding<'tcx, 'a>( +fn simplify_fn_constraint<'tcx, 'a>( self_: Option<&'a Type>, generics: &Generics, - binding: &'a clean::TypeBinding, + constraint: &'a clean::AssocItemConstraint, tcx: TyCtxt<'tcx>, recurse: usize, res: &mut Vec<(RenderTypeId, Vec)>, @@ -1170,9 +1170,9 @@ fn simplify_fn_binding<'tcx, 'a>( is_return: bool, cache: &Cache, ) { - let mut ty_binding_constraints = Vec::new(); - let ty_binding_assoc = RenderTypeId::AssociatedType(binding.assoc.name); - for gen in &binding.assoc.args { + let mut ty_constraints = Vec::new(); + let ty_constrained_assoc = RenderTypeId::AssociatedType(constraint.assoc.name); + for gen in &constraint.assoc.args { match gen { clean::GenericArg::Type(arg) => simplify_fn_type( self_, @@ -1180,7 +1180,7 @@ fn simplify_fn_binding<'tcx, 'a>( &arg, tcx, recurse + 1, - &mut ty_binding_constraints, + &mut ty_constraints, rgen, is_return, cache, @@ -1190,11 +1190,11 @@ fn simplify_fn_binding<'tcx, 'a>( | clean::GenericArg::Infer => {} } } - for binding in binding.assoc.args.bindings() { - simplify_fn_binding( + for constraint in constraint.assoc.args.constraints() { + simplify_fn_constraint( self_, generics, - &binding, + &constraint, tcx, recurse + 1, res, @@ -1203,8 +1203,8 @@ fn simplify_fn_binding<'tcx, 'a>( cache, ); } - match &binding.kind { - clean::TypeBindingKind::Equality { term } => { + match &constraint.kind { + clean::AssocItemConstraintKind::Equality { term } => { if let clean::Term::Type(arg) = &term { simplify_fn_type( self_, @@ -1212,14 +1212,14 @@ fn simplify_fn_binding<'tcx, 'a>( arg, tcx, recurse + 1, - &mut ty_binding_constraints, + &mut ty_constraints, rgen, is_return, cache, ); } } - clean::TypeBindingKind::Constraint { bounds } => { + clean::AssocItemConstraintKind::Bound { bounds } => { for bound in &bounds[..] { if let Some(path) = bound.get_trait_path() { let ty = Type::Path { path }; @@ -1229,7 +1229,7 @@ fn simplify_fn_binding<'tcx, 'a>( &ty, tcx, recurse + 1, - &mut ty_binding_constraints, + &mut ty_constraints, rgen, is_return, cache, @@ -1238,7 +1238,7 @@ fn simplify_fn_binding<'tcx, 'a>( } } } - res.push((ty_binding_assoc, ty_binding_constraints)); + res.push((ty_constrained_assoc, ty_constraints)); } /// Return the full list of types when bounds have been resolved. diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 8ee35db56f8d..0535246ae10f 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -162,9 +162,7 @@ impl<'tcx> SpanMapVisitor<'tcx> { // compiled (because of cfg)! // // See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352 - let typeck_results = self - .tcx - .typeck_body(hir.maybe_body_owned_by(body_id).expect("a body which isn't a body")); + let typeck_results = self.tcx.typeck_body(hir.body_owned_by(body_id).id()); // Interestingly enough, for method calls, we need the whole expression whereas for static // method/function calls, we need the call expression specifically. if let Some(def_id) = typeck_results.type_dependent_def_id(expr_hir_id.unwrap_or(hir_id)) { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index f856b4e9f16c..7e6a19aa52e0 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -153,9 +153,9 @@ impl FromWithTcx for GenericArgs { fn from_tcx(args: clean::GenericArgs, tcx: TyCtxt<'_>) -> Self { use clean::GenericArgs::*; match args { - AngleBracketed { args, bindings } => GenericArgs::AngleBracketed { + AngleBracketed { args, constraints } => GenericArgs::AngleBracketed { args: args.into_vec().into_tcx(tcx), - bindings: bindings.into_tcx(tcx), + bindings: constraints.into_tcx(tcx), }, Parenthesized { inputs, output } => GenericArgs::Parenthesized { inputs: inputs.into_vec().into_tcx(tcx), @@ -187,22 +187,22 @@ impl FromWithTcx for Constant { } } -impl FromWithTcx for TypeBinding { - fn from_tcx(binding: clean::TypeBinding, tcx: TyCtxt<'_>) -> Self { +impl FromWithTcx for TypeBinding { + fn from_tcx(constraint: clean::AssocItemConstraint, tcx: TyCtxt<'_>) -> Self { TypeBinding { - name: binding.assoc.name.to_string(), - args: binding.assoc.args.into_tcx(tcx), - binding: binding.kind.into_tcx(tcx), + name: constraint.assoc.name.to_string(), + args: constraint.assoc.args.into_tcx(tcx), + binding: constraint.kind.into_tcx(tcx), } } } -impl FromWithTcx for TypeBindingKind { - fn from_tcx(kind: clean::TypeBindingKind, tcx: TyCtxt<'_>) -> Self { - use clean::TypeBindingKind::*; +impl FromWithTcx for TypeBindingKind { + fn from_tcx(kind: clean::AssocItemConstraintKind, tcx: TyCtxt<'_>) -> Self { + use clean::AssocItemConstraintKind::*; match kind { Equality { term } => TypeBindingKind::Equality(term.into_tcx(tcx)), - Constraint { bounds } => TypeBindingKind::Constraint(bounds.into_tcx(tcx)), + Bound { bounds } => TypeBindingKind::Constraint(bounds.into_tcx(tcx)), } } } @@ -820,7 +820,10 @@ impl FromWithTcx for Static { Static { type_: stat.type_.into_tcx(tcx), mutable: stat.mutability == ast::Mutability::Mut, - expr: stat.expr.map(|e| rendered_const(tcx, e)).unwrap_or_default(), + 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/lib.rs b/src/librustdoc/lib.rs index 55346c768b66..c0d2f9cfaf95 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -200,7 +200,6 @@ fn init_logging(early_dcx: &EarlyDiagCtxt) { let filter = tracing_subscriber::EnvFilter::from_env("RUSTDOC_LOG"); let layer = tracing_tree::HierarchicalLayer::default() .with_writer(io::stderr) - .with_indent_lines(true) .with_ansi(color_logs) .with_targets(true) .with_wraparound(10) diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 7289ed56dc7a..bcc5a37618a4 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -82,8 +82,6 @@ pub(crate) fn render>( error_codes, edition, playground: &playground, - // For markdown files, it'll be disabled until the feature is enabled by default. - custom_code_classes_in_docs: false, } .into_string() } else { @@ -95,8 +93,6 @@ pub(crate) fn render>( edition, playground: &playground, heading_offset: HeadingOffset::H1, - // For markdown files, it'll be disabled until the feature is enabled by default. - custom_code_classes_in_docs: false, } .into_string() }; @@ -174,14 +170,7 @@ pub(crate) fn test(options: Options) -> Result<(), String> { let codes = ErrorCodes::from(options.unstable_features.is_nightly_build()); // For markdown files, custom code classes will be disabled until the feature is enabled by default. - find_testable_code( - &input_str, - &mut collector, - codes, - options.enable_per_target_ignores, - None, - false, - ); + find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None); crate::doctest::run_tests(options.test_args, options.nocapture, collector.tests); Ok(()) diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 60def40588aa..592dd0a145cf 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -208,14 +208,7 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> { let has_docs = !i.attrs.doc_strings.is_empty(); let mut tests = Tests { found_tests: 0 }; - find_testable_code( - &i.doc_value(), - &mut tests, - ErrorCodes::No, - false, - None, - self.ctx.tcx.features().custom_code_classes_in_docs, - ); + find_testable_code(&i.doc_value(), &mut tests, ErrorCodes::No, false, None); let has_doc_example = tests.found_tests != 0; let hir_id = DocContext::as_local_hir_id(self.ctx.tcx, i.item_id).unwrap(); diff --git a/src/librustdoc/passes/check_custom_code_classes.rs b/src/librustdoc/passes/check_custom_code_classes.rs deleted file mode 100644 index 524795ed77c2..000000000000 --- a/src/librustdoc/passes/check_custom_code_classes.rs +++ /dev/null @@ -1,93 +0,0 @@ -//! NIGHTLY & UNSTABLE CHECK: custom_code_classes_in_docs -//! -//! This pass will produce errors when finding custom classes outside of -//! nightly + relevant feature active. - -use super::Pass; -use crate::clean::{Crate, Item}; -use crate::core::DocContext; -use crate::fold::DocFolder; -use crate::html::markdown::{find_codes, ErrorCodes, LangString}; - -use rustc_errors::StashKey; -use rustc_feature::GateIssue; -use rustc_session::parse::add_feature_diagnostics_for_issue; -use rustc_span::symbol::sym; - -pub(crate) const CHECK_CUSTOM_CODE_CLASSES: Pass = Pass { - name: "check-custom-code-classes", - run: check_custom_code_classes, - description: "check for custom code classes without the feature-gate enabled", -}; - -pub(crate) fn check_custom_code_classes(krate: Crate, cx: &mut DocContext<'_>) -> Crate { - if cx.tcx.features().custom_code_classes_in_docs { - // Nothing to check here if the feature is enabled. - return krate; - } - let mut coll = CustomCodeClassLinter { cx }; - - coll.fold_crate(krate) -} - -struct CustomCodeClassLinter<'a, 'tcx> { - cx: &'a DocContext<'tcx>, -} - -impl<'a, 'tcx> DocFolder for CustomCodeClassLinter<'a, 'tcx> { - fn fold_item(&mut self, item: Item) -> Option { - look_for_custom_classes(&self.cx, &item); - Some(self.fold_item_recur(item)) - } -} - -#[derive(Debug)] -struct TestsWithCustomClasses { - custom_classes_found: Vec, -} - -impl crate::doctest::Tester for TestsWithCustomClasses { - fn add_test(&mut self, _: String, config: LangString, _: usize) { - self.custom_classes_found.extend(config.added_classes); - } -} - -pub(crate) fn look_for_custom_classes<'tcx>(cx: &DocContext<'tcx>, item: &Item) { - if !item.item_id.is_local() { - // If non-local, no need to check anything. - return; - } - - let mut tests = TestsWithCustomClasses { custom_classes_found: vec![] }; - - let dox = item.attrs.doc_value(); - find_codes(&dox, &mut tests, ErrorCodes::No, false, None, true, true); - - if !tests.custom_classes_found.is_empty() { - let span = item.attr_span(cx.tcx); - let sess = &cx.tcx.sess; - let mut err = sess - .dcx() - .struct_span_warn(span, "custom classes in code blocks will change behaviour"); - add_feature_diagnostics_for_issue( - &mut err, - sess, - sym::custom_code_classes_in_docs, - GateIssue::Language, - false, - None, - ); - - err.note( - // This will list the wrong items to make them more easily searchable. - // To ensure the most correct hits, it adds back the 'class:' that was stripped. - format!( - "found these custom classes: class={}", - tests.custom_classes_found.join(",class=") - ), - ); - - // A later feature_err call can steal and cancel this warning. - err.stash(span, StashKey::EarlySyntaxWarning); - } -} diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 257bab3e9fcb..02589a137b41 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -112,14 +112,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item let mut tests = Tests { found_tests: 0 }; - find_testable_code( - dox, - &mut tests, - ErrorCodes::No, - false, - None, - cx.tcx.features().custom_code_classes_in_docs, - ); + find_testable_code(dox, &mut tests, ErrorCodes::No, false, None); if tests.found_tests == 0 && cx.tcx.features().rustdoc_missing_doc_code_examples { if should_have_doc_example(cx, item) { diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 9562559fba26..39350f4cbbb6 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -20,9 +20,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &clean::Item) { if let Some(dox) = &item.opt_doc_value() { let sp = item.attr_span(cx.tcx); let extra = crate::html::markdown::ExtraInfo::new(cx.tcx, item.item_id.expect_def_id(), sp); - for code_block in - markdown::rust_code_blocks(dox, &extra, cx.tcx.features().custom_code_classes_in_docs) - { + for code_block in markdown::rust_code_blocks(dox, &extra) { check_rust_syntax(cx, item, dox, code_block); } } diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 3a71dd82db88..b1dc766049d5 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -38,9 +38,6 @@ pub(crate) use self::calculate_doc_coverage::CALCULATE_DOC_COVERAGE; mod lint; pub(crate) use self::lint::RUN_LINTS; -mod check_custom_code_classes; -pub(crate) use self::check_custom_code_classes::CHECK_CUSTOM_CODE_CLASSES; - /// A single pass over the cleaned documentation. /// /// Runs in the compiler context, so it has access to types and traits and the like. @@ -72,7 +69,6 @@ pub(crate) enum Condition { /// The full list of passes. pub(crate) const PASSES: &[Pass] = &[ - CHECK_CUSTOM_CODE_CLASSES, CHECK_DOC_TEST_VISIBILITY, STRIP_ALIASED_NON_LOCAL, STRIP_HIDDEN, @@ -87,7 +83,6 @@ pub(crate) const PASSES: &[Pass] = &[ /// The list of passes run by default. pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[ - ConditionalPass::always(CHECK_CUSTOM_CODE_CLASSES), ConditionalPass::always(COLLECT_TRAIT_IMPLS), ConditionalPass::always(CHECK_DOC_TEST_VISIBILITY), ConditionalPass::always(STRIP_ALIASED_NON_LOCAL), diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 907ea6d309c9..886df82e5b69 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -614,7 +614,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> { // Unneeded. } - fn visit_body(&mut self, b: &'tcx hir::Body<'tcx>) { + fn visit_body(&mut self, b: &hir::Body<'tcx>) { let prev = mem::replace(&mut self.inside_body, true); walk_body(self, b); self.inside_body = prev; diff --git a/src/stage0 b/src/stage0 index 72f50b787a7a..ed88549e6982 100644 --- a/src/stage0 +++ b/src/stage0 @@ -14,434 +14,434 @@ nightly_branch=master # All changes below this comment will be overridden the next time the # tool is executed. -compiler_date=2024-05-24 +compiler_date=2024-05-26 compiler_version=beta -rustfmt_date=2024-05-24 +rustfmt_date=2024-05-29 rustfmt_version=nightly -dist/2024-05-24/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=502e7f1a05acd503079654dca24a1a9945452580d835d0b6a2cc21155837a4c7 -dist/2024-05-24/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=0bcf49fe166183955a27a0be2e83aa6d6ee9820a475323d8f61c6b159960d3f8 -dist/2024-05-24/rustc-beta-aarch64-pc-windows-msvc.tar.gz=234d90368b765cbe8824068eb2d21ca4c9d7f5cd401f686ef5b338a1781d1468 -dist/2024-05-24/rustc-beta-aarch64-pc-windows-msvc.tar.xz=085cc56230431db4c6088e0f9c4d63fb5af2a7064a5a7e21d5d19be1d3026d18 -dist/2024-05-24/rustc-beta-i686-unknown-linux-gnu.tar.gz=790bcf8e2fe47efc4a0071093df383d70c3383ba3290aaa2f6b5eade8e2f35f0 -dist/2024-05-24/rustc-beta-i686-unknown-linux-gnu.tar.xz=7f8df95a04a6e57db99fb84d60baeddef4a69f13f026f5cc5719a8b6c231d4b8 -dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=939759a91a408b4ecd8921e0cf07676cc473d1c23a2021a57f0f8b04465e9ed4 -dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=5ac62bb9f5d7e7e499598f5579156e593d07c91eadfd1326b29f2bea29122164 -dist/2024-05-24/rustc-beta-aarch64-apple-darwin.tar.gz=134d09a9f7c51f1862f1b361da5608bdae02bef2fdb994e30404a8b0e309b7d6 -dist/2024-05-24/rustc-beta-aarch64-apple-darwin.tar.xz=c3eae7e3583a6f4e68d388a73d2414ca355ef98215417f908ac81e1ea90b2d51 -dist/2024-05-24/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=0f9aa17c2a8748cdf06bbd77bb948ba65794b89587744839db503bb0988e0824 -dist/2024-05-24/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=390c430ffe5f237d547ae2c93a058122d3b8fbf4ea71b20018f0f8bf83858398 -dist/2024-05-24/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=bf6a18c4f54921c46d90fe2a53f6e3044a32f327d6cd13e8308db683a428aef7 -dist/2024-05-24/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=27dcf104f3ca958f0ef3bed47c26e3318e545d1de06f27bf9b25aac97a21c06b -dist/2024-05-24/rustc-beta-x86_64-unknown-linux-musl.tar.gz=07c74d5cc87fba304d33ac7844a1e762225f9ec8ca5a5c6b7bab4c427ffed80a -dist/2024-05-24/rustc-beta-x86_64-unknown-linux-musl.tar.xz=08b6c39e9315c0eee5174d540851c6530e6b1c900db4396fdf8a967b88d69a75 -dist/2024-05-24/rustc-beta-aarch64-unknown-linux-musl.tar.gz=c3aa3cead301f7081c88b5bbd0c0b5a24eab203cbdb2d772ed0ddba8e3034928 -dist/2024-05-24/rustc-beta-aarch64-unknown-linux-musl.tar.xz=943a3fd053657bce6cafb589665c5ad98d5c453ab7c594650ed8c3cd15356647 -dist/2024-05-24/rustc-beta-s390x-unknown-linux-gnu.tar.gz=b8db693c04ad41d1e90b7a3bec7f41a0a21872a220342742402dcd0cb4f28799 -dist/2024-05-24/rustc-beta-s390x-unknown-linux-gnu.tar.xz=ec509af079e002d181b092f1a9e768744656b93fc78466efad8fac567d2184f1 -dist/2024-05-24/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=50f60b246b50778720557f16e87cc19373dd44a77e423bc1e2db1e504557cb58 -dist/2024-05-24/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=ed2a36058a7f0a2393309fbbe435a0c498ab682e91d757f6d70d9c16091dd646 -dist/2024-05-24/rustc-beta-x86_64-unknown-illumos.tar.gz=9b931dc596fd980a66507ca9c83b17c4e6d376a9741361a41dfb176f41b4bd2c -dist/2024-05-24/rustc-beta-x86_64-unknown-illumos.tar.xz=e1bb3f44adf89ff9900ed3bdabb7ab386018c8894d6d92c68f3881077f777a1c -dist/2024-05-24/rustc-beta-x86_64-pc-windows-msvc.tar.gz=c5427a8ba5dc41aa00b8194c49b711685a6c6bd0674ab93ec44b953897def2f4 -dist/2024-05-24/rustc-beta-x86_64-pc-windows-msvc.tar.xz=274545121eb6003eb52fddf030f8893ad63cebee564648dbef312aa28853cb54 -dist/2024-05-24/rustc-beta-i686-pc-windows-msvc.tar.gz=36185524fe00de47a92cb0fb766a4a7afadee469cd5f1ef1345ac24364499425 -dist/2024-05-24/rustc-beta-i686-pc-windows-msvc.tar.xz=7681b6695ac56c50277318fb9deec495fcadcb266a763f1ad3d19b88c9a520fb -dist/2024-05-24/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=d1115327b8cfb23e60a70510f78e39329f2092a0a99763b2cbd25929c41cb24f -dist/2024-05-24/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=7bb0b5b15e5218d9e4554ff2eec03cbe2fde2e957f954fa08aa7079b334bad05 -dist/2024-05-24/rustc-beta-x86_64-unknown-netbsd.tar.gz=6a46a111e30efc6f8f090b2c9e547465e6fcf836b9433fc1f8c53276a0ef63fb -dist/2024-05-24/rustc-beta-x86_64-unknown-netbsd.tar.xz=9516471cb5d3377e1430e64171b7a289bd8a8674032d73c739e0cffa85e87e92 -dist/2024-05-24/rustc-beta-x86_64-apple-darwin.tar.gz=63331eea78233ec4ee4d9390a509a587bbb6e07ce0748fca36cf93a0f4ecb216 -dist/2024-05-24/rustc-beta-x86_64-apple-darwin.tar.xz=b668abe9cb4c5366ee866f8e399ced6c9a8b560f5e5adbe7d6c07058762be21d -dist/2024-05-24/rustc-beta-x86_64-pc-windows-gnu.tar.gz=076e95ca2413fc3f07257ce0b94212db0331e797679a60695929cb588c6047cf -dist/2024-05-24/rustc-beta-x86_64-pc-windows-gnu.tar.xz=d1d006a216c2358a33000e400b5a2c223ee0ab875cfd57eca95b9bd230494d62 -dist/2024-05-24/rustc-beta-x86_64-unknown-freebsd.tar.gz=48ccaab8b59f8bb3e1e0fb82368b79d317e66e4b6a2c6d18d0d49b32e96b2e95 -dist/2024-05-24/rustc-beta-x86_64-unknown-freebsd.tar.xz=a050b10d6f67c1f1d2cdb2425ffb51445ade293328ec3e235400c151a447beb9 -dist/2024-05-24/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=21f26e3028f1174184be66ce88597e1551d2dbf7d9458f528f15366c6cf52c30 -dist/2024-05-24/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=fe504571f52c9eaba68fcc07398db049e3dd6131daa14c2b999540b84cec4885 -dist/2024-05-24/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=082828da023201d2b8f84e686d727f77b76a71c929c5588098d8c4609ffca336 -dist/2024-05-24/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=13bf4a5f012b29334dececacfe16ab6755f7b97165229cff7c27d37b6acb455f -dist/2024-05-24/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=f4584c00af06eb05e6f238f3ce8cbb39ace84e3aad7a3b158b5bb591e522eab8 -dist/2024-05-24/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=8fe01de1853880df20e355ba3925eb1cc537a6fb6aca53b638ee74f689f15cdf -dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=7a24b865db48708120ad670811238fccfd054bba0a92d6b436237c0726678413 -dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=3716d2a3896a2f3cb774c265e58d29e4f8ea35228261f499b96887cb40ff5cd9 -dist/2024-05-24/rustc-beta-i686-pc-windows-gnu.tar.gz=336dd7b17d5ea546f359fff5e7697f82022b0710e1d6ab513370f21741d6f737 -dist/2024-05-24/rustc-beta-i686-pc-windows-gnu.tar.xz=829a078f5d4126d90e117c2c5d31f259b3ba4960b834830c0e49a23ce3bb339f -dist/2024-05-24/rust-std-beta-x86_64-unknown-uefi.tar.gz=3522e09c17465ceda12ad69adc341cda01171cc7275623ea55cc0a56611fcff9 -dist/2024-05-24/rust-std-beta-x86_64-unknown-uefi.tar.xz=d71dac0e0316928d2e5c83c092fab2605b3e46b75a0de867e838067a5134851d -dist/2024-05-24/rust-std-beta-armv7r-none-eabihf.tar.gz=d9fe62eafe589b5223097d35104c5d32b623e98a0e60284254770dc5a760ded8 -dist/2024-05-24/rust-std-beta-armv7r-none-eabihf.tar.xz=0ed3d3b74882594f08be828a491bad42c5b73914c461346e634a38dbf609de0e -dist/2024-05-24/rust-std-beta-wasm32-wasip1-threads.tar.gz=850236f8f00bfdf0f032a2f4b2c3ee1c71ddd7fe11a87648066eb63801d302ff -dist/2024-05-24/rust-std-beta-wasm32-wasip1-threads.tar.xz=db1c182ddbb3276752c16d4d9c9ee94f97b426349fb44a456c276268c4aa8be4 -dist/2024-05-24/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=ce22565ddab95e2f43abc8a864787820f3b1dd0a0f174639b90c26726da667ab -dist/2024-05-24/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=214c16191cc3a3623a7b8d3a995c50132c03f90b3fad0d08927a5e449ea13923 -dist/2024-05-24/rust-std-beta-i686-unknown-freebsd.tar.gz=478c1de19c252d581b4438af70b37b36c0bd240e5bf5ca5ba4e752438e80707b -dist/2024-05-24/rust-std-beta-i686-unknown-freebsd.tar.xz=0948aa34ea060445ca2a410df33622a9228f3fe0f24a94442799568b251c1e10 -dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=e139b5a0151a1a3ff8e6bc94ff856522be558cffbf51fd76a434591e30d51ccd -dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=dccf2fcff4e0980b3e0edd30a565c6bc3f994812f2acce9c7a07eb6ea8ad84ab -dist/2024-05-24/rust-std-beta-wasm32-unknown-unknown.tar.gz=2f6aff225189a507b79e84388b69fdcfe12ac29a6a955cd60d34298bb7435c79 -dist/2024-05-24/rust-std-beta-wasm32-unknown-unknown.tar.xz=2b623f3318ff77aada72d0ca8ce46e807f8e4833dd74717d1a4102f1ee3bef78 -dist/2024-05-24/rust-std-beta-i686-unknown-linux-musl.tar.gz=85e016d2c36da363618b184576e35263034ef0291e8a36f9380879917e757f67 -dist/2024-05-24/rust-std-beta-i686-unknown-linux-musl.tar.xz=fb0be15c71068cdec7e8b75f6ebcf1094d610c0e41d1cec08c2031d8583d10c5 -dist/2024-05-24/rust-std-beta-thumbv6m-none-eabi.tar.gz=96c68111c9a491f816f56ae8f1f552ce31738fa9b9d9d00e42c2d1f0a3628ef0 -dist/2024-05-24/rust-std-beta-thumbv6m-none-eabi.tar.xz=a6e20d5c434cbe9b86e406c6132d1986489fe76168be7a60b6459b0f2691877b -dist/2024-05-24/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=933e7b14c199d36f6eb51ae6527c9af2d094ec13bb1299bcf8c72ba9b0d69515 -dist/2024-05-24/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=ade7325d0787ade9c3122a042baf7238ba5d493a6b7b7ea311421e11a15586cb -dist/2024-05-24/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=8816d3c9fbe0dfadfab0ba7db858bfd32546161f6460b4c9160a4e77ab54ac8f -dist/2024-05-24/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=da52d6feb060edada6fb0f747ef1c1ea658f2070c024a873c69ba909ade175b2 -dist/2024-05-24/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=b699e48e19a1860132719487bf287a3a3f014257182a53b4ed95f1316f401fec -dist/2024-05-24/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=402cad3c14a356f7345bb8cc93ef7186fd09b4ae1abdd13bc020c7e424a941d3 -dist/2024-05-24/rust-std-beta-aarch64-unknown-none.tar.gz=d875d0e34057c77c34e2020310f33a56f08f3b063b202f513be8de96319e9e4b -dist/2024-05-24/rust-std-beta-aarch64-unknown-none.tar.xz=3f489181280332f0d7169f656d03252f7de43b84a6fd6de9fb9c6906c09f7b72 -dist/2024-05-24/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=072503fd29be4101f8e1f75bad03a5b2486fd2e8e2f217f651d6cee2e0b2f032 -dist/2024-05-24/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=b96a542616a05b2ccaad49d9e22273341df7000ca63e4eb91ee219e8b931f4b0 -dist/2024-05-24/rust-std-beta-wasm32-wasip1.tar.gz=ccae6a247c76bbe08216faad0faff0d2052982baa1cba8d403f3182bd3d92e46 -dist/2024-05-24/rust-std-beta-wasm32-wasip1.tar.xz=ceb781289ab079bbab947f366eeb4087b04082326c4f935c78b3887351fe6c89 -dist/2024-05-24/rust-std-beta-i686-unknown-uefi.tar.gz=ed888cc3847b8616d50e80d6c3c0116c8c0e73c6b7fc3b39bb04bced9fb8d9fa -dist/2024-05-24/rust-std-beta-i686-unknown-uefi.tar.xz=51ef73968d5e9ae2b7d857befa8827aac37c490f2051f526ad1b5089ee9fa550 -dist/2024-05-24/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=226d46a2cf4e5c58f1ad1357bfc607d23c195122c7a74a5ddb6636ed35d295a4 -dist/2024-05-24/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=27e68d85bfbc8302e68aea58bc57d1d8ff038a0eee7629f17f479d0ea1a6acaa -dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=132be65f60c5d0b7d6293495acf51559b8855c80498befe98d6cef752deb1a71 -dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=7f938a1bfcea115c99e7e813c9737f86788d78af8f97265ce8f7ebde52dca54b -dist/2024-05-24/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=186c252edf1497a5f559dabbd8245491e3fef7caa6a80b5dc989275caeed95af -dist/2024-05-24/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=3be2944eee2ec57d7ae3d2eb87b7b1881590adaa68c5c6851fa7c027b4f7c4a1 -dist/2024-05-24/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=ae9bfb56c1be153d29371a75141471f676cdf5ec6e8b6af252f4a6f3a1054712 -dist/2024-05-24/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=1387267e76f332fdfaea426468a45ad5d967f1ee9a211b9b72c6cace0b746ad1 -dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=ef44a8ad9b1e07d240a00a2bec592d4f19a099ddfd8b2398f4ea2d50216548e0 -dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=25d0da3cc4616bf6778af8277341b3e436300865245d016a370892d1afcfef31 -dist/2024-05-24/rust-std-beta-x86_64-unknown-freebsd.tar.gz=d5da4fed34f7c008e6365475e2c9a8ac6b74468839fe017827e3c884fca95b1c -dist/2024-05-24/rust-std-beta-x86_64-unknown-freebsd.tar.xz=7aeade644917bfb22fe68f427a46e21834d45fcc626755b0af806ae28d018518 -dist/2024-05-24/rust-std-beta-wasm32-wasi.tar.gz=3c5d32303ca72eb469730421945f2d2216f8f96aa160d11d6b2e38c6350763dd -dist/2024-05-24/rust-std-beta-wasm32-wasi.tar.xz=9705313b0e7d696b4e7c4ae6201e1dd2a02c51b5d0caac730591419322462f0a -dist/2024-05-24/rust-std-beta-armv7a-none-eabi.tar.gz=afc32902cd96bfd1c72e5d2cda240a2275f8b8262a0f952e53b39bdf267ffe18 -dist/2024-05-24/rust-std-beta-armv7a-none-eabi.tar.xz=8a34c9025601a2ee0dabce89ec195fa3bf990986517955768409f3620ae90efa -dist/2024-05-24/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=dddbace8cce3233b6a906ea75032e21c7f2a07be131ff7c356f9d7d59bf90fee -dist/2024-05-24/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=b833758c5555d8805191527f676a20ba6e902fb4da538df8795c5282f495ab65 -dist/2024-05-24/rust-std-beta-aarch64-unknown-uefi.tar.gz=2750fc63254bdb773423483808363048126f20246d8d1a26800d06dc7489807c -dist/2024-05-24/rust-std-beta-aarch64-unknown-uefi.tar.xz=ccef9823e93948996965f9ed2e73f9dd1638a840c57ef96e5c8df525ac241af3 -dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=47ebc0eb1bbfa824df620a73d1253f22dda9a2f0810c9b6c542e4a3ed545e899 -dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=6b5d87a1de21c15352121a9380449ae1df9e49b983ffa2431e3e2767a1b36501 -dist/2024-05-24/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=6e3adc75a553a2d97214d2147340ce23a09a2cad1f5e411048b17f74cc735128 -dist/2024-05-24/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=473c1a57e19527a5a710b5ee59692a1f9d0759d5163de0337e061b006765f197 -dist/2024-05-24/rust-std-beta-i586-pc-windows-msvc.tar.gz=eebbea699b2cd32d14123af5ce49ed2fc81f8b2b8de8a83048bdaaae3d0ddbd9 -dist/2024-05-24/rust-std-beta-i586-pc-windows-msvc.tar.xz=2a9591eeebfa1ebb4af31ec8c0929b9bdb353ed92c1f22f4a5651d0578a6a5fb -dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=036a0bea6dbf65183a3d772fe2cf79c9ad86100274680b639e23683b5a29aa6a -dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=ebb328a83ad6cdee2e2b26fce63e6ad57293726a59352eb7bb9ac2d022504c33 -dist/2024-05-24/rust-std-beta-i586-unknown-linux-gnu.tar.gz=254ba6539d9c7b3b7d1b7ef92056c8c4dc7a9378da7da2575b4010cdbf9ca718 -dist/2024-05-24/rust-std-beta-i586-unknown-linux-gnu.tar.xz=9dfb77901799850f50ae983d05aa9467fbf50d0995b3dd1de880dcb48663706c -dist/2024-05-24/rust-std-beta-arm-linux-androideabi.tar.gz=d99a69e9dd172506a73412c5d3b338a0df798ef77e20e5d8376989d74ada2289 -dist/2024-05-24/rust-std-beta-arm-linux-androideabi.tar.xz=35f9022e3aff144157a504e73107cdc4fd7aab4e175eb193d240cdbc539d587f -dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=aca1d6e2bafd7a446a52bd5a6b6daddb36a2e76f29ffac3ba17cc47f80c2af9c -dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=f967c44f7ed974abf292f4b77ddf1e875f08eecb9f8ad930f7d22ca49253b59e -dist/2024-05-24/rust-std-beta-i686-pc-windows-gnu.tar.gz=61da28d58e15c845d96ae5c1aa93710c47cc3f1903e001bac55e208ea76693a5 -dist/2024-05-24/rust-std-beta-i686-pc-windows-gnu.tar.xz=6aae3ee172ed6ea5c4f547841c70bfbf26879698c984c4b94f295846282a8643 -dist/2024-05-24/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=aa7cd934f8d17ed79c1d5e37acd67e3f988a0b727a72960b7d9858f965694c19 -dist/2024-05-24/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=2ab9fe2d4e6679ab880ff27addee27c9efa6c851e4781f20971ce035b5037b86 -dist/2024-05-24/rust-std-beta-thumbv7em-none-eabi.tar.gz=96281c576bbf4a1eb9ce814517040189be4529050af2fbce9d20cdf0549154e1 -dist/2024-05-24/rust-std-beta-thumbv7em-none-eabi.tar.xz=1f37734d1987dd0c58f03ee1374a214ef3d35244d455908ca9b346d5945e3aaa -dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=515f28e48b0237144bb4110b15c1dfa9dbbd23167b3798a32cd8cf28e741e2d6 -dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=469ee9ef8ec15d8203f07630d72ac32ac262a0708617b712f139f1f3adfc7e62 -dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=066b9b8550ad7960bf6653bdc762ad5264f697ce2122b6789175d270ed0ff9ae -dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=7dcde7ccfd02c980ddc33ebb980b1fc364aab099ffd7698a758a375102d48ed0 -dist/2024-05-24/rust-std-beta-aarch64-apple-ios.tar.gz=b54b1fe276bf44c39f55678aa4b5c8d50c44332d8ba515d94d057da2e1e036c1 -dist/2024-05-24/rust-std-beta-aarch64-apple-ios.tar.xz=1ed8171e1e957aec55be7410f5f9fd7e1b48473f4bc85d1f81360502ddf562a2 -dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=b85f3e30dada40bc826daa9f02883924cabcf25dd0738e9f783b4185e5bcd6fb -dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=4a5642069ce14b53a0ebedf808e9580cf145e30f0e8e61400a27ed14956ed295 -dist/2024-05-24/rust-std-beta-i686-pc-windows-msvc.tar.gz=3296a8cbcbbc8296a28d1f97bf24f0c47142c7524ca83d1e215adc6cf1ae459e -dist/2024-05-24/rust-std-beta-i686-pc-windows-msvc.tar.xz=5ff405dfdbc42805f8fadd06323066e2a0aa238517871c65198e0c7eb8f6c210 -dist/2024-05-24/rust-std-beta-thumbv7em-none-eabihf.tar.gz=01893bc682d37aa38bff5d41e8b61d23ece07f64f950b2efefa2e67efeb47081 -dist/2024-05-24/rust-std-beta-thumbv7em-none-eabihf.tar.xz=fcf60f22fab4d53f0352f98c1def023ec174d4d930b7ec0eef71e4ca6a1315de -dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=39feeb9da7f9901db336af32543785fd3b0a587684aabf42254efd763461c820 -dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=f14b77154f905166c769012e600321f1ff9cf79155f9031d7a05eb7469353569 -dist/2024-05-24/rust-std-beta-armv7-linux-androideabi.tar.gz=49c2f372740848e34c8a60256ffde8c578be529087855e517af27a3f4f440428 -dist/2024-05-24/rust-std-beta-armv7-linux-androideabi.tar.xz=5dfc8fdffd7f502ff05f50b8834424f7129b0f7be80647eac466e9fa19660e12 -dist/2024-05-24/rust-std-beta-i586-unknown-linux-musl.tar.gz=7dcdd118d7f862b7bb532fdbfa94a92d88a035a22310c4c2f6c9fc2230467d6c -dist/2024-05-24/rust-std-beta-i586-unknown-linux-musl.tar.xz=dbccad2e2b705f2b38ad2b0a8da9bdd3ab58849818051674c26cf516ad7fb37b -dist/2024-05-24/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=06ad4618876e3c9413fde9763b93271e15451ab91c65b56ad6f8be958d2651ff -dist/2024-05-24/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=079120eec04d3940aa4f96627fd6d9ef8f74662eb132f52f4e5c797f5dd16678 -dist/2024-05-24/rust-std-beta-thumbv7m-none-eabi.tar.gz=2b0c040d29177a6a1829b3f4e5f5be9313c70205366707d586f4290e80c081d2 -dist/2024-05-24/rust-std-beta-thumbv7m-none-eabi.tar.xz=7487ecd436a99fbea0a968c082b42c6036ea0a7f66e8175e61aa0139ff2f80bd -dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=041e08179dd50bf95ca4f66bc5b1a10b958bc696774997139fa6754587c45336 -dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=4a7e06b730d3e35318690fc2927e4084062754c2256e5ea2bb37014e3c66101b -dist/2024-05-24/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=e0cbee59a29d119616e60766eb68b581e27a661498c6af8b7e3cb8279078ba49 -dist/2024-05-24/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=7a21de0bf78aa43cba18f560bf2668c902ee4755fc74f7fee7128f0fa9ded5f3 -dist/2024-05-24/rust-std-beta-aarch64-apple-darwin.tar.gz=dfd520844463a19cb99dc9c33849d646970166e3424c5dd96fb69c4483bd14f7 -dist/2024-05-24/rust-std-beta-aarch64-apple-darwin.tar.xz=7aa566be6a31bc5ebe6f588f521933d2d30514a3caa29332c91a9bba2f41f37d -dist/2024-05-24/rust-std-beta-wasm32-unknown-emscripten.tar.gz=70efc840eb8b45f0c4f527165ca87a913d18661cf4996766448c03bacc5ac429 -dist/2024-05-24/rust-std-beta-wasm32-unknown-emscripten.tar.xz=b19493c7894240666496a4cde38cda7dbcce3977c0014cc531f27fedfaabeb6b -dist/2024-05-24/rust-std-beta-loongarch64-unknown-none.tar.gz=ae808e787aa5997f2f6ab0fa4bcd65c3c3724d909738b9f78998796c939c6d83 -dist/2024-05-24/rust-std-beta-loongarch64-unknown-none.tar.xz=2bb6da4f902a8f1d6725705c16d513478c027cbf82c8ab9948feeeed028f60e3 -dist/2024-05-24/rust-std-beta-x86_64-linux-android.tar.gz=f29b6c9b9f507858c08a560569bea2a65a749f3f906caa92a2f78998e3530d25 -dist/2024-05-24/rust-std-beta-x86_64-linux-android.tar.xz=7b79450216d0e11e6c3cf241cd57b5064388a8d6d7c0b0e52d29f8373ff97da1 -dist/2024-05-24/rust-std-beta-x86_64-unknown-none.tar.gz=37b03d9f74ec899fde6ae56eb6af8e6b04c2bf8fdf2de08f14fd576569c7f78f -dist/2024-05-24/rust-std-beta-x86_64-unknown-none.tar.xz=6d212f421ff3b67ed0c0b205a1c3af1df6c5210d21127faf53f906ddc46f1758 -dist/2024-05-24/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=53d0a088e7e70b333a72a83bd42f57c81c24520bad9ae89ef710bc2ad658984b -dist/2024-05-24/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=f26ac1c83990634235b44e14884307a8cc35ab730747b6e4fc90542a985d164d -dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=d8385e3c27433ca0898344dad62a91a5bc29b5cbacc5660cef82db0475ce9a04 -dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=4478fe4b44978f4000708014802365ff25dde402acdf1546101fa07fef329c9e -dist/2024-05-24/rust-std-beta-x86_64-unknown-netbsd.tar.gz=ebeb2599218420288ea2b95dc5c1a30f4482a37ff28b06bfc945569f60c8b914 -dist/2024-05-24/rust-std-beta-x86_64-unknown-netbsd.tar.xz=5610b2b28f534eec0003b848621881d3b0addbefdfd69666dc555124aa6dd600 -dist/2024-05-24/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=5bed751da30f4ec0d76613ab04b5e7687b0928539215241988ae792e93fc1ac6 -dist/2024-05-24/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=a46f5557facf0e7fe88cb70a52afe1bf7329836ea3379e9eb3d2823884806f35 -dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=ae040d65d4a52e5369c212f3f3e8986eb92e903d2661734831d253d24efd9f57 -dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=5bfc44c33c26cba4d381b3a4ec0821ed6fe7597ba1ea33f53f4ed5b9e883aa88 -dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=7a85f404f581debe2802c64da4e421eab591a47ca40518249c3293d5f3fa109e -dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=02b85ff8b77947f53e0bd70c9a40c5bc55fb820f86efb40c2e985266153553ec -dist/2024-05-24/rust-std-beta-x86_64-apple-ios.tar.gz=db60e79cb4497d46467de9e2e808ae58ee329e2cfc7a114f97d7455c756ced38 -dist/2024-05-24/rust-std-beta-x86_64-apple-ios.tar.xz=fd7c3fac452faaadf1f907a270daf4e6b09063d9023d0a00bcfbbeffa66aaba5 -dist/2024-05-24/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=6ef5201b5b5ddc2c8ea7fb20186f086e0ebba77992b86ee9517973063dde8393 -dist/2024-05-24/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=32744f5af908ff5c925f5b6fe9f2ddb985b23b3a707aa61c5bfbbc4754838d52 -dist/2024-05-24/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=857d39bbcd5b8ea6ecefbbbf5a082b11e0e96e51e85c06b33aebc0b96bc48a5f -dist/2024-05-24/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=d51e77d6fc82bdbae84d4bb787e4df4167a3bdea6ab211d9b8ddf79c285547c9 -dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=8b5578ab21645fd5ae11dd8e1c6bcd6ff8f402da94345a5a5c462ebddacdf733 -dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=d3f1f2821af7ec976fc5f68cdcea77b3b36d0e1f54ca17e86fd92b0083d113fa -dist/2024-05-24/rust-std-beta-aarch64-linux-android.tar.gz=09095551ce4bca6bb872b07c4a5d62cf96915fcdb95f6e36884b2f6758464e5c -dist/2024-05-24/rust-std-beta-aarch64-linux-android.tar.xz=5ab50b5e63d10c1a2edcb7c60cddb081f2779dfcdb6ddfd1785c282c775c4128 -dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=85633e33d5c82d99cb59d9ac2cf6811b871db12ca3530293ffdd73870a3ee758 -dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=cfabeb1cecc122b16ff8c63a09e25c15b4855ae30fb71d631ae106150fa10595 -dist/2024-05-24/rust-std-beta-armebv7r-none-eabihf.tar.gz=79532507392a67355c649f92c575ccacce0c73e5c3bec969b0f501e82c3ed291 -dist/2024-05-24/rust-std-beta-armebv7r-none-eabihf.tar.xz=c47637bcf4a3b031f43c5225daa76bd29bb747104ce34d3020328f677b186246 -dist/2024-05-24/rust-std-beta-sparcv9-sun-solaris.tar.gz=b64d6b7272689d68074fc15779bb2dd625a897b2afdcc400d6b21f3d64aea45d -dist/2024-05-24/rust-std-beta-sparcv9-sun-solaris.tar.xz=54688000828eda67b5761e405f3318f97f58616ecc0fd4b67a3da1ad5fe24471 -dist/2024-05-24/rust-std-beta-x86_64-unknown-redox.tar.gz=6ba9d6456afab0e61593e12a34bb50cbdb8bd78def16eece0f0c79703fd31499 -dist/2024-05-24/rust-std-beta-x86_64-unknown-redox.tar.xz=4b88c220a125af0d7c3a8b50c2edb3acbac9f5a3d54630e5aa926a898c8c5ee4 -dist/2024-05-24/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=194780953225139f9c3ca0ed92106a34fd7466aeae3b92aece0fbed31c22ae7c -dist/2024-05-24/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=7907a4234a8cd358df1ef1e462136d1c31435461806b7581e621698afce8f1a4 -dist/2024-05-24/rust-std-beta-aarch64-apple-ios-sim.tar.gz=faa185048776def01bd11870e2d1d0bde2fca0654ffe01614f36a2602523f261 -dist/2024-05-24/rust-std-beta-aarch64-apple-ios-sim.tar.xz=07a424016f695d47ceacb6966983a2fec1414caa9ef5bf84d72540283686c639 -dist/2024-05-24/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=c083674853c3412de578f469e50a367bff77f5f3f8e85bff082200f769150bb4 -dist/2024-05-24/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=2e29b73c2942fad3f2a79ad294e16b124c7c271ce26c6e2b65d5cfadb9709c3e -dist/2024-05-24/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=f5e0be0aa0ce467db0bf18fb9d306f88efa36786ea28539fec841300f13fc926 -dist/2024-05-24/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=e7c5d53eeb250006c2ff5c90bdc3a31fd19edde7f9022b96f86655889a2ffe43 -dist/2024-05-24/rust-std-beta-armebv7r-none-eabi.tar.gz=d78c22fb8862dd3bd258e7982dcce54b859756b8f3bede42097873dd7239e14b -dist/2024-05-24/rust-std-beta-armebv7r-none-eabi.tar.xz=bb1ca2a1bf420f5feb10133ac208f1be8fe54927af236855202758959d933019 -dist/2024-05-24/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=3bc49069aaba38a7ac627181b73f6249d707be590d77bd410a90a59c9ae98378 -dist/2024-05-24/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=a66a7b99c95b600abba03330e9f26fdcf87860259f81d41ab629643663c188e3 -dist/2024-05-24/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=c17554b2eeaf0af3115fbf3659ca22be0ca1ef7b4c64c831a18466db04cc8d02 -dist/2024-05-24/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=f4b21bf361ffcab4abc8ecbcc0c671788f4f2df058a24334d0aa0c2567c86fbc -dist/2024-05-24/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=1e99b060eb7686203e8b49a2ead224ae3a28456b14a7db89585fe547673ab0c2 -dist/2024-05-24/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=dca7426cdc98b799cade30c8adb4386c4fd0be2d1e6fd055615a0d0350dfe396 -dist/2024-05-24/rust-std-beta-x86_64-apple-darwin.tar.gz=2d683687edd6df5f650979fe8d4ded9c813a695033f11be7444fec7599f58225 -dist/2024-05-24/rust-std-beta-x86_64-apple-darwin.tar.xz=f14f1f132b28d67737fd7d2eaa740a74bce2f19443f0e938c26e182be97404c0 -dist/2024-05-24/rust-std-beta-i686-linux-android.tar.gz=3b812e866ad74e542fe32c625ffac712ee1bf3d101f73828cd938bdbc688b7dd -dist/2024-05-24/rust-std-beta-i686-linux-android.tar.xz=6cd72f9ae6b0459f57e8cc7c5161efb0b0477bbac33339951c9b4ca4f4512de0 -dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=cf0436b2a84bdb83af01a9383dadb2d0bdb43edbcb959c28d20d8874a4b6bc3c -dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=afd01da46d82692d8bea9eefa31000ca10372ee7bdc5a9d8c6b5c4bcecd930cd -dist/2024-05-24/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=3f90c703dd67cee0972536caccc6641dbe5bf38eb8dc822937ff3c98abc97710 -dist/2024-05-24/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=a79012cb247484db2df607a63e451cb6748be1a103d6e368883d95e92fd5ee8f -dist/2024-05-24/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=8df8df9a6eb55bc9b63dbb4b1fbf3e15ba6f95b0ae1e901d4f3d2e594d4fbaef -dist/2024-05-24/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=f110b657611fd530af1fdb20b06384a41db126832ff9a0b8e3e53b508addf1ff -dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=f89ad7191d2eb0c5d8b01892e61e68747e66d18214152cdef5c5b191a1606981 -dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=729057537bb4494e3d060c26867bd6695f62a096eaf33582010d583c7234a313 -dist/2024-05-24/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=ea83d20d4dc99b7e9eeef69eeba2224015fc1bd0b0ad4695ca6dcb537a5f610b -dist/2024-05-24/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=b3615738d1c067d22327b62e416e06cc57c08c2141c0a478f265fd888ce6f655 -dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=7915fd0662c2cc9724395745bb23d6589e48b74c11151b5674fdd7834483c54a -dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=d868ffc4f8b60bd61d862e83f445c783b9b98b11041ba9d284354d1c7c5c81b3 -dist/2024-05-24/rust-std-beta-x86_64-unknown-illumos.tar.gz=9d4ec9d659228b86780d29f183b7b1d8d9087290d9602659d985b5a4adaefe52 -dist/2024-05-24/rust-std-beta-x86_64-unknown-illumos.tar.xz=315ef515146f4de92935fd02a458bf71cbfa967d426b7d781b361f650752fb0d -dist/2024-05-24/rust-std-beta-i686-unknown-linux-gnu.tar.gz=c3cfe615737af46a5de0c0c71cd530d8f1b8fe5d8c9c89865ba5d127c71ebbed -dist/2024-05-24/rust-std-beta-i686-unknown-linux-gnu.tar.xz=fb375bcafb3d35146ee387772440921cf1ec737f48e035bb34a6772ed6f98435 -dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=0b5253ef9d9d1298423e6fbc1170e3a7173717ebfc57653debdeceb80df74d8f -dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=f1ca8bde4ca0621bba03e94de67167c01a2cc5b37f5b77e600986c67cb477ad8 -dist/2024-05-24/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=9eaa5a78691b16244bb8d2d4f1e22b3548243967b49572a276a66997a04733a1 -dist/2024-05-24/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=f4919dd99711b1b0c7c533a2301423a3c6b01534fb8dfb7811356ea827b43b3e -dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=9c5156e544557ba6cdc366407cac81b90255b0759c7e9ecf19d15560f8da0338 -dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=8f9841d0d6bf623330e497304efed6bffb96f081208be5b5952c493884d803f7 -dist/2024-05-24/rust-std-beta-armv7r-none-eabi.tar.gz=6fbf1ea31e37333c52e2c28d92baadac89bdb2c53fabe18b3977c2a837f69606 -dist/2024-05-24/rust-std-beta-armv7r-none-eabi.tar.xz=e1b656df5f54c6317ebbe660ca9488a6c93e1516e4d8cd13d4d601d98e18cc71 -dist/2024-05-24/rust-std-beta-x86_64-pc-solaris.tar.gz=d5831bd26c24ee90134178a0877944ebfc5fa743e4b6644308f2e6f9480cbb94 -dist/2024-05-24/rust-std-beta-x86_64-pc-solaris.tar.xz=3441e45c78e670b2cbb5becd10fb1a20232adfba8a3b27534b364fad47a8b14f -dist/2024-05-24/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=3ca6068a2b62dc715fba00c8f8c231465a8cb918bcc0ec28ba5eefd6322509ae -dist/2024-05-24/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=3674d1fb506ee0237f8dc359ebce38aaa1f302e0cfda1a23ca083596aa6ed1cc -dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=6150c318589db8d2243619b85e0bdbf4433dedd1f6bdaf8ab5a0c48d0fd9a62f -dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=3a03e4ee500596e03335f7d01e666727ca35f861a82dad214ca06c09c11246a0 -dist/2024-05-24/cargo-beta-aarch64-apple-darwin.tar.gz=39998995295e1c03bf81c2f384d871a0270e3b87ca87b23c61642e6455c83287 -dist/2024-05-24/cargo-beta-aarch64-apple-darwin.tar.xz=4a837a5313c2b7c340c1df32f37679975abb7263966d90f755e87c4925262065 -dist/2024-05-24/cargo-beta-x86_64-unknown-illumos.tar.gz=6f6b434451c5e08e89feaab897d6d70445b380e12ad398453ec36425954c1d09 -dist/2024-05-24/cargo-beta-x86_64-unknown-illumos.tar.xz=183082bd9b3ecb97831d22a1f88820a9622cef480db113695907fd00eac25602 -dist/2024-05-24/cargo-beta-aarch64-unknown-linux-musl.tar.gz=7d500984773dea88db82653b5565f6d73a622cbaf9da2db942b3453f0b965296 -dist/2024-05-24/cargo-beta-aarch64-unknown-linux-musl.tar.xz=9e9a890b7314a731ce63d57c325cd6476c6fa50e0364b4c7b8e2e5620c83ae05 -dist/2024-05-24/cargo-beta-s390x-unknown-linux-gnu.tar.gz=5a3bd87bf129c826ec705b94f0ebca06fc2b3629d191b76fafc09cff8c59adc3 -dist/2024-05-24/cargo-beta-s390x-unknown-linux-gnu.tar.xz=24fcbcea1863cf45eadef4fa575d3ec1faded48ddd9aa02f45d199a4b09c136c -dist/2024-05-24/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=6a844b4584ea5c89556518ad063ff6298e6c47853d23f7d8f96a07774b0329e3 -dist/2024-05-24/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=4f20df4cd9832304e4a5963b27f7caa3d5cf7d1d8ca7a203db3c3f30552bf2e5 -dist/2024-05-24/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=d986028f54153318e862d42bc6f6858b88dfb32089d1039e7cf1bba384ccae1e -dist/2024-05-24/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=a6ecc5e601620ce896f4371487a7cd9ae529dd20f760d44c498fd705fc4140d0 -dist/2024-05-24/cargo-beta-aarch64-pc-windows-msvc.tar.gz=59f6d05082f4feb8d1fdedc513c27f4d1680280daa40889aeada106c8d363678 -dist/2024-05-24/cargo-beta-aarch64-pc-windows-msvc.tar.xz=820c078d60cf6530f1c67111c99ecfc492b564e4f48113770c684677a553864a -dist/2024-05-24/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=8c89e03e9c8f41f2efc8c0c05397051dc67505b634d9b9b7a076471b334a6b8c -dist/2024-05-24/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=592c740d96a1d78711c8a861b3ea17c36a806ca2dc1d869d51dc6e5de456ee60 -dist/2024-05-24/cargo-beta-i686-pc-windows-gnu.tar.gz=9db89655fecd5169d7cfe6869bd901abd621f6f5ccc9c2928ca52a666ef11eb8 -dist/2024-05-24/cargo-beta-i686-pc-windows-gnu.tar.xz=9a37c1efbc17ee392784109db3d5674d95b68829ef87895c2f7dcdedc2271952 -dist/2024-05-24/cargo-beta-i686-unknown-linux-gnu.tar.gz=0b6e0cde1312e5294efd1f9ff94a7448e8025b755d02fb36b0e15b2642069cde -dist/2024-05-24/cargo-beta-i686-unknown-linux-gnu.tar.xz=5b96820f5ef0f04afeda2fc4052788a0a5c17f24a73680abe265d4a52a27d266 -dist/2024-05-24/cargo-beta-x86_64-unknown-freebsd.tar.gz=42a56ca6639895afcc379daa674270aafed270ed3698ac7a16d2180b67d78da3 -dist/2024-05-24/cargo-beta-x86_64-unknown-freebsd.tar.xz=9dc792621d33faaf4c5b779df0b72eeb87ff2756bd7347517f50ae0a41d067ac -dist/2024-05-24/cargo-beta-x86_64-pc-windows-msvc.tar.gz=e30d1feb140198a1cccba94f1f4f12a1e5446c6925c4bc35a82dd8fed54be079 -dist/2024-05-24/cargo-beta-x86_64-pc-windows-msvc.tar.xz=b754bb31b01483bbb92b14f1fb7de241295223c58a84059f36b2237c93963bad -dist/2024-05-24/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=de99b7e5b35a756f4d3ae4f780a154310c6062dbcb9c9ab0083d061976634d0e -dist/2024-05-24/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=224f4a46d4cc3ea797fd7cf70f80e2c16ee758cec23aa1816964d9128264928e -dist/2024-05-24/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=0e3907c9e2d11bcf9ae9739c01608f66048a63c343cb006374ddec08d6ea7c78 -dist/2024-05-24/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=981ce940535a7684952299c1be88378c6763ee91d3765b014330aca0fbc65ce9 -dist/2024-05-24/cargo-beta-x86_64-pc-windows-gnu.tar.gz=ae0074711a8ee88061859789dbe7c7ba9f4f306d5d99fbcdf1a4fb0aef7ec2a8 -dist/2024-05-24/cargo-beta-x86_64-pc-windows-gnu.tar.xz=40de1cd1454bb99a8c3ff18bbf2950fcf480152536dba1bc20576e3cb42b62e2 -dist/2024-05-24/cargo-beta-x86_64-unknown-linux-musl.tar.gz=1f849b69e086fde12e342aa935bdde649cc3b18ab9f372c1decdc6ab52ecae77 -dist/2024-05-24/cargo-beta-x86_64-unknown-linux-musl.tar.xz=75e6ca1b2b75de206ae4c6c8b98f36872e00cb92151c064e29bbb9a5bf47d441 -dist/2024-05-24/cargo-beta-x86_64-unknown-netbsd.tar.gz=fb6a694dc1dd5c0f8e0749354b54ec213ae62977d2293b76806da8cf6b4db18a -dist/2024-05-24/cargo-beta-x86_64-unknown-netbsd.tar.xz=5d2bdce7e5ee3be7a46bc55614ff6b35c996eb95cc6348fe982207f183237b47 -dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=551b70fc54e177ee31a33d79ea7c8ae19b81cf3bbbc767e23455f3da4d1d440a -dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=3ceac72674b7ebc33ed3b73057ff93c4569f9bb47d15c743a9ed2775a51d9eb3 -dist/2024-05-24/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=b38fdb21440650b6cbecd6c2e049b95519f60e37af48d1a98d38ea82fe27d908 -dist/2024-05-24/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=74be24ebefc943be201b114d9eb49e15fda0880eb03c0df60ee382f2a48dd0d0 -dist/2024-05-24/cargo-beta-i686-pc-windows-msvc.tar.gz=70d1d27a68f084c133fa0b3c110d43be37de2446a81e27e92fac5678283fa26f -dist/2024-05-24/cargo-beta-i686-pc-windows-msvc.tar.xz=d02feba93e984c5d5aba5018499c830954f3b49f68c9885f11bd04b48b277f0b -dist/2024-05-24/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=f4eab6af2e369b32879a97446c962c67b8733aaccfbfdc60e04f72e2baf6ab82 -dist/2024-05-24/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=a34c6b4298c5b8fdd266b6035b6a3c5b0458fbb64a853830fc6f9df2c1a0bca3 -dist/2024-05-24/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=b6fac94136e6fab6c0b6425890060f20481bffaa98bebde52f99564afe8e2c3e -dist/2024-05-24/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=6dc5ebd5e03441015655d5929825364b9bebe0659df42ddef09fc489fe22155e -dist/2024-05-24/cargo-beta-x86_64-apple-darwin.tar.gz=f08d91646163be427447b11fe7e1214df4444c98c99070d5f154ba79e47cafa1 -dist/2024-05-24/cargo-beta-x86_64-apple-darwin.tar.xz=ac86b164e6a95388510c6cd5ef6fc82cf9794d5f3ebd12f1bc94f16ca2c85ff4 -dist/2024-05-24/clippy-beta-x86_64-unknown-freebsd.tar.gz=07e962b44908356b427c350f1208a9c017ebdbf4bb6d5f952b1625833b552068 -dist/2024-05-24/clippy-beta-x86_64-unknown-freebsd.tar.xz=6e0173c30b8087e9ff2a4d7b46d178d380ec4a1443034d5706dcfeb8dcd8ecfc -dist/2024-05-24/clippy-beta-aarch64-apple-darwin.tar.gz=ebaa62ae3e7191bc5be56f93b47493641e705ea312071e723a9e03bf9fb487ab -dist/2024-05-24/clippy-beta-aarch64-apple-darwin.tar.xz=3d9c9ecbbbfd2d475d4bec4141e5da4559f092d5167127fd4eb13f5397abc693 -dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=ea1d746dfe195065e8d387ee06db4f0d2615814b9c6ef6246f85d1073c471b06 -dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=86387463578f29dbdbb79257ea973a247df4c6774e88df6b38fcf52b79c99e02 -dist/2024-05-24/clippy-beta-x86_64-unknown-linux-musl.tar.gz=383a5528ac4ac0524fadad6e2bb7fef0b3a03d795250057cc816533728fbb4a7 -dist/2024-05-24/clippy-beta-x86_64-unknown-linux-musl.tar.xz=6f796fc9a9039815692dc5e127fe83c5fb71f208f0876a5c6324bfa9953899bb -dist/2024-05-24/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=4538a4c73464791275fb0eb49ef96356966521131a33ed74c5de1ff587b57e3e -dist/2024-05-24/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=e16fd33e2788bfe6d7dfdaf2692b21bf61edf3d34197cd7d32b1ea998ae03000 -dist/2024-05-24/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=61e5c68a5eb0b7ec35b2353dcf19a54e8fd63a4cc8be1e1651138aa8193cd0d6 -dist/2024-05-24/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=6e2a98ffecd48aae032540eaa0c9573317ffa920d6a21e2e2f2e512d8eb3b991 -dist/2024-05-24/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=ae6406baa95d37a95afec6c3cfde8b1fc5b811fa824785ebd6b17d5f1f31d329 -dist/2024-05-24/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=fe98fd0b83763a2b73622ec3ba849ef2e0e31656010b2be3b2ee31875b19a826 -dist/2024-05-24/clippy-beta-x86_64-unknown-illumos.tar.gz=3a4eba33496cf3c1b116524b3f5466426148b5bf84bce2d1b3865c4429277ba6 -dist/2024-05-24/clippy-beta-x86_64-unknown-illumos.tar.xz=17a5a7e10a8821c12a5930fd1ed85e3a545d16471d7948d09fcfe536fb6556a9 -dist/2024-05-24/clippy-beta-aarch64-pc-windows-msvc.tar.gz=176239e95b1efaa8d12a41792d008ffc4919ce49a86cecc1b5a83fbd94983c9c -dist/2024-05-24/clippy-beta-aarch64-pc-windows-msvc.tar.xz=0e4abffe1c361b54572572633cdb57ba4b5e43aba01b1af9298532de8201a2bd -dist/2024-05-24/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=1b36ea0173144992dbef9bfbe7117454b7d4bc3a717bd04c6b8470f9f3feb38d -dist/2024-05-24/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=43371fd91a35451213a5b082190bb18178ad712627f7243feb1acbdcf5b01c21 -dist/2024-05-24/clippy-beta-aarch64-unknown-linux-musl.tar.gz=9ae71ea9dfe0b56882b949321e4a2820bec4883614bb052cd71d9cce3b203ecd -dist/2024-05-24/clippy-beta-aarch64-unknown-linux-musl.tar.xz=92e23034c6287754a5c7d49c3e53313a614addb220fe0eac36d39b2883b445b6 -dist/2024-05-24/clippy-beta-x86_64-pc-windows-gnu.tar.gz=2076ed6ef91cd8febcf7daa894d110a2acb8a5b48a60f050c5e126c9378624a2 -dist/2024-05-24/clippy-beta-x86_64-pc-windows-gnu.tar.xz=e32790707ddd05624a7066c6185283476aafd7a304fe7528587765102d0fb63e -dist/2024-05-24/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=f47378feae7c5b4d15693ce8b170152237e5adfe027e53e4f017dece19da9f68 -dist/2024-05-24/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=af17738279b4acc3c75974b070c63de6385a62e7cb2ced3d445cb2c7d9928653 -dist/2024-05-24/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=1fa14738518c68f24668fe42ed6653b4a80ac12ac121f36b488215901ea49349 -dist/2024-05-24/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=f636b9d9628b5be5cc873b0698bc8d1a8487ca81309e359e60d6065c3771f8c0 -dist/2024-05-24/clippy-beta-x86_64-apple-darwin.tar.gz=14084cadcf4e71259a3a7e2189e648bcc8f8f044b5abf027079ebc140f3593ae -dist/2024-05-24/clippy-beta-x86_64-apple-darwin.tar.xz=6226dbc6d0e180eb7e946606cd7a5879ce558846334bfd79105ae23cfb7eee63 -dist/2024-05-24/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=6c58a39182997f07a7391e069ae6f141af8a2964f8c5583bedd70039a759c52f -dist/2024-05-24/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=a4c33cdb8711b784f533a685c3a6491f4c841fffcf573b1832315360788833d0 -dist/2024-05-24/clippy-beta-x86_64-pc-windows-msvc.tar.gz=f12a529b11e68e8dcbaeefc13e98935171bab78d5aaca0e6ea6d5fccc71b23ab -dist/2024-05-24/clippy-beta-x86_64-pc-windows-msvc.tar.xz=b060a3285527311eda126adc0f70aa6f361718ef397e89d488a58be7ff70d316 -dist/2024-05-24/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=a7a455d8a0f102d83c07987045beae1a9f633adcbb1752a6c338a0056183cf06 -dist/2024-05-24/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=47869852cf4b215d71ffbb67decee05aa4627041353daa9acd36dd6f2cc8ca71 -dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=99c4401de28a11dc31d868d01d8de661f45f6238ab7fa36bc203868bf9977efd -dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=828ffcd6fae6e48d9af7eca3017eec88b5d79ad5f892dc72ec598d908c23a7d8 -dist/2024-05-24/clippy-beta-i686-unknown-linux-gnu.tar.gz=dfe75e08d07df8e2d2f8b7e1d7840a505e42b2267b0f3b63c4cc8356dc3f4519 -dist/2024-05-24/clippy-beta-i686-unknown-linux-gnu.tar.xz=83270728dc14957c00a8801a5a187b9247b7c7bac7347f71eaec5e2fc59e17fa -dist/2024-05-24/clippy-beta-i686-pc-windows-gnu.tar.gz=7bef578957e857cb38b6cdc126bd055b95b5dff54d11d73f68413425cb4cae3e -dist/2024-05-24/clippy-beta-i686-pc-windows-gnu.tar.xz=9492aa7f12aa1f38afaab16f4c1ef4d3fc45169e25575a3c691ef13b0389c2d0 -dist/2024-05-24/clippy-beta-x86_64-unknown-netbsd.tar.gz=e325ee40a680aba2e413ea314e15fd4f9b5394705f72d652d9914b4fbb16e253 -dist/2024-05-24/clippy-beta-x86_64-unknown-netbsd.tar.xz=c499d0bdc755156a058c32d4d9be8e2b358197aa89a161804ccf87b0ce8c90f1 -dist/2024-05-24/clippy-beta-s390x-unknown-linux-gnu.tar.gz=ef245e8ebc4e598ab68b5bd8fbbeaa311e4b4e0471bab961b39c4d5218655712 -dist/2024-05-24/clippy-beta-s390x-unknown-linux-gnu.tar.xz=55ce153227cecea3a6f05807a156bfbea3c7d7aee72fdfa055fb9ddcbabd041f -dist/2024-05-24/clippy-beta-i686-pc-windows-msvc.tar.gz=d2378b267bf3d0e58300d21dd302161eaea8f8e38b7439731a054597970f7195 -dist/2024-05-24/clippy-beta-i686-pc-windows-msvc.tar.xz=87e337e9a584908d6397987b89756a30e6cd4b537fbe5dfe9d4752d9ae17dd51 -dist/2024-05-24/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=9ce0c27f91a3d3a99a0b32d72284827add678b4e6b1377e2fc978397dc897bbd -dist/2024-05-24/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=2c314fcfeed780a18fef9835266a50a8bfd4c63f66033c7a2cb589243d0dea8d -dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=a1691b9a1629b0ab09505c80ef510fba462f41296b45b04bea52aa66e0314cef -dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=6d36402ae66f53c24db57f37e3f78a2bd5a07a238d59d4b4b8c000202e6e6714 -dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=e54ac8103de0de2c4166da6149c0f3da1db29cbf3909844b5fab43e1f56d943f -dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=986bc361afa619b299f1c6674651aa56a344374ab8731c9cb702a651132841bc -dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=0ee19412859c424304a8e2d66798896ab3be24057a6f12383fadd9c8283e5825 -dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=01ff0f61731da21c55618fff0aca2f900c8b1473b7efc12cd8f1d1e49b51ba8a -dist/2024-05-24/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=9d29a9809633b98851a5de84d37cb0b37b4f9e9223b42841ee11e4288dfafd90 -dist/2024-05-24/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=122e2f607f59dbbd82693ece7610d9f9a92c1640e3501921d0f6069d0eaf4ac0 -dist/2024-05-24/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=5d8d0ed9f63eb0f2b8eb43c47f0a6858702cd5e9c8f1b308b570981f54a45ba9 -dist/2024-05-24/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=203c63f477369ce5a6464d0e11a10c5ed11b2e510e6190d6e0ac9993c43f3ffe -dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=cee4cab103bf4c2b244a91c1d7578d5c807307a3367291ef1efd072f975e27ca -dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=813a55dba22fea0203e43339f95ed1ce8b7406d57b5d75cb0d11ed2638402280 -dist/2024-05-24/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=c9a941b5c05972c0fc875b052728dd5a83dbdcc8437c5509fbc4ca82cefd5866 -dist/2024-05-24/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=3bb87c7cdfd0b942d8051de34d068d3fe6b4d5c8b52534ff43d6ffd802112d99 -dist/2024-05-24/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=2bc18cd1444098b36ba3eb0648944caccac1515495c7180d2258bb29c4dbba71 -dist/2024-05-24/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=a5e49cd58fbe857a2e99dbd9b68aec300dea92a9f840dc564f6f61d71a291cbe -dist/2024-05-24/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=7b270dfdcc65d11d0741adf11f62fff5839b4262ca87a84c273c4f54ccdcf404 -dist/2024-05-24/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=3cfb7ff6d106ee2ca996a7e5790981648e4bca92ae424c780e6d6831dbe5d521 -dist/2024-05-24/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=82ef339de90bd1eb99bdee0ed4ff0431358706cb826c0810c6a05aa7432c56fe -dist/2024-05-24/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=d4332d61ca86a3c561bef17474110dd96fe73789c1fa43ba216be9a0c3690192 -dist/2024-05-24/rustfmt-nightly-aarch64-apple-darwin.tar.gz=5505cd69abfb7cf00ddd32936067088cc4448cfa09e5571516fa2e61d6593e51 -dist/2024-05-24/rustfmt-nightly-aarch64-apple-darwin.tar.xz=0c7cc98f9534c691dcba913b5d40fded47b33ca549ac75098c84d900d8452f01 -dist/2024-05-24/rustfmt-nightly-x86_64-apple-darwin.tar.gz=734c21a4018bf0e5ab561e8e485fd15f9ee38c01685aaf620808edb9a218b476 -dist/2024-05-24/rustfmt-nightly-x86_64-apple-darwin.tar.xz=69e6408ba329925f38522050f84adb20a299960c04ed3012bf075a10c4ad60c0 -dist/2024-05-24/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=d759046124506b761f0d628681e7f5ac73fc23a04f1bab5097e0796b7197097d -dist/2024-05-24/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=fb07a6adc006753ce09457b032d6e1ce06934aa8c009f5d586d3b317dde6ce21 -dist/2024-05-24/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=c7f7195f7c80e9d6afac4fd6cb6f54b4f1c53116cfbbaa06d185bbca4ef2b4d6 -dist/2024-05-24/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=5acb271b43e1f1c186666c33f322b9d3c253b929710eb73000e2eb61b3978dc9 -dist/2024-05-24/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=7aea051dfd13311ef4a95845b6cfb390c6f502ac2bf46fea335abdbcda05a2e4 -dist/2024-05-24/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=832f664b6508735fc91491fef9eca137ea6707cec000ae483d4c8b5ce9abadb4 -dist/2024-05-24/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=a5f79e10a34ad8d02645d1e6ae758812ff16e1c74b63c775c5f840fce5569ed0 -dist/2024-05-24/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=837e8d335322a4d0efb86bf6d6dd65b815548faa9e40135e8cf3b197f6e03960 -dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=c0d3c4786cf4b4c4cf0b8c26d89d6009e3e9d9c1e69092f4b55f0087b08204f2 -dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=0d8a1f390b09f8550c38cd1b74e4e8f7cccc496b86e6f2d6f74291c34cc31bd8 -dist/2024-05-24/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=56ccaaba20445959702503d1aedac87b8a9995bcd8619dd120273d0795859705 -dist/2024-05-24/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=201932eba6521c04367eb682f96a54fec10830fe954bc271ce2766db2afe30a1 -dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=e8c2324aca7fe35e47088d8c317c7f97d88830629e871987faa197d545ef644f -dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=51985f7c0530eb59dce830e1508bc270e1bb3fe7b33a95eb93142611e651a7d5 -dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=a4fa6bcf4c4b9c446236d710c1878efaf1dfdb95a2f5f3c4c374d8fbf49b792e -dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=af0f2443e34c9d6f5d85ff8cb0c0c52fa46b64275c26b57528c1e815edb8f59e -dist/2024-05-24/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=59bd9ccde4722b24b5b746d7e3dfdd48ae8f9c8b142b8c175750b8bdb2c05411 -dist/2024-05-24/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=91dcec67d9382548f89dcaf7c2c6dcaa47f9e04b777f7b8cf047ca0895fd7958 -dist/2024-05-24/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=d16ac0c789f0c79867ca74161214a902f97647d2b448ec510d48b254092ea05b -dist/2024-05-24/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=065d796ed384f07116903ae75dcb4accabb3cd81849a0083fa26b42e5ee3027a -dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=bd673c6d23377af5158565bcc48048d5a8febf346d200920e8ca8e661149f600 -dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=7f630e63ea697c95bdd2ea2edd678e8cf999c5ed9e7760c2b631ed6ecc4f112d -dist/2024-05-24/rustc-nightly-aarch64-apple-darwin.tar.gz=1f418de895c28fb684035c38f5f1ad45993ccab9bdbd247958083043ec2904ff -dist/2024-05-24/rustc-nightly-aarch64-apple-darwin.tar.xz=a762ad9b084a4221f5e24ba7cc99bfa20dfba935d267efd36ecf371de5fa6261 -dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=6fc6f1ee02ac5562da863213924a43b8cc914b54b7a7df7c0fa65b51c0cec2ec -dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=3e4343551874ebd6a41912937784938572706896f7b64b246b7630eb2de81e32 -dist/2024-05-24/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=225dfdb7af532a1de12c04bfb4ad41756db6b0c342e3e974a1587b74ac942cc4 -dist/2024-05-24/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=ef45d12cf6c0a00bd62bde5143bace4b9f4dc3d27d0e66274698fd4c12aa644e -dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=cd5c25154d3a24f9fa14bea66c149c8547179e28307989276b3450411db94f1a -dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=07473937fbe50012d4472e283bedb8fa239a02fedc880e8d3cdf96e449a7a237 -dist/2024-05-24/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=3c96788305ae61feba692d7c254c68486e6caa0a7851dc6ee545338260e195bb -dist/2024-05-24/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=f5789e53bd82a6e7593f51248342bea26014770d86b171d1e6182039e96cd008 -dist/2024-05-24/rustc-nightly-x86_64-unknown-netbsd.tar.gz=c7960546ecaf8e190e0e0a6bf21d3259b6098b440e9f8efd455c0e207db14100 -dist/2024-05-24/rustc-nightly-x86_64-unknown-netbsd.tar.xz=dcbd4e5a41496ec3a76a492b6f48a0913f3174f192b0dce38886580fe5866806 -dist/2024-05-24/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=201d715fc46c3b97c6ba56ed89b45870089ead21b5dbe107fc9c11d4e409b594 -dist/2024-05-24/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=5660fc1ea7228b156b070766d568bd27222245f4a8bbd3fa55d53646320594ac -dist/2024-05-24/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=ba5a31b8f6fe6b55976ce3fb7075cf0c539b83b86c029e1dee9259e76eee90c7 -dist/2024-05-24/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=1494876804a4eae08e22a586295d5c75fe611e90e35e98e9d4fd4ce7f08e1648 -dist/2024-05-24/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=e83d8ad735b0c2213613882affea611db0453f2d83dddcdc325100d94ecb8be4 -dist/2024-05-24/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=c41af42429b2322b140d99049fef6a2bfc6950847601ce5daf5e789939ef8383 -dist/2024-05-24/rustc-nightly-i686-unknown-linux-gnu.tar.gz=4fd2063d10fb4ea166c684edb9b790a0decdc602c600208cad2c378cb5b5f04a -dist/2024-05-24/rustc-nightly-i686-unknown-linux-gnu.tar.xz=522f49079f90b469a7580f3cbc8f7ec88f2267a5df9cb0fc06a40fa21a778b1d -dist/2024-05-24/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=622d58678e2aeca83bfa7172c9cd0fc21128917067b6492fc6a966f0715843e0 -dist/2024-05-24/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=2e021443798286eb5bdc855112970862b58bd12ea3b1a3ef7aad178f757004ef -dist/2024-05-24/rustc-nightly-i686-pc-windows-gnu.tar.gz=a14a5f1c16f8ac231083b11075aae0970370f29b7f8a6b952c945c8b4a99a1c4 -dist/2024-05-24/rustc-nightly-i686-pc-windows-gnu.tar.xz=5a389561f37d446433dc4e4d0ac1259fdfa4bb5728863a0b2e00b6575acc8851 -dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=95e73ffa458449089b753f85aaf71581d6229d1fef10f57aa6ac0a9a15f5e2dc -dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=b678c5d611324ced9ec61e36cb2ac53d595ed0d9024e987b658d3708714137d0 -dist/2024-05-24/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=07d9e8f300835045ae9bc9350aaebb0c7994398e92e43ca0baf4d491d5e06a51 -dist/2024-05-24/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=7d40e53082177294ee09d59730526586ee973b9d0aac24b4c9116db306a926e1 -dist/2024-05-24/rustc-nightly-i686-pc-windows-msvc.tar.gz=e88718e456cfc8892fcdafc1c522b67c53ba5faedf80f43f007222a8bec00a01 -dist/2024-05-24/rustc-nightly-i686-pc-windows-msvc.tar.xz=b8320cdfa66421593610eb7299d57ba20381f10bb6f2f82ef5475f86c454c2c7 -dist/2024-05-24/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=65ddf18ce7489b1bcc0d110fbd645326b960230702f6c9ad45680e44e0c1890e -dist/2024-05-24/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=f64735396de921f8b65fd74a3f2c179094770e39549d057e5222085b17976832 -dist/2024-05-24/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=cdacc2d990089859fe21fd779d24b186101bcd03f91b8f9c595ddf26af9ced5b -dist/2024-05-24/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=74c673001e8794afbf085bde1b5e010420458230fa9eadf7f5f76e5ad11f1c8d -dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=76c0a333525099ec78351d29deb0f0c7b72d8a48860c1595442e574bc454ac5a -dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=5ff07cf9292c0ba7e3860e9ec2c1de9810e932dc12d9711ba6f1795a5c90875f -dist/2024-05-24/rustc-nightly-x86_64-unknown-illumos.tar.gz=32e4afe3e4dd9f64c69da73af0c4a1e6e4c8264640b142de6bb9494c567fdfe4 -dist/2024-05-24/rustc-nightly-x86_64-unknown-illumos.tar.xz=f6d8be59445080cc278a152387e47a98d3b371758bc7f36932343d0caa5896e0 -dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=caeefbab1a93f119669078ba91aa821e5aaff5811fb3d0a6b0ec482d7bc1a404 -dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=7032353ac8ba628f8a2648c106c7a3248ebb1f03bc9036cfca61007f9acc3a0b -dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=ca53d272b136d5fa112ede10627880a58f51d99a40a490b2c9fff6c996f9aabf -dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=d24dcd68c9426f1463c60d5075a9a0ecbc494cdc34a434f377a0b09fdeabf914 -dist/2024-05-24/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=c6a05ee622261a0f4b41b1cf26b5461e1247c00376ac61a0fc4faa16ce478140 -dist/2024-05-24/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=c317af1e4bb1551edc046c426da84ad122379e5829b5e97033c94b6844b18e2c -dist/2024-05-24/rustc-nightly-x86_64-unknown-freebsd.tar.gz=3efbcc6e74d9cd4ff86803410bbdce0f1e64741870c32f33e28c660c68155851 -dist/2024-05-24/rustc-nightly-x86_64-unknown-freebsd.tar.xz=3cb7acb1bf66ba39becc6df1cf2727de424ca3ba90e74f0fd7c76f586f868a89 -dist/2024-05-24/rustc-nightly-x86_64-apple-darwin.tar.gz=427b795b94eb4e4e2bd150e98055c5a9a414937ebef7e586bcaf8a1988eb5214 -dist/2024-05-24/rustc-nightly-x86_64-apple-darwin.tar.xz=405b2a99f9a34c1d1195ab88bf6fb696fadb6c2988a3d83555e2ac4de80ba4e5 \ No newline at end of file +dist/2024-05-26/rustc-beta-aarch64-apple-darwin.tar.gz=b899079e4c3541762db909b2ec2fd73ca10c26874308831346770c35be29d6e4 +dist/2024-05-26/rustc-beta-aarch64-apple-darwin.tar.xz=2370613f7b60baee5dfccb0adf1586ec960d8590863e2be1571e5efe10f7eaf2 +dist/2024-05-26/rustc-beta-i686-pc-windows-msvc.tar.gz=d8976f398b8fdc3a43894cdd783c83bf0d7db33d6d059dd5387dd7a2840c70b6 +dist/2024-05-26/rustc-beta-i686-pc-windows-msvc.tar.xz=1eeb53dfc82b902e5f9e11bb631b0c2812c7f81a84c1023c69903debb6fff4da +dist/2024-05-26/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=512c74d27fc57bddaf8ec8865afc1ec3dc37106e07a9ef60921b2f852c16ef88 +dist/2024-05-26/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=48b01607a0316817505d4286ce075dacdb38fc170aae7e8b4daa7b75272916f9 +dist/2024-05-26/rustc-beta-aarch64-pc-windows-msvc.tar.gz=f9c8260ce005ffb02213b23530abc8bda5f74104ede11202a6b379e1cead640c +dist/2024-05-26/rustc-beta-aarch64-pc-windows-msvc.tar.xz=567989038185ddbf00d5ef5f7bde9934cce7c8d932db81c3c635283512d8983c +dist/2024-05-26/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=9fe58cd58e0f758d338d1ee427186f2ac0b644ef9decf457d4b6c0f67df475e4 +dist/2024-05-26/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=c589495fc21e7bfe3ff19736ba79ff78bc8899bc95f714e93ae4d410a704b0c8 +dist/2024-05-26/rustc-beta-x86_64-unknown-freebsd.tar.gz=4d9206a4361ed0d400decc68b2d908447de0390801bb5ef49885b42e31fc8b07 +dist/2024-05-26/rustc-beta-x86_64-unknown-freebsd.tar.xz=215b0f6ce7885bc2fa8c5d8352e4c5b9bfddb6d92f398ece00ede1bb693c92bc +dist/2024-05-26/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=a7f32c585c191b194a271c3baec3e81d8daac6a107ab5fada0b94e6c31dc295a +dist/2024-05-26/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=ea7a5b798e251fea669265bb66d8e20889e1fa0dd71c5cbb7caf9eb187462fa4 +dist/2024-05-26/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=44cb994404abeb3b9f873cacae90a208b3243a98d6c7366a7f211a81180eb3af +dist/2024-05-26/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=49cdde9184c78d03a3fc1af955c0cb37ab290f6d4f0f3a71ce37903df389f804 +dist/2024-05-26/rustc-beta-x86_64-pc-windows-gnu.tar.gz=fe9aebf5129393a8525c9be7fb3120b61a346028d23a19727dac37bb282d4731 +dist/2024-05-26/rustc-beta-x86_64-pc-windows-gnu.tar.xz=760ea53130788d624e3cbee11ade75b38abeaa10701e8205ae5cd8781f54d5f4 +dist/2024-05-26/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=0a7412f1c722cf74736120b9fce90e4f432da4a51f2d7a53320362e7e829f661 +dist/2024-05-26/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=e82df323b5544ca55a23db09fd23dff72cacc575dd25e7e056033ff2ca5ba3e3 +dist/2024-05-26/rustc-beta-aarch64-unknown-linux-musl.tar.gz=9b9e7fe38a6e1fe44e629a8523d6b3acdf199b2bb94e7cb2bc9dc4858faf2022 +dist/2024-05-26/rustc-beta-aarch64-unknown-linux-musl.tar.xz=cf1c8a2e68d22d078b69fcffa64dafa9d3b54ad4983b485368dc297c4109645e +dist/2024-05-26/rustc-beta-x86_64-pc-windows-msvc.tar.gz=9069c6b50e3842e03ed13cdd39513a17ae4251fb47893c02c58b5f4704b4c9ff +dist/2024-05-26/rustc-beta-x86_64-pc-windows-msvc.tar.xz=6a315e496629f9b57fa9b82e6cb705cc7aacde690b3619c81dfa57382bdb64ac +dist/2024-05-26/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=c31a1bf28a4d2c4470032e893b043c25c349ff07facda18587a2eb76cff648e4 +dist/2024-05-26/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=36da69f87daec24b9810ece65d51abc41128ee1874be14bbc46f74c09a3b20f2 +dist/2024-05-26/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=6b9aab90326c804aeb88bcfbc8055438bae0fb721b9d8b1a64b062836ba9efa4 +dist/2024-05-26/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=d0aeed09775c58a17649c42e0b641f20c44479056db43116ad452e771a88ddfc +dist/2024-05-26/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=4b1293f35b04a2f9e01e9752b3e8a5b61aa2375930fa72a8c3d04f52f4fbcad3 +dist/2024-05-26/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=06a653d79b84399798df9f3e636160f56c774a1593e7ad9a57f6e35a3d54fa77 +dist/2024-05-26/rustc-beta-x86_64-unknown-illumos.tar.gz=827865d233d702017b592d6c46954b54f18ffb758f79bfedf59fb535168b9b18 +dist/2024-05-26/rustc-beta-x86_64-unknown-illumos.tar.xz=4258e58b103e5a579e57059bdb1f61fa8e54854c80340888a11a2e81040bfc32 +dist/2024-05-26/rustc-beta-x86_64-unknown-linux-musl.tar.gz=be7f3f7485cfb378e105f8ea09b4a1fb6b78cd68e2a5b7e1cc354c6abfa55953 +dist/2024-05-26/rustc-beta-x86_64-unknown-linux-musl.tar.xz=ee6c02cdf6baa8cbadf8dc53a075582db428a0b149dec7c0f70bb182f49df79a +dist/2024-05-26/rustc-beta-s390x-unknown-linux-gnu.tar.gz=cbf5cc045498ade9d1051de75b127e78d7986f5dee9ca39586e9e9e3bfe066d2 +dist/2024-05-26/rustc-beta-s390x-unknown-linux-gnu.tar.xz=8803daf2ffadd1c76f7591dd765bccb8630336c00a9419f4e9e9a2fc882cd1c7 +dist/2024-05-26/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=9546048a0d5022d19770398f27e8c51cee4fd5879ec012709b8683a5ea9acd62 +dist/2024-05-26/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=5da5076d933127e616a289f6ba9bdea41f0f8f2604436c440a12f7007e5bee79 +dist/2024-05-26/rustc-beta-i686-unknown-linux-gnu.tar.gz=2f20e8666a768b32913a61e49f1774ad0fd616af874eab37b8fcff5344479806 +dist/2024-05-26/rustc-beta-i686-unknown-linux-gnu.tar.xz=1ac7c922764f406db986050f526f5b4490d789978cafad00db668cb4128d64da +dist/2024-05-26/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=d685e5d7efd8f312f22c0d1c132618f6112e528a51e451fa3279e71d66b46a4d +dist/2024-05-26/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=bb378be1b0bd6187cca16f5142f6d516790b8acc330f64af4371dd15751aff4f +dist/2024-05-26/rustc-beta-i686-pc-windows-gnu.tar.gz=5a628010b3fd859aae9b75086ad299fdee3159c6f7b8c5b93b24f56f392af0c6 +dist/2024-05-26/rustc-beta-i686-pc-windows-gnu.tar.xz=7546c4cbbc9c33dbed8895608116393855d73b99987e5e1fb2e6a8e88b0ed3cf +dist/2024-05-26/rustc-beta-x86_64-unknown-netbsd.tar.gz=5c10adf9a0d2b917d05e285b8754925d324a43335639d6caeae6bc815f70a852 +dist/2024-05-26/rustc-beta-x86_64-unknown-netbsd.tar.xz=49015adf19be4847dc5de824718a07f741b921a6c4f5565ae9d57b2ff24977c3 +dist/2024-05-26/rustc-beta-x86_64-apple-darwin.tar.gz=399a4751cf0f1015cd67b312f89a3b57f1a2e0b2b7052aa943dd87ff88e10e2c +dist/2024-05-26/rustc-beta-x86_64-apple-darwin.tar.xz=214178058be3e0d305838e1cc0c4de7d7a6aaeb3df1c8de451aa598bab46bc13 +dist/2024-05-26/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=fc8ba79857b1f1d8d27049e3322db0e9dd8e8f55e9899a7651826d29d18ccbd8 +dist/2024-05-26/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=d83f291dd371fec862e71e382db853d3547c1f8fc5cf475765e91054ffe4b40d +dist/2024-05-26/rust-std-beta-i686-pc-windows-msvc.tar.gz=4e831a551c6903d6995162c7e4ca35dcb421e50659a52e33b5d82a071ffc9c6d +dist/2024-05-26/rust-std-beta-i686-pc-windows-msvc.tar.xz=4944a6c8bd5716811eaa34d932899cb7a7b1ef16def784663867921357b98b89 +dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=25cf208ccd2bfd922d43f7d5e6000daf523fdea3c436795a641af43ca5af3c3e +dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=846bcd9b52a0c267bc0f5870dde2b672f002df8397d31ec4d55ef407ac9f7097 +dist/2024-05-26/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=2043dc32a5df5da4c289119d70896b88ec527ca72509eafbe39592bf18451c2d +dist/2024-05-26/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=20bffebf6414d6c5eb357280a301a7d7b6e2fe778423403aaa9106ce16ead498 +dist/2024-05-26/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=a67464ceea45dd3bfd20156091e1ac070ad1f921f70cb8c11c0a5945e857cc40 +dist/2024-05-26/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=b8518464ed51eb07fe9874dd38eb81004a58a994e95f1062ec5ab01db0d7cbd1 +dist/2024-05-26/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=398e2a8c2c1ff8e19f810513f1d4105c57b509290393d346ff56a78c58419c54 +dist/2024-05-26/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=3cb98ea534755f69a050df188c4b0b4282e5778609a8df6bd7dc9a467966344b +dist/2024-05-26/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=aaf44990f5ea7055c911d414e7ba74ec6457d347648b13eba087ef87030fef34 +dist/2024-05-26/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=32aa99692fe79711fa637b4f222fc5bcce3673845fee99692ef2cdc94acd033a +dist/2024-05-26/rust-std-beta-wasm32-wasip1.tar.gz=7711323738d70039ac2dcc39812610464b5d06f4a24db127143964424f07692c +dist/2024-05-26/rust-std-beta-wasm32-wasip1.tar.xz=413fc4b5480274ede6fc389d2563655cea0d438baee6b4f6c0d8757a4179d8e3 +dist/2024-05-26/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=b46cc9fab639276eb86be72746f3e484020014041cadff276da79f2c62b16376 +dist/2024-05-26/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=f4241afe5137e9a28fefd20115154dedfdd0db6d62e70e8b447a9999d238bf98 +dist/2024-05-26/rust-std-beta-x86_64-unknown-illumos.tar.gz=7b963148cf41ec6c918448d71929190474ac18b4770581e8ca41c9aa06d0d548 +dist/2024-05-26/rust-std-beta-x86_64-unknown-illumos.tar.xz=11d363e7e1325daa6161206f659b2da1cb64e1a6a49bedea2afd0993692e0110 +dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=2846fb587bc1e04ebcc15c4401eca652ec4a9a3ee07c4c8901ba8f0dec8bd307 +dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=c9aba9b367861d861b7c21969c64ed7c56db27b295b79498f817d28afe6258d6 +dist/2024-05-26/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=dccd96c4f24fd935c04f29b1ac10f936ee92b9c8ecc71ca494d60555a3541a80 +dist/2024-05-26/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=6b22b9c8526b4c5e25e7b6583df7c626388d3ff177e1f7b22c57ffec07bdcde2 +dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=d85b7dc13e34927030b76f0578dfa8da22025b914e8f024e611a05f55f2ff60c +dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=327beab489c253a802259760afc82ac337fe2addd2f26877610e1a2ca8a20c47 +dist/2024-05-26/rust-std-beta-thumbv7m-none-eabi.tar.gz=3b78f640fbc54016515b15fe5eba6c3d3f679582f33fbbd7656a9514bf04de25 +dist/2024-05-26/rust-std-beta-thumbv7m-none-eabi.tar.xz=f8fa181333351d8673b938b0395be2632110cdc6ad40f2b2bbc254643f5047df +dist/2024-05-26/rust-std-beta-wasm32-wasi.tar.gz=fa1f7cbf6784e9d1487a88f1942a223056315d45968d1f23ac262d81e6a3a1ca +dist/2024-05-26/rust-std-beta-wasm32-wasi.tar.xz=e13ce9734bebabf39839b27310c4a97c1553a34988bb2de69c9f4ad38592da48 +dist/2024-05-26/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=93c06f87883dd3b8abc504ee10c0d46ad702ec7266f13996a8e8dbbdcc6adfb8 +dist/2024-05-26/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=f785f3f53f47cd70cb3b1e04f46ae56f937814a895d132db470e21d9eb3f0eba +dist/2024-05-26/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=7bdb39efb763f3272550f229d97145515e73c9510b54c53246436c068fa4b98e +dist/2024-05-26/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=33960973887d3e4dc5f72550dd636c28bf6d5a9319c23c2ea1a14bb4c33eccf3 +dist/2024-05-26/rust-std-beta-x86_64-unknown-redox.tar.gz=16194e687a77d25e67d575f4e8a202d070771b6e51fb261d3a4673978b4c2a76 +dist/2024-05-26/rust-std-beta-x86_64-unknown-redox.tar.xz=0ce66624b0d2c1e476c730fc96718e8ff52780f8d5d6968e39a30cb9bd906b22 +dist/2024-05-26/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=01555fb03930106ae6be0c4bbc185a5f8cbec27375aedf4201529ed6856ac02d +dist/2024-05-26/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=3fa3ec9e478370a2874e7a47dcd84f714612b0eb05a8cbb6ff9379250e750278 +dist/2024-05-26/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=b84dc461e790fdcbf8084d2adb42398e51f162416522f2901f1d82d07915ee70 +dist/2024-05-26/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=8792ac895cd373b3fa8f4913e5a1b098d97ca1ca8f71beb15ca614111ea9bbbc +dist/2024-05-26/rust-std-beta-i686-unknown-linux-musl.tar.gz=5133f49db7ba73e900d8431838cbc12a5a276ff0f95fcd10a5791d5b4ef9b714 +dist/2024-05-26/rust-std-beta-i686-unknown-linux-musl.tar.xz=607131ca6ed1feab6289035445be404060281d3b1f720f40eb985b0341d2f2cd +dist/2024-05-26/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=aa8ba338e80abadf4383c34a686b1fa331e31a4cf0bb067576288f265a86aac3 +dist/2024-05-26/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=46fdbdffd351933cc1bebeaee3e2b26bee28c2356a9b337a4472346ee6cac9c9 +dist/2024-05-26/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=dbbd9d0f3b4ecd1cac5d9c6ee62e5e099fd5f05dd8703c9035d5280b38e3a601 +dist/2024-05-26/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=60edbb54ab8f1b982057a79063e6cf0fe5e4041c6306251e54cfca7014de84c9 +dist/2024-05-26/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=7ab82e3ae01242203d9d72b7d3c01c3bd70ef4d9ddcc86feaf025ae120558dad +dist/2024-05-26/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=148500507545bc8addedd8fe2f1df836c9aba894afb06bcb6f8a1258d9590999 +dist/2024-05-26/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=5b9d7ca3c0b76a23ac412aae8421750b144c9e9fdacdb34a637a6f5f353d9bc9 +dist/2024-05-26/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=7c856cc68e7d0b972258cc8f37731e72b9dd7eb88fc143fdea5220f4f60f6db0 +dist/2024-05-26/rust-std-beta-x86_64-unknown-uefi.tar.gz=5ddf07fcfd6e2cf17104f26fdfbaed3fa9055708b0ca63b1b0e675df8690b04f +dist/2024-05-26/rust-std-beta-x86_64-unknown-uefi.tar.xz=bbe32665b93efc6cf2fc5c28af448f85efa3810734a121033a92eac06b8414b1 +dist/2024-05-26/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=cde6a9cfb0aeced8be963fd7faa0456d506b6d693e84afd6a5423ac37a69d944 +dist/2024-05-26/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=026bdb53279ebb5f6a50f581b12ca2aa2c4de9655e786a3a17a606b2db4ff49d +dist/2024-05-26/rust-std-beta-i686-linux-android.tar.gz=8a21fb5147985941fc9eb8581e9970997240d8af19d6348e8b1b4296ecbea47c +dist/2024-05-26/rust-std-beta-i686-linux-android.tar.xz=ac5fd73f5a6ddc8c0644b32626c0bc53c885788e3e9fe331e2b598b86f0daebd +dist/2024-05-26/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=1f791a99dbed0179a1ea7b36fd13128c5c05d08489c8baa0ce660b6bbaf42a05 +dist/2024-05-26/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=92f8573bb786beb5cc74f3842a57d2725409ca7c2b12ed64f7ee543bb3ee477a +dist/2024-05-26/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=faf08553004fda1e2215116221cf35c7ea4a9f9c51b5bbe4bf16c99235d571de +dist/2024-05-26/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=81a5f8c273f7403091781bd7ad110fe7103392bef4350bba0e029385bc0ce0a7 +dist/2024-05-26/rust-std-beta-x86_64-apple-darwin.tar.gz=2a2bf00ca629cd0c7bdcc7333456f5766db2a805cba1c88a1a89cfe76a0f5d09 +dist/2024-05-26/rust-std-beta-x86_64-apple-darwin.tar.xz=b3ac3042484e972962a3e67b4f9251380135d6cf07b9589c5e3e94b0dbdb70fb +dist/2024-05-26/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=c1953526bed228077dd42be2e570d1276fcf04868e4c8d426d23e00037178617 +dist/2024-05-26/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=71310bef84016c25c949826121b8bf78eabac6d7c34b3397961ad39493df49c2 +dist/2024-05-26/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=d8fa9332e29f19b8b06dbafa2b6b13eb3479b9b28601372dabcee0cbb2a4d0ab +dist/2024-05-26/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=84daea4b14a3eb2712120652ebb2c342e6a37f984f1512dfa3cbd3531fb5cf53 +dist/2024-05-26/rust-std-beta-armebv7r-none-eabihf.tar.gz=348822ddf1f918cf56e6b76cdcfd3c4d4f50fb8e45c8b8c803e639910150b044 +dist/2024-05-26/rust-std-beta-armebv7r-none-eabihf.tar.xz=0f26d6888811e8ce6f0324bc5b4cbd667fbd8771e3e42192410d15e1d45033d5 +dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=42b49ef649da71c425b9de48812c23470638ac876f489f4c1c35ac116ba0d078 +dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=1111d46b2f5ef019cfb894b1a330721ee6fa1cf19b6f3c1abd8f866f8a208b3c +dist/2024-05-26/rust-std-beta-thumbv7em-none-eabi.tar.gz=4a41109968645be22ef1540037ac0a73789583eb250381d8431dfa6c8dd3a652 +dist/2024-05-26/rust-std-beta-thumbv7em-none-eabi.tar.xz=10007bd59e6cd60e924e472c19df1bda10bf6c60887ed91fb9874a7e596f9e72 +dist/2024-05-26/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=09d74fb8bd049910c60f585193af33fa51eab82dd2211030d71f3dcfba128a96 +dist/2024-05-26/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=2cdabc7be85304a7675fcebd53b8dd0e4183007fe0f81db3811df0d8bc712120 +dist/2024-05-26/rust-std-beta-x86_64-apple-ios.tar.gz=2061188c2361ce7b3a62a5bf45012aed708a8a86c2e5d1035a8c82b2ce868aa9 +dist/2024-05-26/rust-std-beta-x86_64-apple-ios.tar.xz=b6fd849acd590c2b853783b12b7b559395cc6698c6ab60d3b58a8475c809b9c6 +dist/2024-05-26/rust-std-beta-armv7r-none-eabihf.tar.gz=1915d8b728f8e37d7ede0da8cf2281676b970281c486d683f58d9bccfac2868e +dist/2024-05-26/rust-std-beta-armv7r-none-eabihf.tar.xz=21323f2a4eb7d46924438d0cc341b5d4e35b1ddb5abb02604980b5b055449e40 +dist/2024-05-26/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=2f6ff815e3f4ed2913a27bb30c51c3992e60fa4d7d00a6ea8c648f19c9fd56bd +dist/2024-05-26/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=ae6d85a4ee1a98084f3b95befb923ccb57eb42a05ef1fc9f4e5d6736a63edc09 +dist/2024-05-26/rust-std-beta-x86_64-linux-android.tar.gz=580b1f05fc5530fe0078e958b8740ac538ba1b2589e2c893a6b25f12fa4609f5 +dist/2024-05-26/rust-std-beta-x86_64-linux-android.tar.xz=8eccdb906d4f28404172d6e09dbe8a33a89cdf4dea168c446a3f38d719b63ec7 +dist/2024-05-26/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=91c10648eaa115ebb2436cf78031d86704a917c2641090c2fc30d3234f2ed316 +dist/2024-05-26/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=376e28b76c9b0fb590b7a7b3700debb4bd5878d861c144aa69502a0aaba2c9ba +dist/2024-05-26/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=9a02c999175b39b1ae4a99a5556f42c89ce02b9c6e25688cfe573833256f9a0b +dist/2024-05-26/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=5dbcb9a42313fcbec57d26877175320bde265a1c1c1f8a3415bb742b86810153 +dist/2024-05-26/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=df780a07a1322e981da7083938d755dbefe0a2fa00c6acbe5658469400b79d32 +dist/2024-05-26/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=611fe18a51c4d84b231d3cf9a2dc47913071698634b7b3c4c066b1e92ef5adee +dist/2024-05-26/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=0f30d5e28ed599888e8125b3614070ef3da7d9b52442fd11e15993a84b678432 +dist/2024-05-26/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=7118728e4dfb3283f4f6ffdf0cb92e4f1dbee7a8d9ee79c2cb4cad99e90507f5 +dist/2024-05-26/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=f1f1a976de6ad212370887bc8079a0ce6b491ca9bad3e4e8d2ba06e4eafae2d3 +dist/2024-05-26/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=034a5cebd66cf8f6d9379a26744e14d7d7e681b9203589a090a0fa205296d58d +dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=900ac2af2799139ea704e192f6709f364b736e31ce682e12ce2ba0471b01afa1 +dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=5883309a473fb227ed5c71b7f341fc6f5ff22657d089ba790fc80ac9afeb065b +dist/2024-05-26/rust-std-beta-i586-unknown-linux-musl.tar.gz=da1637ebab43f0a7b6e64ba42d8e2d06f04c7c8eda4e8f80a6fa520832288dde +dist/2024-05-26/rust-std-beta-i586-unknown-linux-musl.tar.xz=c80f46b0b5b4cd2e3ea67f4ab3df1ad4124fa6b425d598ca0b6656451a74ba44 +dist/2024-05-26/rust-std-beta-aarch64-unknown-uefi.tar.gz=f7d0413c0882917fd041704c692cf5cc5030660aa9f04ada91e5c3c3fe007c6c +dist/2024-05-26/rust-std-beta-aarch64-unknown-uefi.tar.xz=ad84c695a7eb2dccee3d3560e2140fe19c6aee116fc5fc953ac944d630d3fd64 +dist/2024-05-26/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=d42f482f7c262cc9cd6f9bb5bc64019cc348c0ec552ac5b518bd92548018411a +dist/2024-05-26/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=7589cab1072cecc50a9481e025e2f62f42975e60ba3e50fa6074e57e80c97257 +dist/2024-05-26/rust-std-beta-i686-unknown-uefi.tar.gz=85392042843c9653f1f6f643c0ba1af98ab0fd5a81cf1ddb7736415238cd5fa1 +dist/2024-05-26/rust-std-beta-i686-unknown-uefi.tar.xz=9cac1dafe8fc420c163fdb0ec089443dd4632077eaef73c459f3e8a9648fc6e5 +dist/2024-05-26/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=a2c33177e3a1d48542bd376eac44d4fc6320e58ed5b5ee1c5f58980301d7df49 +dist/2024-05-26/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=7183769937af0c9501b8fb71ce84a41562d9d773f4647d0d76d692fc0a623994 +dist/2024-05-26/rust-std-beta-armv7a-none-eabi.tar.gz=48e17ac14232f015425b46e1cfea19eea664cd224e0ec3e5b2ff58b82174b67a +dist/2024-05-26/rust-std-beta-armv7a-none-eabi.tar.xz=e04323b38171e9c63a4cd1673a5d69a9faf6e415d69ba11e7da7f30bd77077ac +dist/2024-05-26/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=2bc38de25271bd34c74a97b2f09133b4d3518911bd2d32deceab3e91f7554aed +dist/2024-05-26/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=2aad6d3b0b86847dfb1e57394de95dcbfe799630b388933d09939d1e309df911 +dist/2024-05-26/rust-std-beta-x86_64-unknown-none.tar.gz=9de88c179553ec42bdf5e036a44318a442778396380c44387cac94658ae7a294 +dist/2024-05-26/rust-std-beta-x86_64-unknown-none.tar.xz=f526dabd3d11858320129ccabfb3e5d14249ea6db30ac882ab26ae628d91f81e +dist/2024-05-26/rust-std-beta-armv7r-none-eabi.tar.gz=fa439d79673ad7a467dda9aa40524299880378d2a44a3338d038a6c6e6ec164c +dist/2024-05-26/rust-std-beta-armv7r-none-eabi.tar.xz=e07e26bcb5bd8dc93a877d122568aa78d09f77e81a3c85538872ddea47f3b319 +dist/2024-05-26/rust-std-beta-i586-pc-windows-msvc.tar.gz=f703880c171e14a6748beadb64477e85716e1cf45f98c5342600ee850518ba60 +dist/2024-05-26/rust-std-beta-i586-pc-windows-msvc.tar.xz=17dbd60169c3f47aa031d58dcd4898032d1e4991df86ff64e684e833c717d453 +dist/2024-05-26/rust-std-beta-armebv7r-none-eabi.tar.gz=5e53e25483594947af7a2aa5f14b06d44e0eaa16a464a004cfe7b079da9d7847 +dist/2024-05-26/rust-std-beta-armebv7r-none-eabi.tar.xz=81da84696b4250ad653b29aa73e8dd70fb0db6b469d8895a1f6c587ef38b47eb +dist/2024-05-26/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=d93918290043ba801c78f1d662ab847cd19002560fa6832176bb549cc51b0e8b +dist/2024-05-26/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=46b81807b463ef523a2e522199b4cdff70b817ab45bac56d17b7cf40c2bdb908 +dist/2024-05-26/rust-std-beta-i686-unknown-linux-gnu.tar.gz=adc0fa2c9a8cc8b4204fbd0455ccb2f914ae5335d8f8f96dc3df2791cf85e625 +dist/2024-05-26/rust-std-beta-i686-unknown-linux-gnu.tar.xz=8d5531693ba346d36f89fa969826434a1583c60dd1bf61b055aff026cadcb82d +dist/2024-05-26/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=01bd0ccbae4a301cd39eb92afda2f3a4d81276c17f8a3f48f9226a36fe4b6d31 +dist/2024-05-26/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=a07afdb285f1744ea75082d0a92f07333d5fd26ab84818a1bbb91ffab047998f +dist/2024-05-26/rust-std-beta-aarch64-apple-darwin.tar.gz=333fb310bf7749b0fb81a4f0930d0db738e24098fd3b4b38d037686c713f7243 +dist/2024-05-26/rust-std-beta-aarch64-apple-darwin.tar.xz=aa720a70e396e872045fe5934444b0e1b1e4633f371dc781397192c42a970c22 +dist/2024-05-26/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=4949dc875777c799d1fa74db866d6492b25bf15a9383867f8272c3751b1bfd99 +dist/2024-05-26/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=40eb3bffd0ca0db7dcd330e01f28ba777807f0e2e514f65e3c2aedf19b72d61c +dist/2024-05-26/rust-std-beta-loongarch64-unknown-none.tar.gz=0b719a0748343cea4f6e3fcd0dffc567de0e45eef6b8067259c5d8b61c7b8040 +dist/2024-05-26/rust-std-beta-loongarch64-unknown-none.tar.xz=e7cb82769b71b100a8453df764a231d1967e5ae41a39a0b974a31ecd6c348568 +dist/2024-05-26/rust-std-beta-aarch64-linux-android.tar.gz=9b85abd7488b16f323396e5158059104281319971933a0702055b1e508418395 +dist/2024-05-26/rust-std-beta-aarch64-linux-android.tar.xz=2164c9dd13043e16b5144670a3032adfe0e439b18a193ca22c4c6b6bab678577 +dist/2024-05-26/rust-std-beta-sparcv9-sun-solaris.tar.gz=ab9d4db4abb8057fa0e9d8cfe0d01921da5499d082402f6277e1f8ed75c32f23 +dist/2024-05-26/rust-std-beta-sparcv9-sun-solaris.tar.xz=43254c65450dde6de4ce2538b80100db01ca15632989a6ba7173b01f4acc89bc +dist/2024-05-26/rust-std-beta-x86_64-unknown-netbsd.tar.gz=07c76a68e44cb9d6ba527d17dafdc0b51c9e2b51ab1c5dbbe8784d137609a4b5 +dist/2024-05-26/rust-std-beta-x86_64-unknown-netbsd.tar.xz=caf5dc8356c9fd34f13983f338e0d44fbec83358309a60b1d7520aaaddc4ff57 +dist/2024-05-26/rust-std-beta-i686-pc-windows-gnu.tar.gz=ca3561531a6054f2236a820c77b5ce109118f720a0e1ef850cb5dc8abfd1c8ce +dist/2024-05-26/rust-std-beta-i686-pc-windows-gnu.tar.xz=955681b4b4f5b3bebee11c381b8c12a73ca7fedf4f4d80213be9035cfad722f1 +dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=035483e893dc4e28689c8ddba80b0e12d4b6ff8c8075c8fbb72612edfb830d1a +dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=e6d4f6d00972fdf6f9c9faf4e8608d7f6eca23094623ddd9c6a08237f0721825 +dist/2024-05-26/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=02f9bb16b62f6b1a02787ad30877fe5b1676524ec868789044b82cb762cd96d3 +dist/2024-05-26/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=c54719d0e78d063c1aabc9253a3cb0bb5bc9a9b88bdd02829f004c183ef225ae +dist/2024-05-26/rust-std-beta-arm-linux-androideabi.tar.gz=ab579d41fa31499c9ae0574194961d64065bbded4595c9809504826151d7ffb9 +dist/2024-05-26/rust-std-beta-arm-linux-androideabi.tar.xz=41f0ac3317212f46df64b0907487ced9b5c8e390f2d8a49f284ddf95a89c04b1 +dist/2024-05-26/rust-std-beta-i686-unknown-freebsd.tar.gz=cad37ef490a691de7b1649b94aea62af61a79d93e3f859fffaf5ccf63ca238f5 +dist/2024-05-26/rust-std-beta-i686-unknown-freebsd.tar.xz=f20be5c8c379fe9d2445eaf83fdb9b1df77117a93fa6ec0b97fbd0e5449f75bc +dist/2024-05-26/rust-std-beta-armv7-linux-androideabi.tar.gz=58eb5e6155e8f4e598f7201ad46633afda0fbc3221fdf07c57ab7c644eed4140 +dist/2024-05-26/rust-std-beta-armv7-linux-androideabi.tar.xz=c2ee165302f135710ea2158d9592731cfdbb1c2d7f529ac1557b190826aae24d +dist/2024-05-26/rust-std-beta-wasm32-unknown-emscripten.tar.gz=6268910518871d87012f8e77e31c3b525cb573f6697787b03c516e2a43846e45 +dist/2024-05-26/rust-std-beta-wasm32-unknown-emscripten.tar.xz=01cf5cd68bcd9a7f706ff1b266bc5bfb61b8b1230488b3352359ce1c604c5d36 +dist/2024-05-26/rust-std-beta-x86_64-unknown-freebsd.tar.gz=c3baafd66056b93943bde313b84b00f719fbb006045a7af869d1c0b77927ffc4 +dist/2024-05-26/rust-std-beta-x86_64-unknown-freebsd.tar.xz=7d846e6840553986ebe3f2a8dd526af5daeaad566f3b241e94c2d18dedabed85 +dist/2024-05-26/rust-std-beta-wasm32-wasip1-threads.tar.gz=b4de80001c585b3644116c7a4cc7ee6a00476058f84637c3ff49e8dfc5edcf1d +dist/2024-05-26/rust-std-beta-wasm32-wasip1-threads.tar.xz=8facfbeb32902b094512c89dac44b94f437163a8b630adc485383045ec4bfd0d +dist/2024-05-26/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=0b8a82fa80653cbd2c27237b7b696f4ddd37e0a2575fca29655fd36883193659 +dist/2024-05-26/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=ea9b3e6984605bd2606aa0456e5a9ecc4addd2880104cf5ddbb7fdb81673818f +dist/2024-05-26/rust-std-beta-x86_64-pc-solaris.tar.gz=b4234ad1e817f65a7a2ecdfabfb1437ce98fd580c0bff61037ec917fd6e3c88b +dist/2024-05-26/rust-std-beta-x86_64-pc-solaris.tar.xz=b7ee8e567aa1341d76be78eccd2c5857f4757b295b32a14d4054766c41cd126c +dist/2024-05-26/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=145a8427c01b038b9bc79aed2e0ff46af87789555bd486885b3592c4bb62fe9b +dist/2024-05-26/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=d84f020657dd466ba4f45d50fe1a8c316d03291c8845c443e2c68c4b40e590c4 +dist/2024-05-26/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=96b2278c15a6f83cb37ad6af34d9c5f364198a19cedac937d5cbaafbaca63fa7 +dist/2024-05-26/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=edbe125808cfcc69189c59f7b7614e056d34b23d121f9f165a93498eb775f92f +dist/2024-05-26/rust-std-beta-thumbv7em-none-eabihf.tar.gz=dbbc72ede43591cfddb55ceb4aeb38d641a7ea7d7c0f5f4415a3c2e3a07e916a +dist/2024-05-26/rust-std-beta-thumbv7em-none-eabihf.tar.xz=6b80df5802d08d6653fea474366bf1d4c892a87738a7a9f7156ae7ef916b5de6 +dist/2024-05-26/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=2e9c56810053a067bf91df0bf3d2c5c08c823e25fbe7267a6633ad33876ab0bb +dist/2024-05-26/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=494963c721fb8d1e0d44ab9ad4212aa086af2363289d7b0d8b08c1e82f71efc7 +dist/2024-05-26/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=9901fb8f28e2334b31cb594afb1a91f22fa019b13808b650d940bd2d89a1315d +dist/2024-05-26/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=583b0336f3f501eda441cdb5fbae87c4457a0bdcf896cca808111a181549b786 +dist/2024-05-26/rust-std-beta-i586-unknown-linux-gnu.tar.gz=e4fd222c2ed08e0fc1da161a23183ee222fa8755e70f4a352ae854b2cb798663 +dist/2024-05-26/rust-std-beta-i586-unknown-linux-gnu.tar.xz=81bf3475805e8af9a6297868ce9c1893c22d901fc7d16f0482c28a4655608de6 +dist/2024-05-26/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=c1d015599bc48664b01507da30bf152d730eaf0bd61cd907caa353b223d7adb9 +dist/2024-05-26/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=fdea1b1280e2fa5b14ef8998408557ecad0954b2502fe073e65e3ec3cacd1d22 +dist/2024-05-26/rust-std-beta-aarch64-apple-ios.tar.gz=be8fc41bb262be74ad73d375db76cc8ba277e8313a911aaabf17b02c52909b2f +dist/2024-05-26/rust-std-beta-aarch64-apple-ios.tar.xz=7ae7187a9e85b58b740cf778df6d4442e388236501d6eeee76bcef0f9f378533 +dist/2024-05-26/rust-std-beta-wasm32-unknown-unknown.tar.gz=f5d863504c8b6b3fd42123dc09ad5e2cef978d8887a8ed62a125c125a7022b32 +dist/2024-05-26/rust-std-beta-wasm32-unknown-unknown.tar.xz=a36d65ab13f0da73e38f5e034d041dbdb1dc6577508734af332b2cbda5122ad6 +dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=f9c9684b948b09d658689ca70b84515b3533c41edab0e25bcd8aef5e40c621f5 +dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=e595f26a2b49d2f5b36e5a7333ac6bd0b54fd1c05122d160e5c1a4708ed6d488 +dist/2024-05-26/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=2c140b89014321f7827ce3e0b2d6cfdc84e871f05b3a0908716174719689498a +dist/2024-05-26/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=bfed676e39a67671f3256edb6b9e20e8ed4421d4b777627c1484afd8c0d68d85 +dist/2024-05-26/rust-std-beta-aarch64-apple-ios-sim.tar.gz=8297677d667a637cb298e9e7453ba68190a9ad314a52015bc4124817e6586ece +dist/2024-05-26/rust-std-beta-aarch64-apple-ios-sim.tar.xz=f2763a0f3a59b6c87ad1dc390cd7715587cf2b41fb58f58849243c69524905ac +dist/2024-05-26/rust-std-beta-thumbv6m-none-eabi.tar.gz=447a1c4e502b0deef96183af40f32ef3f0d011f833621d7b0a6d972c8859e986 +dist/2024-05-26/rust-std-beta-thumbv6m-none-eabi.tar.xz=5d21d53fdcbdcae5dedf1e8cf2742d05b95198c984cf42322b72e98636214364 +dist/2024-05-26/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=f1ea6387ea140cce37c4708bbd5135d74f2861309b907b58458f2a4bb34dff13 +dist/2024-05-26/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=464f09ab8fe2fb8cda1d194d1178e025f092c13984680fcfc55f60f0f3b7f757 +dist/2024-05-26/rust-std-beta-aarch64-unknown-none.tar.gz=17b2d567838919513d8b998819f0367cee1b030882bff2be1116fcc4d3b95b1e +dist/2024-05-26/rust-std-beta-aarch64-unknown-none.tar.xz=a0571520b61b28a64055b6420ce5cbd49ebb8aaaefc73ab40df73b0ebeb142e8 +dist/2024-05-26/cargo-beta-aarch64-unknown-linux-musl.tar.gz=61a51a1409249cb99d168d88805d678f042b0cebae06f0f2be3ec3ffe507e59a +dist/2024-05-26/cargo-beta-aarch64-unknown-linux-musl.tar.xz=ea1e0fa7859596502b1b270e58599ca0d71c17060dc504a8cc801dc63a60de30 +dist/2024-05-26/cargo-beta-x86_64-pc-windows-gnu.tar.gz=ed791a607b85ed30666cf25de886892bcdab38bb2194bb5969637c4bf5700dcf +dist/2024-05-26/cargo-beta-x86_64-pc-windows-gnu.tar.xz=3cd4887501f35f9d608c25e5306b3e20473820d194e014902f1ba7e2baf365d7 +dist/2024-05-26/cargo-beta-i686-pc-windows-msvc.tar.gz=c531faa0b9af65f9987897dab8ef32d32c53d14437a76541fb7e477d73a778ca +dist/2024-05-26/cargo-beta-i686-pc-windows-msvc.tar.xz=f624fd704ee17023fe568a5f7165fd310170610b62fcfe0be374fbd53ba5e5fa +dist/2024-05-26/cargo-beta-s390x-unknown-linux-gnu.tar.gz=e4de592c9e6e58556ee56ca395838259cd239cd88be27fe27141181981ebac4f +dist/2024-05-26/cargo-beta-s390x-unknown-linux-gnu.tar.xz=b34dedc4c0312d40c7923f7fda9491ec6969002d641cff31889b96ba9becec08 +dist/2024-05-26/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=3c60bd3a7623e4a6f8691256ebdbd5b7441a13cc291803cd7e1e3a9af600def6 +dist/2024-05-26/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=07c4043b8da23bc161e8df2924c96f21c3d613e07b6d78c57c57908eeff50feb +dist/2024-05-26/cargo-beta-x86_64-unknown-freebsd.tar.gz=9e8e5e7e2725c680eef7ac4c9b962f04f31d2f59a33a4ff2025aa035f0ef9f80 +dist/2024-05-26/cargo-beta-x86_64-unknown-freebsd.tar.xz=c5e194b6bd6494101ac163902943437b3b0b1e78cfe50900fa80eda96bf37a4a +dist/2024-05-26/cargo-beta-i686-unknown-linux-gnu.tar.gz=20931f1b365f6f39fa473393ffade8bca346d00483673253a75f5718728e934f +dist/2024-05-26/cargo-beta-i686-unknown-linux-gnu.tar.xz=7ce7c900c333f79170d28fcc85603822c39b14b687db22618ae11bfd3d6d274e +dist/2024-05-26/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=152b2d0c9d1b79ef75cf5d86b880aff2e675e74d1f3456d156f782692df9062a +dist/2024-05-26/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=29852ddbc3e91ef2524a267f4037a901a5dcef4182138dc85f946b13f2defe2d +dist/2024-05-26/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=084be6c65205744138bb4b32c8c64acfcd62eec48de06dce24904d7dc92d5d08 +dist/2024-05-26/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=40139b0b78e8bf8b6ced7bd45675be174b51e99b0e09d5029aa2810f4ecd1850 +dist/2024-05-26/cargo-beta-x86_64-unknown-illumos.tar.gz=92448a4b52d02cc7e33c4304542f3514c1dfdd48a10a15c085caf24eae1ac955 +dist/2024-05-26/cargo-beta-x86_64-unknown-illumos.tar.xz=54757ba4bfc4ee87161dab91d3406570eae3f95f9022742b7096359e532a46bf +dist/2024-05-26/cargo-beta-aarch64-pc-windows-msvc.tar.gz=c8d3cd13d4a2f3932b3804bfd18a11f847b5c2bb5ae32f4eb04c75f882c23471 +dist/2024-05-26/cargo-beta-aarch64-pc-windows-msvc.tar.xz=ff5b389e3645d58fd7cad66881554537d36319d84add1d897382b6ca3ca406f2 +dist/2024-05-26/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=31ea12902d3179266af423f4534881a9b2ea0131c0ee292a46e4db35efed6063 +dist/2024-05-26/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=1b467f77feaadd5d37d6faeca1f4001e7d5d1b29c4d40465c78f4d556ae23b1a +dist/2024-05-26/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=a32d5142d32f64f3adc18d9949c63e4582caac446daf8809626f3edc04dcc2ee +dist/2024-05-26/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=facf0eb79d61967126c5c49698aea3603790c13f467e40475ba4ba80d2937ee8 +dist/2024-05-26/cargo-beta-x86_64-pc-windows-msvc.tar.gz=bbc183a2ffa90e9771c1db7ae1bb260d6c5ecc86933e9d60026d5ff4975c76ac +dist/2024-05-26/cargo-beta-x86_64-pc-windows-msvc.tar.xz=154e72625aa847777464b1aa8d885f8de0f16138362ec3725f96b434d6ec3a1d +dist/2024-05-26/cargo-beta-x86_64-unknown-linux-musl.tar.gz=b45ea7d288797a7da04b71b665dca721899df248887e35b1d6903077a7f3a363 +dist/2024-05-26/cargo-beta-x86_64-unknown-linux-musl.tar.xz=cf654640589ad3326d5072be882270c8e16694400668a2b1be1feea6cd623636 +dist/2024-05-26/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=0c57f4972f64d8a418d4821492d2f069b7dd8f7b1e9626bdf59c4763ee85e06c +dist/2024-05-26/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=2ddb32aec0863593472f47c90fe9e8f008fdf69f3e33679d808383e56e5acaae +dist/2024-05-26/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=f304394966cea648c66faadc1f04d46a39e7532b913ae6f170b67eca1c03cfbf +dist/2024-05-26/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=0625fe16550bd1a1aac9699560e168836d6a31f24c2bd5f49007029684991c05 +dist/2024-05-26/cargo-beta-aarch64-apple-darwin.tar.gz=8159a07acc11cd1c1b7d0c0dcf8be269325033922c21a85ec38a9a1b11166cbf +dist/2024-05-26/cargo-beta-aarch64-apple-darwin.tar.xz=e4e935be5e89a405c06dcc77a76929a7c5fda2e576bde183a6854254720e053e +dist/2024-05-26/cargo-beta-i686-pc-windows-gnu.tar.gz=6a5c34fd6a762df06c7b25d3a25f93f8dcd9071789528365350b20ac4a0cf08b +dist/2024-05-26/cargo-beta-i686-pc-windows-gnu.tar.xz=3b0784e1ada13f88c1b3d130135406ab1b12ace88e2f296b292071ec35d15b50 +dist/2024-05-26/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=8dee7954f81238d7be66538f70cce670b724e919fcd7f2eeeef8ee492a808a8d +dist/2024-05-26/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=dd2445c26ea2c151b93bff68c164ed69a313f87fbf1f90e8024317b4a66a6185 +dist/2024-05-26/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=bdcc649bb6f425ab32caa2cc385fa3b99cbe86cc3ea7a5780788c35c029fb099 +dist/2024-05-26/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=8fb0a771f69f3d6849129a1ebf5026e256010775e8bb9befd52325243b8f188e +dist/2024-05-26/cargo-beta-x86_64-apple-darwin.tar.gz=2f4cefcb58f0ff51eef25680c926313e9b5e4a2c3beb710e7bb8eadde50c9313 +dist/2024-05-26/cargo-beta-x86_64-apple-darwin.tar.xz=5d53afb9ca5fe65a56e1d64e4746b13f9c586f81603553c0556eb02ad95df4c2 +dist/2024-05-26/cargo-beta-x86_64-unknown-netbsd.tar.gz=35c5b04d84d85c43f0c5a3bdc2aa8b8fb848961e3c4daf276704f85e47ae3fb2 +dist/2024-05-26/cargo-beta-x86_64-unknown-netbsd.tar.xz=3b0296264bd63a2d40c9d5e3a663756a5bdf442635ee8b6f54438a2767a2d04d +dist/2024-05-26/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=a8c3a909f50a5de7f78672942d87aed939ee60ed6d5e50f308460a942a632545 +dist/2024-05-26/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=2ca4cb39879eba33da970197d45de82df898cf5a5bd4f4614b083fe999fac575 +dist/2024-05-26/clippy-beta-aarch64-apple-darwin.tar.gz=04c563beabcaefe80eda700ab26e975b30b5264c6202e04c9577f6c2b41bd6a9 +dist/2024-05-26/clippy-beta-aarch64-apple-darwin.tar.xz=19846f743872fd899ad66ce4820eef3f7ac056834856fe1d86c963f2e8acf2e5 +dist/2024-05-26/clippy-beta-s390x-unknown-linux-gnu.tar.gz=911554e8139df5c5b61fc85aaee2119cf36f3ec0f0e8741a7c8d92b1205bcff6 +dist/2024-05-26/clippy-beta-s390x-unknown-linux-gnu.tar.xz=1b108110da176b81daaadbc8c0a65950761fca243eb6cbf5ae0991d2bc3c89ec +dist/2024-05-26/clippy-beta-x86_64-unknown-illumos.tar.gz=264150fbe3d369f18b61f2d607b694519c2b4b50f93c8c03f7109064bea79ad7 +dist/2024-05-26/clippy-beta-x86_64-unknown-illumos.tar.xz=89a044938cf7734caaf39c98c6e2a036e544bc474a0af3a3d92e47f39534e6cc +dist/2024-05-26/clippy-beta-x86_64-unknown-linux-musl.tar.gz=f3a99c3a05280706cc042d67cec7162088cd2f62f2174bce8f074eda3d43cb8c +dist/2024-05-26/clippy-beta-x86_64-unknown-linux-musl.tar.xz=0da48481695a90c1857bc0f8ff39223b3791b8b7102143e44bcca7bcea6fcb42 +dist/2024-05-26/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=5ba8b0e2162c574dc73121a69e43fd6629df9c656d96d95e9d269c3bc6e62add +dist/2024-05-26/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=778eaf706993f617d40c22084f06d4ec8fa7455a22bcb699bd7b376d1194bd58 +dist/2024-05-26/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=cdf9711390230edab20cf0552d55ebbef87263b3353fd51bf232c12d1dd131d4 +dist/2024-05-26/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=5aa9b052cd0c7452ad08a1523c6fcad7df0a69f62a0a222b6a57d003d1881a6a +dist/2024-05-26/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=3d7276560656e51826e3033dcc45fd2c78c2d872951c7e3434fd5f693a37fb45 +dist/2024-05-26/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=9aa885565bf7691ed028b8838a4108313cb2e7eda4b2f96381e8d80655ff4ce8 +dist/2024-05-26/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=29bcb622529f9e13b6aff7597e4c9d474f8127259f9efa96fa928eb3ba49b157 +dist/2024-05-26/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=14c7a9664a635479391eb33b90d8af80188cd38069799bb5b851b935e1848473 +dist/2024-05-26/clippy-beta-x86_64-pc-windows-msvc.tar.gz=3491ca3ce04812559abe45455e468625791aa6fc648ddc229d429159ce2b639f +dist/2024-05-26/clippy-beta-x86_64-pc-windows-msvc.tar.xz=85eca1d8659dd6c171295b0aea160eff1410bc60e15889952998460b30df03ab +dist/2024-05-26/clippy-beta-aarch64-unknown-linux-musl.tar.gz=aed3c4e45f47fd0bd6ca299f5883132e6d8b3c3f06d6bede71bb664bb0b04c10 +dist/2024-05-26/clippy-beta-aarch64-unknown-linux-musl.tar.xz=b8c475ac163435bad15fada68c29733d96f23f87cd92f5aa13ca99df21b93323 +dist/2024-05-26/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=3b42f9ffedd1b4074e7831fbf0809987866021b095eaa5f2d9481ca2765a7f85 +dist/2024-05-26/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=d71a3e5ae13c46f68f95f8fca7a3c6f8795faebf7602f8d1206e355c6d9bec08 +dist/2024-05-26/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=ce12948ba13e8f0556255a65657e9b92b996c2f96966cfefb895a6ffb8b08d47 +dist/2024-05-26/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=d1d23de591053c469fccc8ae6edeae3a2a8502ea5feb95272ab90f6651c52dc1 +dist/2024-05-26/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=31ae7b2c3af5ca9b47a9eb6ff53d1717df49e3a834584659a7108a72739799bc +dist/2024-05-26/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=576332e47d5cd862581be587f03aa3a3e6abfc982fda6d26c7dcef0e2742b537 +dist/2024-05-26/clippy-beta-aarch64-pc-windows-msvc.tar.gz=8bd2c213b1dd6eea58a7896203962e9928ba9a39b0cbed5c5737b2d35c707a44 +dist/2024-05-26/clippy-beta-aarch64-pc-windows-msvc.tar.xz=dd530cb08114f28323c740e453f25b553376f0f4df977ebc79a87d09ac8e2b25 +dist/2024-05-26/clippy-beta-i686-unknown-linux-gnu.tar.gz=d8aa70bb4711bb985592632f88b2499b1fceedc294adcdb6e37f234dff0081f9 +dist/2024-05-26/clippy-beta-i686-unknown-linux-gnu.tar.xz=26349efee4513b0c37b9a963f3f6fcdeabc6857554bf3f28efa7c76c5c5b54b3 +dist/2024-05-26/clippy-beta-x86_64-apple-darwin.tar.gz=e6283756c66ff219a879799b6237df25755ac6a590e2015750bc3ac79eee322b +dist/2024-05-26/clippy-beta-x86_64-apple-darwin.tar.xz=474a5bacc986404ebdca454c28254e6af3a7865db1daf26da56497e6dd8db248 +dist/2024-05-26/clippy-beta-x86_64-pc-windows-gnu.tar.gz=2fab393b9f0fae2c087067dc42758f914d74eff81c6e87da134520b1e4bcfb97 +dist/2024-05-26/clippy-beta-x86_64-pc-windows-gnu.tar.xz=23f46cea5a99191908e79f6f145b6577ce328aa4a435c8fb84a3c5afba8b9476 +dist/2024-05-26/clippy-beta-i686-pc-windows-gnu.tar.gz=5d0b5a07967828f9d2180ecda420433962532721fcd6b5b1dcf7fd273c8ee1bb +dist/2024-05-26/clippy-beta-i686-pc-windows-gnu.tar.xz=34e36c25a1f385161d352f4d0fd03c332b9ad70c8bd96cd7928010f367d9ed07 +dist/2024-05-26/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=6bb0b231319507013f6556b88c7b32e640e182249935935796b33063f77d8c5f +dist/2024-05-26/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=e029f9e9176d0562d6729ad87ba9dbaf474c003854f140da0a57ca52b2794a68 +dist/2024-05-26/clippy-beta-x86_64-unknown-netbsd.tar.gz=5aff0b8818b2639d2bb792288464b042aa2987e63e4b8d885ceed14fbd2425a6 +dist/2024-05-26/clippy-beta-x86_64-unknown-netbsd.tar.xz=6edd1afcf6bf4d9118a1dfbd8fc7f862026d179277b465da51b6b455957bc30b +dist/2024-05-26/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=8969bae5fee4a30591b55d57b06d03d7d2be08ee20d2e5d04f055f916a8e248a +dist/2024-05-26/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=7dfddd258c8cfa4f6b26f739fe52bb0519543472476595d901486b53ab22ebe5 +dist/2024-05-26/clippy-beta-x86_64-unknown-freebsd.tar.gz=2462c2fdc6215312ec7a12e98f74f9cfb06c0bed30812441268bb91feb2e4a8a +dist/2024-05-26/clippy-beta-x86_64-unknown-freebsd.tar.xz=154d43b7db31cf9c25f6379c6bc0bb828fcaba99d9313e8267f705bdf810655d +dist/2024-05-26/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=ed50a1f702e574c754a0c6eabfe120b5b3286bfe004dcc58b6a857684ae44033 +dist/2024-05-26/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=c7431985caefaa2d995483b0af592f828157d517828e6792c8abec0a52e2e600 +dist/2024-05-26/clippy-beta-i686-pc-windows-msvc.tar.gz=870b60708cb7fb9bd76d6c1ec2572502bbb7a86152d7e2ffb0e3d023674193a7 +dist/2024-05-26/clippy-beta-i686-pc-windows-msvc.tar.xz=292183dc34bbc648564ef99230efdb8749d3d2e34a190b62b318ef1b8f4546fc +dist/2024-05-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=c28d6ba3d8319ca2a3c810ef13637dc67df6ab5c6d3e67e085009b296a4e87d3 +dist/2024-05-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=ba1e59c352e3e10696f3b1e5516af1d7b9fc480f4b9b45f313234a9151f4db57 +dist/2024-05-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=2efadde71b4bfbd6713b381f4e2df77a51be47818c4d7a0a9000d4f31502d50a +dist/2024-05-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=82347bd970ad3a6e6d9565d9e6bfa994e23f849591ae6fda109f876928033952 +dist/2024-05-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=c3deeda6061109a09b123df68fd83a9c11c30419b91fc73be7653e4650b1b544 +dist/2024-05-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=a93bab60e6133734771ccbc807b44263c368bdb66b05491359897a23803d31be +dist/2024-05-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=e71d212b7e25d7bbd0bdc4d04de8fa9c896239f1063f5e33067baf5278134cc5 +dist/2024-05-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=467191e0463a1f465304ffa37724da8199a112691147ae0c49fc311007fce410 +dist/2024-05-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=e2be1ffefa6c19b2682d8ac219ad88956485c99d41bcdd76fe78c80ce214f331 +dist/2024-05-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=7c801202c1c575c2522782f4346b4fc08abfc7f952a0cf3ad36a184e8e3c59ce +dist/2024-05-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=cbc04f5efa7849c51944612974aeadef63479202f2c0426d9301f38a54f3e023 +dist/2024-05-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=e0deed883ba554d9b863bad8f9903b5952813439469282673fcd322ab7692751 +dist/2024-05-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=d3c4d54c15e8dbc45e2182354510cb705068fd32e604d289c0c612a6942ae82c +dist/2024-05-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=a112b66030fc6d861ac988fbdb9496040a702d84409e41936c192af21d0ac7e2 +dist/2024-05-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=633f765dfa420b35aead7f8e0be99d28c90dd8d76dc452321e0b1102563f9f5e +dist/2024-05-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=5db0f26d1705666dd1b6aa9c00bd24679698c7afc5b9a5df7d5588dd8be4dbd8 +dist/2024-05-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz=a919f09c70fb61986dc0b4a52a75641edf18d7a4a9396fb0aae1009510bfdef1 +dist/2024-05-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz=1d5781a9e6c705dd0a14ae75d4a49e5b0bf149d5d157ee19afc4fcbf6c31de29 +dist/2024-05-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=866667cc443b61ada4e25b816ee3d8e9de0d3114a9f5ce26fa36f311731f5726 +dist/2024-05-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=66cfae5d45a256b8d838a93e49a1cab0263418158ea238e07ba673dc7b3df6f1 +dist/2024-05-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=57b29a2e3bd7d5aad05d6ac6ec8acd3f0b747ce679ea0fb53a203c5383895765 +dist/2024-05-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=b8a5f95ab75b9a645934adb9a76513e0ff85f98de7b82aba494bd74289597d43 +dist/2024-05-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=d1ec7e5e6c8b13ef47359b1e64b972be0c4f740d18d341190db347cd89a868e7 +dist/2024-05-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=84f60a1fb717916a03c8f054610f543efd687bbfeee3b58bf8e99fa976bc7faf +dist/2024-05-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz=3016ced168060e3e2ba6147d3f4d13b18c76338ca80a827557b7882f168bb5ef +dist/2024-05-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz=cd45818ace482132afef6b6d59d892d002a476fbad00f28182b865b56687d239 +dist/2024-05-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=d49c9b195f063d2268074ecf9366380a968700a007f71593b1fcd8e5324b3a28 +dist/2024-05-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=66209a3abe1d64c7b00d55f526045d553e782ae994520da3a0ebdcef72142eda +dist/2024-05-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=40f9c57aaa01f165604e47a967c2ce2af83a8c1d79f7cfa5cb737dc1513c12a0 +dist/2024-05-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=b5e067643239ef064de01776806de26a3d728aa9a3e2b88fb619400a6a2cf4ad +dist/2024-05-29/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=2a860e5b10568f388252eb531913aad8aa0389d37cd2af49480802773a596be2 +dist/2024-05-29/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=6587860267c67a64977275f5d16b856d934f2a683ee1a6155dbf4bc9e52dc841 +dist/2024-05-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=979abfded9f0758334c867f2f493ac4741f9321c8321d9f5425adba51e19e5cf +dist/2024-05-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=392924fe23bbe9df2723e67af3cd5aba27b176c04878c62904e97fbed9bc946d +dist/2024-05-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=9e809bab970bad03e9fc2bbae8302498053115a8db46a8bd617014d751d153be +dist/2024-05-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=8abee908fa9bfcf6e48b3e62581875ae65cc2b79b31c8df0976aa680c58e0ca8 +dist/2024-05-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=48a98383da0741207106ccf93414739d7dcc37b83bfbd79b3789acd1481ca7e0 +dist/2024-05-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=9706e65357de932a3325ed03153f455cc9af1d551a41327049c72a7a7cfd811b +dist/2024-05-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=eb328f79f4fa5afa2ecef6869555b5303761ef0b8fe5d69ef6eb03a01c93af9d +dist/2024-05-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=d5e7f54a4b972f8f6192a85e0185307406cfbcc50465a21c22d2fe64bbccc03c +dist/2024-05-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=b3964c1199d4cf6ed8926a5442ad95eb6c5bca8639576b5a423df0afaddf2353 +dist/2024-05-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=3b3711a87366e42348321efcb87b232f0cb9c68f8fef9f651893d599bbd03bf6 +dist/2024-05-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=2900e5fff29a5bff6bdbcd4205dd8bf5992df44534f04c1279a7cd47d050a15b +dist/2024-05-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=e5269da876cfbb5d0eb0ac24b34cf38e950a6904188fb4a7171f0504cbce654c +dist/2024-05-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=4ccb7a272765c9c59776922f0e034f2ffdc236e959d4500df9d928078016ec9c +dist/2024-05-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=5da7e0f39a0bb8c527f1db46c24713265ea7a3c9fb1bfaf84be6c6268ce68893 +dist/2024-05-29/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=de475ba7e107a5c144a417bb6b482b779ff954e0210c181a71a960c091a71532 +dist/2024-05-29/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=431c7d2d5a0c7bdb27dc15079c92cf71ce496978f1f2922e444da49e1b12affc +dist/2024-05-29/rustc-nightly-i686-pc-windows-gnu.tar.gz=5e08f7be71e0ba29abcc3486a727df8444b818d6e4deac4728108c25382a4cc1 +dist/2024-05-29/rustc-nightly-i686-pc-windows-gnu.tar.xz=df5b548d795cf89bc6bd6bc5608cca377e46e5829485a4f3b7d43e294e2b48d4 +dist/2024-05-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz=2f2f62d57833250c2b36509e820d7d4860bfdd297f46af5eacecb6c0f27430b9 +dist/2024-05-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz=d819323b185b9cb9b5fb2f1521d9f71408c026ffe345cd6b76f7ffca0917b054 +dist/2024-05-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=af87663dc3677d7a697192cd9f7e2e73f6825cd86109a3a1af424e39c2e20f5f +dist/2024-05-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=fdd0b838ff62feebfec9a7b8d516cab45568141a751641654b6ebd63165cd023 +dist/2024-05-29/rustc-nightly-aarch64-apple-darwin.tar.gz=9c328c9692688ee51fff66e43d92155752fdd67128c0f2fa3e5a642f43d7dd08 +dist/2024-05-29/rustc-nightly-aarch64-apple-darwin.tar.xz=d4f17356232fd136d2844d5888cc1425c0b942aa5ccaaf877fb8a8b357b6d4f1 +dist/2024-05-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=fe6533f08d7ce2e06e9fb337cdc32d865e8e00b8f91908737bc6354d3206eaf2 +dist/2024-05-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=dcec47a722fde1ec2eb61523a3a0efb06deed29f33e64ed1b11a01abccd20c2b +dist/2024-05-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz=82f159b866d58fc7183ff923d714183f319459d9e47719551d17c8c2345ca138 +dist/2024-05-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz=6bf7bcd9ba441e35bb2cc6ca2b91c8fa9dbaf72e11d57bb3371b0303701aa66c +dist/2024-05-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=e205ebc20e54660c7698f589f367dbed50bdbe46380b4505f96e8a90f9620c52 +dist/2024-05-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=8c2f2f53a77d638f36014b294dfc30d30b44899af92837d54237e7035e365d44 +dist/2024-05-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=dafb95b4125eb098fac7cbbf775f82247705f4ae39081966f1cc6530e47ab9eb +dist/2024-05-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=e450864ba5db1035016100e83e36574a50bd1037f5613abe9fb2171506458069 +dist/2024-05-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=79d563c9dbf525955da2f0e666b8e1d8aaed2beccf8ed400ce0ee0916892bbb1 +dist/2024-05-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=886cabea80578d4bddad4fd9eaeada7b7295c1a26f9d65a7466b078ce8f455e2 +dist/2024-05-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=96c7e311c97e0739bdb27d114e2c70b4f0300695dea7b17867b17f87609d75f4 +dist/2024-05-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=e59464ace28065d7b3ebc21bcde836c5cf6d7e442cb69dfb9751cf08f597958f +dist/2024-05-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=43016ec0b5b33c7f16cf4f4c486b0d4e3554cc7fef139a78558c177856f047ea +dist/2024-05-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=e74571f5b4dfb498aef90454b12ea33e927a86cc31fbfb83ab33b3e0439afa09 +dist/2024-05-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=7a7479cd717019f2e18cb022d96deb5d27c554cf411920d04229f940fbc7226c +dist/2024-05-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=bbd708d94f94da90010eb574aac0fed82490989a3f4b3b66e51d65526e0b3629 +dist/2024-05-29/rustc-nightly-x86_64-unknown-illumos.tar.gz=f60e5f253ce5f17631620a5ed99873e6067d65a547dfbb0ea751e7b151cdf971 +dist/2024-05-29/rustc-nightly-x86_64-unknown-illumos.tar.xz=71448313016bd45a7bbf083207a5f334c1a921b8a68bc9618cb4644c7e134716 +dist/2024-05-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=69c481a820c25d7b59d3d63081e93f9784c00cc4efd301fb5b9680b3166e2d9b +dist/2024-05-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=3a33c45bce9fcc91730bfed44db0c1781f9a6c8c0a4382af775f4c9b638ee5a7 +dist/2024-05-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=d8d12e8b1f70353fd9b84ebea1ccb3a0f4bb561e99283c77ccb970ad6838cd19 +dist/2024-05-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=2890c1e4eb5eb0cfb57cf947088c43efd11e5e071bdb6191609639d541244394 +dist/2024-05-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=0ba52772ae17e47cabd816980f0cb22bd25254ccc213da6a968bd8e635607c4c +dist/2024-05-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=4da826ffedd6468d336d97722b20f8ba49cbe7d77c7667addab19c39f731dd69 +dist/2024-05-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz=463bd6103900d486e874195bd65646265449333dd5dd5f007cc57120289a5553 +dist/2024-05-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz=0f4b1b482056ca489e9e74c634b733d1903ac0e6196506e635cc7edd6dc8f4d0 +dist/2024-05-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=42b41b32eceec839cedf88ffea93c99b04ee4bc9ce095e0872bfe3a67a6f6421 +dist/2024-05-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=644896626ec0177c21ab549eff85fcf28d307848454055b4e43909455df51b01 +dist/2024-05-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=43698606a91a090ebdcd6ab5f40f8d62fc0d653eaec74ab851438abe7da8a89e +dist/2024-05-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=19b759811b9193c7b0d710b18427d7324c7ca4dafeca5d7cfebb6686761f9e67 +dist/2024-05-29/rustc-nightly-i686-pc-windows-msvc.tar.gz=c52226e19cff041f23552589f872399723d4c6d6514db93c2d6201f70f36e013 +dist/2024-05-29/rustc-nightly-i686-pc-windows-msvc.tar.xz=49c5b9d7551462e29ef4a036b3a6dd8905455256aff636b4fd4defc516d62e3f +dist/2024-05-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=b04be4f9b1eaf4bb5e9a2a544614ac99f466d5925108633fb8c5b700e7aece7b +dist/2024-05-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=8638b2106fbf7e5dc6837caaf07af1750b6aa24dc845e22a35d8e8e53584b2d6 +dist/2024-05-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=99710480631e11119640f6955257838648db572c4ed0d8d1b0081bace32313b0 +dist/2024-05-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=daab5b6364ad2afe80c96e8d905160e75c0783192296e88fd2b639c49b09d829 +dist/2024-05-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=0f6e0e64bbe42aae577cc0cb87d81ecb64a21c745277872177025611993c47a0 +dist/2024-05-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=fd45d7b870257bce91a33f5b971b11e0c6743e1c03eaa3c26bd201fe9be0c083 +dist/2024-05-29/rustc-nightly-x86_64-apple-darwin.tar.gz=29c34129ce3fef647140a0302fa1699af5460dab518b56d6a2257c7d7c288487 +dist/2024-05-29/rustc-nightly-x86_64-apple-darwin.tar.xz=fdf25c965c5218fad6e2949da8df88eeb9f886a8f5b9c72ec9d79a993c4829c6 \ No newline at end of file diff --git a/src/tools/cargo b/src/tools/cargo index 431db31d0dbe..7a6fad0984d2 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 431db31d0dbeda320caf8ef8535ea48eb3093407 +Subproject commit 7a6fad0984d28c8330974636972aa296b67c4513 diff --git a/src/tools/clippy/book/src/configuration.md b/src/tools/clippy/book/src/configuration.md index 9eb067abd91e..ea549e4df4a5 100644 --- a/src/tools/clippy/book/src/configuration.md +++ b/src/tools/clippy/book/src/configuration.md @@ -133,7 +133,7 @@ Very rarely, you may wish to prevent Clippy from evaluating certain sections of `clippy` cfg is not set. You may need to provide a stub so that the code compiles: ```rust -#[cfg(not(clippy)] +#[cfg(not(clippy))] include!(concat!(env!("OUT_DIR"), "/my_big_function-generated.rs")); #[cfg(clippy)] diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md index 415022612caa..48c00bcbf341 100644 --- a/src/tools/clippy/book/src/development/adding_lints.md +++ b/src/tools/clippy/book/src/development/adding_lints.md @@ -587,6 +587,11 @@ declare_clippy_lint! { } ``` +If the lint is in the `restriction` group because it lints things that are not +necessarily “bad” but are more of a style choice, then replace the +“Why is this bad?” section heading with “Why restrict this?”, to avoid writing +“Why is this bad? It isn't, but ...”. + Once your lint is merged, this documentation will show up in the [lint list][lint_list]. diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs index b6481dde4dde..2e56eb8ec15f 100644 --- a/src/tools/clippy/clippy_dev/src/new_lint.rs +++ b/src/tools/clippy/clippy_dev/src/new_lint.rs @@ -331,12 +331,17 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { } fn get_lint_declaration(name_upper: &str, category: &str) -> String { + let justification_heading = if category == "restriction" { + "Why restrict this?" + } else { + "Why is this bad?" + }; formatdoc!( r#" declare_clippy_lint! {{ /// ### What it does /// - /// ### Why is this bad? + /// ### {justification_heading} /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/absolute_paths.rs b/src/tools/clippy/clippy_lints/src/absolute_paths.rs index 8ba661afeeb6..461117cf965d 100644 --- a/src/tools/clippy/clippy_lints/src/absolute_paths.rs +++ b/src/tools/clippy/clippy_lints/src/absolute_paths.rs @@ -12,7 +12,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of items through absolute paths, like `std::env::current_dir`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Many codebases have their own style when it comes to importing, but one that is seldom used /// is using absolute paths *everywhere*. This is generally considered unidiomatic, and you /// should add a `use` statement. diff --git a/src/tools/clippy/clippy_lints/src/allow_attributes.rs b/src/tools/clippy/clippy_lints/src/allow_attributes.rs index 39fc49dee377..123d0e51eeee 100644 --- a/src/tools/clippy/clippy_lints/src/allow_attributes.rs +++ b/src/tools/clippy/clippy_lints/src/allow_attributes.rs @@ -19,10 +19,11 @@ declare_clippy_lint! { /// This lint only warns outer attributes (`#[allow]`), as inner attributes /// (`#![allow]`) are usually used to enable or disable lints on a global scale. /// - /// ### Why is this bad? - /// `#[expect]` attributes suppress the lint emission, but emit a warning, if + /// ### Why restrict this? + /// `#[allow]` attributes can linger after their reason for existence is gone. + /// `#[expect]` attributes suppress the lint emission, but emit a warning if /// the expectation is unfulfilled. This can be useful to be notified when the - /// lint is no longer triggered. + /// lint is no longer triggered, which may indicate the attribute can be removed. /// /// ### Example /// ```rust,ignore diff --git a/src/tools/clippy/clippy_lints/src/as_conversions.rs b/src/tools/clippy/clippy_lints/src/as_conversions.rs index e3daf75c3eb6..cfa25005a05e 100644 --- a/src/tools/clippy/clippy_lints/src/as_conversions.rs +++ b/src/tools/clippy/clippy_lints/src/as_conversions.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// There is a good explanation the reason why this lint should work in this way and how it is useful /// [in this issue](https://github.com/rust-lang/rust-clippy/issues/5122). /// - /// ### Why is this bad? + /// ### Why restrict this? /// `as` conversions will perform many kinds of /// conversions, including silently lossy conversions and dangerous coercions. /// There are cases when it makes sense to use `as`, so the lint is diff --git a/src/tools/clippy/clippy_lints/src/asm_syntax.rs b/src/tools/clippy/clippy_lints/src/asm_syntax.rs index 7c88bfc97ca4..0db1456d40bf 100644 --- a/src/tools/clippy/clippy_lints/src/asm_syntax.rs +++ b/src/tools/clippy/clippy_lints/src/asm_syntax.rs @@ -65,9 +65,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of Intel x86 assembly syntax. /// - /// ### Why is this bad? - /// The lint has been enabled to indicate a preference - /// for AT&T x86 assembly syntax. + /// ### Why restrict this? + /// To enforce consistent use of AT&T x86 assembly syntax. /// /// ### Example /// @@ -114,9 +113,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of AT&T x86 assembly syntax. /// - /// ### Why is this bad? - /// The lint has been enabled to indicate a preference - /// for Intel x86 assembly syntax. + /// ### Why restrict this? + /// To enforce consistent use of Intel x86 assembly syntax. /// /// ### Example /// diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs index aec22965b1b0..7217686dcca5 100644 --- a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs +++ b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs @@ -16,23 +16,33 @@ declare_clippy_lint! { /// ### What it does /// Checks for `assert!(r.is_ok())` or `assert!(r.is_err())` calls. /// - /// ### Why is this bad? - /// An assertion failure cannot output an useful message of the error. + /// ### Why restrict this? + /// This form of assertion does not show any of the information present in the `Result` + /// other than which variant it isn’t. /// /// ### Known problems /// The suggested replacement decreases the readability of code and log output. /// /// ### Example - /// ```rust,ignore + /// ```rust,no_run /// # let r = Ok::<_, ()>(()); /// assert!(r.is_ok()); - /// # let r = Err::<_, ()>(()); + /// # let r = Err::<(), _>(()); /// assert!(r.is_err()); /// ``` + /// + /// Use instead: + /// + /// ```rust,no_run + /// # let r = Ok::<_, ()>(()); + /// r.unwrap(); + /// # let r = Err::<(), _>(()); + /// r.unwrap_err(); + /// ``` #[clippy::version = "1.64.0"] pub ASSERTIONS_ON_RESULT_STATES, restriction, - "`assert!(r.is_ok())`/`assert!(r.is_err())` gives worse error message than directly calling `r.unwrap()`/`r.unwrap_err()`" + "`assert!(r.is_ok())` or `assert!(r.is_err())` gives worse panic messages than directly calling `r.unwrap()` or `r.unwrap_err()`" } declare_lint_pass!(AssertionsOnResultStates => [ASSERTIONS_ON_RESULT_STATES]); diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs index 39f406077995..a24bd5ed44be 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs @@ -309,9 +309,9 @@ declare_clippy_lint! { /// /// (This requires the `lint_reasons` feature) /// - /// ### Why is this bad? - /// Allowing a lint should always have a reason. This reason should be documented to - /// ensure that others understand the reasoning + /// ### Why restrict this? + /// Justifying each `allow` helps readers understand the reasoning, + /// and may allow removing `allow` attributes if their purpose is obsolete. /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs index bd2c96f01f6f..e60c36ced75d 100644 --- a/src/tools/clippy/clippy_lints/src/casts/mod.rs +++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs @@ -303,7 +303,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for casts of a function pointer to any integer type. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Casting a function pointer to an integer can have surprising results and can occur /// accidentally if parentheses are omitted from a function call. If you aren't doing anything /// low-level with function pointers then you can opt-out of casting functions to integers in @@ -535,8 +535,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for the usage of `as _` conversion using inferred type. /// - /// ### Why is this bad? - /// The conversion might include lossy conversion and dangerous cast that might go + /// ### Why restrict this? + /// The conversion might include lossy conversion or a dangerous cast that might go /// undetected due to the type being inferred. /// /// The lint is allowed by default as using `_` is less wordy than always specifying the type. diff --git a/src/tools/clippy/clippy_lints/src/create_dir.rs b/src/tools/clippy/clippy_lints/src/create_dir.rs index 7a3d5a070912..27c00948a8f2 100644 --- a/src/tools/clippy/clippy_lints/src/create_dir.rs +++ b/src/tools/clippy/clippy_lints/src/create_dir.rs @@ -10,8 +10,10 @@ declare_clippy_lint! { /// ### What it does /// Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead. /// - /// ### Why is this bad? - /// Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`. + /// ### Why restrict this? + /// Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`, + /// resulting in failure when more than one directory needs to be created or when the directory already exists. + /// Crates which never need to specifically create a single directory may wish to prevent this mistake. /// /// ### Example /// ```rust,ignore diff --git a/src/tools/clippy/clippy_lints/src/dbg_macro.rs b/src/tools/clippy/clippy_lints/src/dbg_macro.rs index db5937266047..b0590b0a71cb 100644 --- a/src/tools/clippy/clippy_lints/src/dbg_macro.rs +++ b/src/tools/clippy/clippy_lints/src/dbg_macro.rs @@ -14,7 +14,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of the [`dbg!`](https://doc.rust-lang.org/std/macro.dbg.html) macro. /// - /// ### Why is this bad? + /// ### Why restrict this? /// The `dbg!` macro is intended as a debugging tool. It should not be present in released /// software or committed to a version control system. /// diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs index 1d6c4ce72e18..ff631909bcb5 100644 --- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs +++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs @@ -22,9 +22,8 @@ declare_clippy_lint! { /// /// See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback. /// - /// ### Why is this bad? - /// For those who are very careful about types, default numeric fallback - /// can be a pitfall that cause unexpected runtime behavior. + /// ### Why restrict this? + /// To ensure that every numeric type is chosen explicitly rather than implicitly. /// /// ### Known problems /// This lint can only be allowed at the function level or above. @@ -49,7 +48,7 @@ declare_clippy_lint! { declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]); impl<'tcx> LateLintPass<'tcx> for DefaultNumericFallback { - fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { + fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) { let hir = cx.tcx.hir(); let is_parent_const = matches!( hir.body_const_context(hir.body_owner_def_id(body.id())), diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs index b4290b6437f2..3fa9bad0d03d 100644 --- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs +++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs @@ -10,7 +10,7 @@ declare_clippy_lint! { /// ### What it does /// Displays a warning when a union is declared with the default representation (without a `#[repr(C)]` attribute). /// - /// ### Why is this bad? + /// ### Why restrict this? /// Unions in Rust have unspecified layout by default, despite many people thinking that they /// lay out each field at the start of the union (like C does). That is, there are no guarantees /// about the offset of the fields for unions with multiple non-ZST fields without an explicitly diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index c6aef9ac2d60..d60320d82825 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -2,7 +2,9 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::sugg::has_enclosing_paren; use clippy_utils::ty::{implements_trait, is_manually_drop, peel_mid_ty_refs}; -use clippy_utils::{expr_use_ctxt, get_parent_expr, is_lint_allowed, path_to_local, DefinedTy, ExprUseNode}; +use clippy_utils::{ + expr_use_ctxt, get_parent_expr, is_block_like, is_lint_allowed, path_to_local, DefinedTy, ExprUseNode, +}; use core::mem; use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX}; use rustc_data_structures::fx::FxIndexMap; @@ -641,7 +643,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { } } - fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { + fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'_>) { if Some(body.id()) == self.current_body { for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) { let replacements = pat.replacements; @@ -1038,14 +1040,8 @@ fn report<'tcx>( ); }, State::ExplicitDeref { mutability } => { - if matches!( - expr.kind, - ExprKind::Block(..) - | ExprKind::ConstBlock(_) - | ExprKind::If(..) - | ExprKind::Loop(..) - | ExprKind::Match(..) - ) && let ty::Ref(_, ty, _) = data.adjusted_ty.kind() + if is_block_like(expr) + && let ty::Ref(_, ty, _) = data.adjusted_ty.kind() && ty.is_sized(cx.tcx, cx.param_env) { // Rustc bug: auto deref doesn't work on block expression when targeting sized types. diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 2a644922fb1c..636698e96f6d 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -1,17 +1,17 @@ -use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy}; use clippy_utils::{has_non_exhaustive_attr, is_lint_allowed, match_def_path, paths}; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor}; use rustc_hir::{ - self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Safety, Impl, Item, ItemKind, UnsafeSource, + self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, Safety, UnsafeSource, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::traits::Reveal; use rustc_middle::ty::{ - self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, Upcast, TraitPredicate, Ty, TyCtxt, + self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, TraitPredicate, Ty, TyCtxt, Upcast, }; use rustc_session::declare_lint_pass; use rustc_span::def_id::LocalDefId; @@ -390,13 +390,17 @@ fn check_unsafe_derive_deserialize<'tcx>( .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local())) .any(|imp| has_unsafe(cx, imp)) { - span_lint_and_help( + span_lint_hir_and_then( cx, UNSAFE_DERIVE_DESERIALIZE, + adt_hir_id, item.span, "you are deriving `serde::Deserialize` on a type that has methods using `unsafe`", - None, - "consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html", + |diag| { + diag.help( + "consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html", + ); + }, ); } } @@ -452,20 +456,27 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r && !has_non_exhaustive_attr(cx.tcx, *adt) && !ty_implements_eq_trait(cx.tcx, ty, eq_trait_def_id) && let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id) + && let Some(local_def_id) = adt.did().as_local() // If all of our fields implement `Eq`, we can implement `Eq` too && adt .all_fields() .map(|f| f.ty(cx.tcx, args)) .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])) { - span_lint_and_sugg( + span_lint_hir_and_then( cx, DERIVE_PARTIAL_EQ_WITHOUT_EQ, + cx.tcx.local_def_id_to_hir_id(local_def_id), span.ctxt().outer_expn_data().call_site, "you are deriving `PartialEq` and can implement `Eq`", - "consider deriving `Eq` as well", - "PartialEq, Eq".to_string(), - Applicability::MachineApplicable, + |diag| { + diag.span_suggestion( + span.ctxt().outer_expn_data().call_site, + "consider deriving `Eq` as well", + "PartialEq, Eq", + Applicability::MachineApplicable, + ); + }, ); } } diff --git a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs index def4b5932b4b..a995f06fb73d 100644 --- a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs +++ b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs @@ -20,11 +20,11 @@ declare_clippy_lint! { /// [aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases /// [supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html /// - /// ### Why is this bad? + /// ### Why restrict this? /// It may be not desired to have many different scripts for /// identifiers in the codebase. /// - /// Note that if you only want to allow plain English, you might want to use + /// Note that if you only want to allow typical English, you might want to use /// built-in [`non_ascii_idents`] lint instead. /// /// [`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents diff --git a/src/tools/clippy/clippy_lints/src/doc/markdown.rs b/src/tools/clippy/clippy_lints/src/doc/markdown.rs index 1add02af3101..41c0bcd55adc 100644 --- a/src/tools/clippy/clippy_lints/src/doc/markdown.rs +++ b/src/tools/clippy/clippy_lints/src/doc/markdown.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::snippet_with_applicability; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, SuggestionStyle}; @@ -30,6 +30,7 @@ pub fn check( word = tmp_word; } + let original_len = word.len(); word = word.trim_start_matches(trim_pattern); // Remove leading or trailing single `:` which may be part of a sentence. @@ -44,6 +45,25 @@ pub fn check( continue; } + // Ensure that all reachable matching closing parens are included as well. + let size_diff = original_len - word.len(); + let mut open_parens = 0; + let mut close_parens = 0; + for c in word.chars() { + if c == '(' { + open_parens += 1; + } else if c == ')' { + close_parens += 1; + } + } + while close_parens < open_parens + && let Some(tmp_word) = orig_word.get(size_diff..=(word.len() + size_diff)) + && tmp_word.ends_with(')') + { + word = tmp_word; + close_parens += 1; + } + // Adjust for the current word let offset = word.as_ptr() as usize - text.as_ptr() as usize; let span = Span::new( @@ -92,13 +112,15 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span, code_level: isize, b if let Ok(url) = Url::parse(word) { // try to get around the fact that `foo::bar` parses as a valid URL if !url.cannot_be_a_base() { - span_lint( + span_lint_and_sugg( cx, DOC_MARKDOWN, span, "you should put bare URLs between `<`/`>` or make a proper Markdown link", + "try", + format!("<{word}>"), + Applicability::MachineApplicable, ); - return; } } diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs index 9f08973948a3..3d875e7ac2d3 100644 --- a/src/tools/clippy/clippy_lints/src/doc/mod.rs +++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs @@ -261,7 +261,7 @@ declare_clippy_lint! { /// Checks for the doc comments of publicly visible /// safe functions and traits and warns if there is a `# Safety` section. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Safe functions and traits are safe to implement and therefore do not /// need to describe safety preconditions that users are required to uphold. /// diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs index 119473c2454b..4a6ffcd9a788 100644 --- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs +++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs @@ -52,9 +52,10 @@ declare_clippy_lint! { /// Checks for usage of `std::mem::forget(t)` where `t` is /// `Drop` or has a field that implements `Drop`. /// - /// ### Why is this bad? - /// `std::mem::forget(t)` prevents `t` from running its - /// destructor, possibly causing leaks. + /// ### Why restrict this? + /// `std::mem::forget(t)` prevents `t` from running its destructor, possibly causing leaks. + /// It is not possible to detect all means of creating leaks, but it may be desirable to + /// prohibit the simple ones. /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/else_if_without_else.rs b/src/tools/clippy/clippy_lints/src/else_if_without_else.rs index a6ca7fe9e0bb..bb6f9aac2236 100644 --- a/src/tools/clippy/clippy_lints/src/else_if_without_else.rs +++ b/src/tools/clippy/clippy_lints/src/else_if_without_else.rs @@ -11,7 +11,7 @@ declare_clippy_lint! { /// Checks for usage of if expressions with an `else if` branch, /// but without a final `else` branch. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10). /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/empty_drop.rs b/src/tools/clippy/clippy_lints/src/empty_drop.rs index 74db250b3ae9..c5fc72b5e2d8 100644 --- a/src/tools/clippy/clippy_lints/src/empty_drop.rs +++ b/src/tools/clippy/clippy_lints/src/empty_drop.rs @@ -9,7 +9,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for empty `Drop` implementations. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Empty `Drop` implementations have no effect when dropping an instance of the type. They are /// most likely useless. However, an empty `Drop` implementation prevents a type from being /// destructured, which might be the intention behind adding the implementation as a marker. diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs index 420888b6ccb3..d16714695cb7 100644 --- a/src/tools/clippy/clippy_lints/src/empty_enum.rs +++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs @@ -7,32 +7,53 @@ use rustc_session::declare_lint_pass; declare_clippy_lint! { /// ### What it does - /// Checks for `enum`s with no variants. + /// Checks for `enum`s with no variants, which therefore are uninhabited types + /// (cannot be instantiated). /// - /// As of this writing, the `never_type` is still a - /// nightly-only experimental API. Therefore, this lint is only triggered - /// if the `never_type` is enabled. + /// As of this writing, the `never_type` is still a nightly-only experimental API. + /// Therefore, this lint is only triggered if `#![feature(never_type)]` is enabled. /// /// ### Why is this bad? - /// If you want to introduce a type which - /// can't be instantiated, you should use `!` (the primitive type "never"), - /// or a wrapper around it, because `!` has more extensive - /// compiler support (type inference, etc...) and wrappers - /// around it are the conventional way to define an uninhabited type. - /// For further information visit [never type documentation](https://doc.rust-lang.org/std/primitive.never.html) + /// * If you only want a type which can’t be instantiated, you should use [`!`] + /// (the primitive type "never"), because [`!`] has more extensive compiler support + /// (type inference, etc.) and implementations of common traits. /// + /// * If you need to introduce a distinct type, consider using a [newtype] `struct` + /// containing [`!`] instead (`struct MyType(pub !)`), because it is more idiomatic + /// to use a `struct` rather than an `enum` when an `enum` is unnecessary. + /// + /// If you do this, note that the [visibility] of the [`!`] field determines whether + /// the uninhabitedness is visible in documentation, and whether it can be pattern + /// matched to mark code unreachable. If the field is not visible, then the struct + /// acts like any other struct with private fields. + /// + /// * If the enum has no variants only because all variants happen to be + /// [disabled by conditional compilation][cfg], then it would be appropriate + /// to allow the lint, with `#[allow(empty_enum)]`. + /// + /// For further information, visit + /// [the never type’s documentation][`!`]. /// /// ### Example /// ```no_run - /// enum Test {} + /// enum CannotExist {} /// ``` /// /// Use instead: /// ```no_run /// #![feature(never_type)] /// - /// struct Test(!); + /// /// Use the `!` type directly... + /// type CannotExist = !; + /// + /// /// ...or define a newtype which is distinct. + /// struct CannotExist2(pub !); /// ``` + /// + /// [`!`]: https://doc.rust-lang.org/std/primitive.never.html + /// [cfg]: https://doc.rust-lang.org/reference/conditional-compilation.html + /// [newtype]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction + /// [visibility]: https://doc.rust-lang.org/reference/visibility-and-privacy.html #[clippy::version = "pre 1.29.0"] pub EMPTY_ENUM, pedantic, diff --git a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs index 969df6d85b5a..745599b0e57a 100644 --- a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs +++ b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs @@ -11,16 +11,23 @@ declare_clippy_lint! { /// ### What it does /// Finds structs without fields (a so-called "empty struct") that are declared with brackets. /// - /// ### Why is this bad? - /// Empty brackets after a struct declaration can be omitted. + /// ### Why restrict this? + /// Empty brackets after a struct declaration can be omitted, + /// and it may be desirable to do so consistently for style. + /// + /// However, removing the brackets also introduces a public constant named after the struct, + /// so this is not just a syntactic simplification but an an API change, and adding them back + /// is a *breaking* API change. /// /// ### Example /// ```no_run /// struct Cookie {} + /// struct Biscuit(); /// ``` /// Use instead: /// ```no_run /// struct Cookie; + /// struct Biscuit; /// ``` #[clippy::version = "1.62.0"] pub EMPTY_STRUCTS_WITH_BRACKETS, @@ -32,14 +39,20 @@ declare_clippy_lint! { /// ### What it does /// Finds enum variants without fields that are declared with empty brackets. /// - /// ### Why is this bad? - /// Empty brackets while defining enum variants are redundant and can be omitted. + /// ### Why restrict this? + /// Empty brackets after a enum variant declaration are redundant and can be omitted, + /// and it may be desirable to do so consistently for style. + /// + /// However, removing the brackets also introduces a public constant named after the variant, + /// so this is not just a syntactic simplification but an an API change, and adding them back + /// is a *breaking* API change. /// /// ### Example /// ```no_run /// enum MyEnum { /// HasData(u8), - /// HasNoData(), // redundant parentheses + /// HasNoData(), // redundant parentheses + /// NoneHereEither {}, // redundant braces /// } /// ``` /// @@ -48,6 +61,7 @@ declare_clippy_lint! { /// enum MyEnum { /// HasData(u8), /// HasNoData, + /// NoneHereEither, /// } /// ``` #[clippy::version = "1.77.0"] diff --git a/src/tools/clippy/clippy_lints/src/endian_bytes.rs b/src/tools/clippy/clippy_lints/src/endian_bytes.rs index dd03df797de3..bb766e963387 100644 --- a/src/tools/clippy/clippy_lints/src/endian_bytes.rs +++ b/src/tools/clippy/clippy_lints/src/endian_bytes.rs @@ -13,8 +13,9 @@ declare_clippy_lint! { /// ### What it does /// Checks for the usage of the `to_ne_bytes` method and/or the function `from_ne_bytes`. /// - /// ### Why is this bad? - /// It's not, but some may prefer to specify the target endianness explicitly. + /// ### Why restrict this? + /// To ensure use of explicitly chosen endianness rather than the target’s endianness, + /// such as when implementing network protocols or file formats rather than FFI. /// /// ### Example /// ```rust,ignore @@ -31,9 +32,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for the usage of the `to_le_bytes` method and/or the function `from_le_bytes`. /// - /// ### Why is this bad? - /// It's not, but some may wish to lint usage of this method, either to suggest using the host - /// endianness or big endian. + /// ### Why restrict this? + /// To ensure use of big endian or the target’s endianness rather than little endian. /// /// ### Example /// ```rust,ignore @@ -50,9 +50,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for the usage of the `to_be_bytes` method and/or the function `from_be_bytes`. /// - /// ### Why is this bad? - /// It's not, but some may wish to lint usage of this method, either to suggest using the host - /// endianness or little endian. + /// ### Why restrict this? + /// To ensure use of little endian or the target’s endianness rather than big endian. /// /// ### Example /// ```rust,ignore diff --git a/src/tools/clippy/clippy_lints/src/error_impl_error.rs b/src/tools/clippy/clippy_lints/src/error_impl_error.rs index 8dbb47fadc5d..8e49138cd26b 100644 --- a/src/tools/clippy/clippy_lints/src/error_impl_error.rs +++ b/src/tools/clippy/clippy_lints/src/error_impl_error.rs @@ -12,7 +12,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for types named `Error` that implement `Error`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// It can become confusing when a codebase has 20 types all named `Error`, requiring either /// aliasing them in the `use` statement or qualifying them like `my_module::Error`. This /// hinders comprehension, as it requires you to memorize every variation of importing `Error` diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index b58018ca0353..48c4c4206fe8 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -10,7 +10,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{ self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, RegionKind, Ty, - TypeVisitableExt, TypeckResults, + TypeVisitableExt, TypeckResults, TyCtxt, }; use rustc_session::declare_lint_pass; use rustc_span::symbol::sym; @@ -240,7 +240,7 @@ fn check_inputs( }) } -fn check_sig<'tcx>(cx: &LateContext<'tcx>, closure: ClosureArgs<'tcx>, call_sig: FnSig<'_>) -> bool { +fn check_sig<'tcx>(cx: &LateContext<'tcx>, closure: ClosureArgs>, call_sig: FnSig<'_>) -> bool { call_sig.safety == Safety::Safe && !has_late_bound_to_non_late_bound_regions( cx.tcx.signature_unclosure(closure.sig(), Safety::Safe).skip_binder(), diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs index 9ffda6457424..436dc8611bde 100644 --- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs +++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs @@ -10,10 +10,10 @@ declare_clippy_lint! { /// ### What it does /// Warns on any exported `enum`s that are not tagged `#[non_exhaustive]` /// - /// ### Why is this bad? - /// Exhaustive enums are typically fine, but a project which does - /// not wish to make a stability commitment around exported enums may wish to - /// disable them by default. + /// ### Why restrict this? + /// Making an `enum` exhaustive is a stability commitment: adding a variant is a breaking change. + /// A project may wish to ensure that there are no exhaustive enums or that every exhaustive + /// `enum` is explicitly `#[allow]`ed. /// /// ### Example /// ```no_run @@ -40,10 +40,10 @@ declare_clippy_lint! { /// ### What it does /// Warns on any exported `struct`s that are not tagged `#[non_exhaustive]` /// - /// ### Why is this bad? - /// Exhaustive structs are typically fine, but a project which does - /// not wish to make a stability commitment around exported structs may wish to - /// disable them by default. + /// ### Why restrict this? + /// Making a `struct` exhaustive is a stability commitment: adding a field is a breaking change. + /// A project may wish to ensure that there are no exhaustive structs or that every exhaustive + /// `struct` is explicitly `#[allow]`ed. /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs index 106844dd4348..91c94d66458d 100644 --- a/src/tools/clippy/clippy_lints/src/exit.rs +++ b/src/tools/clippy/clippy_lints/src/exit.rs @@ -9,11 +9,13 @@ declare_clippy_lint! { /// ### What it does /// Detects calls to the `exit()` function which terminates the program. /// - /// ### Why is this bad? - /// Exit terminates the program at the location it is called. For unrecoverable - /// errors `panics` should be used to provide a stacktrace and potentially other - /// information. A normal termination or one with an error code should happen in - /// the main function. + /// ### Why restrict this? + /// `exit()` immediately terminates the program with no information other than an exit code. + /// This provides no means to troubleshoot a problem, and may be an unexpected side effect. + /// + /// Codebases may use this lint to require that all exits are performed either by panicking + /// (which produces a message, a code location, and optionally a backtrace) + /// or by returning from `main()` (which is a single place to look). /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/float_literal.rs b/src/tools/clippy/clippy_lints/src/float_literal.rs index 2cd4e9e99a56..4ec9bd757ff4 100644 --- a/src/tools/clippy/clippy_lints/src/float_literal.rs +++ b/src/tools/clippy/clippy_lints/src/float_literal.rs @@ -38,9 +38,9 @@ declare_clippy_lint! { /// Checks for whole number float literals that /// cannot be represented as the underlying type without loss. /// - /// ### Why is this bad? - /// Rust will silently lose precision during - /// conversion to a float. + /// ### Why restrict this? + /// If the value was intended to be exact, it will not be. + /// This may be especially surprising when the lost precision is to the left of the decimal point. /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/format_push_string.rs b/src/tools/clippy/clippy_lints/src/format_push_string.rs index 2b08437d8271..a75538dd329b 100644 --- a/src/tools/clippy/clippy_lints/src/format_push_string.rs +++ b/src/tools/clippy/clippy_lints/src/format_push_string.rs @@ -11,7 +11,7 @@ declare_clippy_lint! { /// Detects cases where the result of a `format!` call is /// appended to an existing `String`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Introduces an extra, avoidable heap allocation. /// /// ### Known problems diff --git a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs index 7729c556e1fc..2cbc4b072341 100644 --- a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs +++ b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; -use rustc_hir::{Body, ExprKind, FnDecl, Safety, ImplicitSelfKind}; +use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind, Safety}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::Span; diff --git a/src/tools/clippy/clippy_lints/src/functions/mod.rs b/src/tools/clippy/clippy_lints/src/functions/mod.rs index dfcaac9abefc..26534492dddd 100644 --- a/src/tools/clippy/clippy_lints/src/functions/mod.rs +++ b/src/tools/clippy/clippy_lints/src/functions/mod.rs @@ -338,8 +338,10 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does /// Lints when `impl Trait` is being used in a function's parameters. - /// ### Why is this bad? - /// Turbofish syntax (`::<>`) cannot be used when `impl Trait` is being used, making `impl Trait` less powerful. Readability may also be a factor. + /// + /// ### Why restrict this? + /// Turbofish syntax (`::<>`) cannot be used to specify the type of an `impl Trait` parameter, + /// making `impl Trait` less powerful. Readability may also be a factor. /// /// ### Example /// ```no_run @@ -366,9 +368,8 @@ declare_clippy_lint! { /// Lints when the name of function parameters from trait impl is /// different than its default implementation. /// - /// ### Why is this bad? - /// Using the default name for parameters of a trait method is often - /// more desirable for consistency's sake. + /// ### Why restrict this? + /// Using the default name for parameters of a trait method is more consistent. /// /// ### Example /// ```rust diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 192fb611c2d4..cb1d0de1edff 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -79,7 +79,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap(); let span = decl.output.span(); let infcx = cx.tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let cause = traits::ObligationCause::misc(span, fn_def_id); ocx.register_bound(cause, cx.param_env, ret_ty, send_trait); let send_errors = ocx.select_all_or_error(); diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs index f5ba62ae432e..0b2008152198 100644 --- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs +++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs @@ -15,7 +15,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for if-else that could be written using either `bool::then` or `bool::then_some`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Looks a little redundant. Using `bool::then` is more concise and incurs no loss of clarity. /// For simple calculations and known values, use `bool::then_some`, which is eagerly evaluated /// in comparison to `bool::then`. diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs index a46aae36d5c5..ca830af3b2f3 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs @@ -328,7 +328,7 @@ impl<'a, 'b, 'tcx> ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; - fn visit_body(&mut self, body: &'tcx Body<'_>) { + fn visit_body(&mut self, body: &Body<'tcx>) { let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body.id())); walk_body(self, body); self.maybe_typeck_results = old_maybe_typeck_results; diff --git a/src/tools/clippy/clippy_lints/src/implicit_return.rs b/src/tools/clippy/clippy_lints/src/implicit_return.rs index 5288efd8df8c..cc342007ec61 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_return.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_return.rs @@ -16,12 +16,13 @@ declare_clippy_lint! { /// ### What it does /// Checks for missing return statements at the end of a block. /// - /// ### Why is this bad? - /// Actually omitting the return keyword is idiomatic Rust code. Programmers - /// coming from other languages might prefer the expressiveness of `return`. It's possible to miss - /// the last returning statement because the only difference is a missing `;`. Especially in bigger - /// code with multiple return paths having a `return` keyword makes it easier to find the - /// corresponding statements. + /// ### Why restrict this? + /// Omitting the return keyword whenever possible is idiomatic Rust code, but: + /// + /// * Programmers coming from other languages might prefer the expressiveness of `return`. + /// * It's possible to miss the last returning statement because the only difference is a missing `;`. + /// * Especially in bigger code with multiple return paths, having a `return` keyword makes it easier to find the + /// corresponding statements. /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs index dc935ed3d7fe..2b389d4f9b19 100644 --- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs +++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs @@ -3,7 +3,7 @@ use clippy_utils::source::snippet; use rustc_errors::{Applicability, SuggestionStyle}; use rustc_hir::def_id::DefId; use rustc_hir::{ - GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, TypeBinding, + GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, AssocItemConstraint, WherePredicate, }; use rustc_hir_analysis::lower_ty; @@ -54,9 +54,9 @@ fn emit_lint( poly_trait: &rustc_hir::PolyTraitRef<'_>, bounds: GenericBounds<'_>, index: usize, - // The bindings that were implied, used for suggestion purposes since removing a bound with associated types - // means we might need to then move it to a different bound - implied_bindings: &[TypeBinding<'_>], + // The constraints that were implied, used for suggestion purposes since removing a bound with + // associated types means we might need to then move it to a different bound. + implied_constraints: &[AssocItemConstraint<'_>], bound: &ImplTraitBound<'_>, ) { let implied_by = snippet(cx, bound.span, ".."); @@ -83,29 +83,29 @@ fn emit_lint( let mut sugg = vec![(implied_span_extended, String::new())]; - // We also might need to include associated type binding that were specified in the implied bound, + // We also might need to include associated item constraints that were specified in the implied bound, // but omitted in the implied-by bound: // `fn f() -> impl Deref + DerefMut` // If we're going to suggest removing `Deref<..>`, we'll need to put `` on `DerefMut` - let omitted_assoc_tys: Vec<_> = implied_bindings + let omitted_constraints: Vec<_> = implied_constraints .iter() - .filter(|binding| !bound.bindings.iter().any(|b| b.ident == binding.ident)) + .filter(|constraint| !bound.constraints.iter().any(|c| c.ident == constraint.ident)) .collect(); - if !omitted_assoc_tys.is_empty() { - // `<>` needs to be added if there aren't yet any generic arguments or bindings - let needs_angle_brackets = bound.args.is_empty() && bound.bindings.is_empty(); - let insert_span = match (bound.args, bound.bindings) { - ([.., arg], [.., binding]) => arg.span().max(binding.span).shrink_to_hi(), + if !omitted_constraints.is_empty() { + // `<>` needs to be added if there aren't yet any generic arguments or constraints + let needs_angle_brackets = bound.args.is_empty() && bound.constraints.is_empty(); + let insert_span = match (bound.args, bound.constraints) { + ([.., arg], [.., constraint]) => arg.span().max(constraint.span).shrink_to_hi(), ([.., arg], []) => arg.span().shrink_to_hi(), - ([], [.., binding]) => binding.span.shrink_to_hi(), + ([], [.., constraint]) => constraint.span.shrink_to_hi(), ([], []) => bound.span.shrink_to_hi(), }; - let mut associated_tys_sugg = if needs_angle_brackets { + let mut constraints_sugg = if needs_angle_brackets { "<".to_owned() } else { - // If angle brackets aren't needed (i.e., there are already generic arguments or bindings), + // If angle brackets aren't needed (i.e., there are already generic arguments or constraints), // we need to add a comma: // `impl A` // ^ if we insert `Assoc=i32` without a comma here, that'd be invalid syntax: @@ -113,16 +113,16 @@ fn emit_lint( ", ".to_owned() }; - for (index, binding) in omitted_assoc_tys.into_iter().enumerate() { + for (index, constraint) in omitted_constraints.into_iter().enumerate() { if index > 0 { - associated_tys_sugg += ", "; + constraints_sugg += ", "; } - associated_tys_sugg += &snippet(cx, binding.span, ".."); + constraints_sugg += &snippet(cx, constraint.span, ".."); } if needs_angle_brackets { - associated_tys_sugg += ">"; + constraints_sugg += ">"; } - sugg.push((insert_span, associated_tys_sugg)); + sugg.push((insert_span, constraints_sugg)); } diag.multipart_suggestion_with_style( @@ -229,8 +229,8 @@ struct ImplTraitBound<'tcx> { trait_def_id: DefId, /// The generic arguments on the `impl Trait` bound args: &'tcx [GenericArg<'tcx>], - /// The associated types on this bound - bindings: &'tcx [TypeBinding<'tcx>], + /// The associated item constraints of this bound + constraints: &'tcx [AssocItemConstraint<'tcx>], } /// Given an `impl Trait` type, gets all the supertraits from each bound ("implied bounds"). @@ -253,7 +253,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds Some(ImplTraitBound { predicates, args: path.args.map_or([].as_slice(), |p| p.args), - bindings: path.args.map_or([].as_slice(), |p| p.bindings), + constraints: path.args.map_or([].as_slice(), |p| p.constraints), trait_def_id, span: bound.span(), }) @@ -310,20 +310,20 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) { if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound && let [.., path] = poly_trait.trait_ref.path.segments && let implied_args = path.args.map_or([].as_slice(), |a| a.args) - && let implied_bindings = path.args.map_or([].as_slice(), |a| a.bindings) + && let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints) && let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id() && let Some(bound) = find_bound_in_supertraits(cx, def_id, implied_args, &supertraits) // If the implied bound has a type binding that also exists in the implied-by trait, // then we shouldn't lint. See #11880 for an example. && let assocs = cx.tcx.associated_items(bound.trait_def_id) - && !implied_bindings.iter().any(|binding| { + && !implied_constraints.iter().any(|constraint| { assocs - .filter_by_name_unhygienic(binding.ident.name) + .filter_by_name_unhygienic(constraint.ident.name) .next() .is_some_and(|assoc| assoc.kind == ty::AssocKind::Type) }) { - emit_lint(cx, poly_trait, bounds, index, implied_bindings, bound); + emit_lint(cx, poly_trait, bounds, index, implied_constraints, bound); } } } diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs index 35fcd8cdd354..e3e79749bea6 100644 --- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs @@ -45,9 +45,10 @@ declare_clippy_lint! { /// does report on arrays if we can tell that slicing operations are in bounds and does not /// lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint. /// - /// ### Why is this bad? - /// Indexing and slicing can panic at runtime and there are - /// safe alternatives. + /// ### Why restrict this? + /// To avoid implicit panics from indexing and slicing. + /// There are “checked” alternatives which do not panic, and can be used with `unwrap()` to make + /// an explicit panic when it is desired. /// /// ### Example /// ```rust,no_run diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs index 1127f00abde0..95ae591884bc 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs @@ -14,7 +14,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for multiple inherent implementations of a struct /// - /// ### Why is this bad? + /// ### Why restrict this? /// Splitting the implementation of a type makes the code harder to navigate. /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs b/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs index e486563808a5..1c8fd0a27f98 100644 --- a/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs +++ b/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{Expr, ExprKind}; @@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for NumberedFields { snippet_with_applicability(cx, path.span(), "..", &mut appl), expr_spans .into_iter_sorted() - .map(|(_, span)| snippet_with_applicability(cx, span, "..", &mut appl)) + .map(|(_, span)| snippet_with_context(cx, span, path.span().ctxt(), "..", &mut appl).0) .intersperse(Cow::Borrowed(", ")) .collect::() ); diff --git a/src/tools/clippy/clippy_lints/src/integer_division_remainder_used.rs b/src/tools/clippy/clippy_lints/src/integer_division_remainder_used.rs index a3577b765c03..cf598d5045ec 100644 --- a/src/tools/clippy/clippy_lints/src/integer_division_remainder_used.rs +++ b/src/tools/clippy/clippy_lints/src/integer_division_remainder_used.rs @@ -7,10 +7,10 @@ use rustc_session::declare_lint_pass; declare_clippy_lint! { /// ### What it does - /// Checks for the usage of division (/) and remainder (%) operations - /// when performed on any integer types using the default Div and Rem trait implementations. + /// Checks for the usage of division (`/`) and remainder (`%`) operations + /// when performed on any integer types using the default `Div` and `Rem` trait implementations. /// - /// ### Why is this bad? + /// ### Why restrict this? /// In cryptographic contexts, division can result in timing sidechannel vulnerabilities, /// and needs to be replaced with constant-time code instead (e.g. Barrett reduction). /// diff --git a/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs b/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs index 6c6eff9ba48b..fb29d9824179 100644 --- a/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs +++ b/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs @@ -14,8 +14,8 @@ declare_clippy_lint! { /// ### What it does /// This is a restriction lint which prevents the use of hash types (i.e., `HashSet` and `HashMap`) in for loops. /// - /// ### Why is this bad? - /// Because hash types are unordered, when iterated through such as in a for loop, the values are returned in + /// ### Why restrict this? + /// Because hash types are unordered, when iterated through such as in a `for` loop, the values are returned in /// an undefined order. As a result, on redundant systems this may cause inconsistencies and anomalies. /// In addition, the unknown order of the elements may reduce readability or introduce other undesired /// side effects. 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 790bed580fd1..07efee159aab 100644 --- a/src/tools/clippy/clippy_lints/src/large_include_file.rs +++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs @@ -10,10 +10,12 @@ use rustc_span::sym; declare_clippy_lint! { /// ### What it does /// Checks for the inclusion of large files via `include_bytes!()` - /// and `include_str!()` + /// or `include_str!()`. /// - /// ### Why is this bad? - /// Including large files can increase the size of the binary + /// ### Why restrict this? + /// Including large files can undesirably increase the size of the binary produced by the compiler. + /// This lint may be used to catch mistakes where an unexpectedly large file is included, or + /// temporarily to obtain a list of all large files. /// /// ### Example /// ```rust,ignore diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 97a245b76d44..57e0a7aa2c7e 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -9,7 +9,7 @@ use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::{ AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind, ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatKind, PathSegment, PrimTy, QPath, - TraitItemRef, TyKind, TypeBindingKind, + TraitItemRef, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, AssocKind, FnSig, Ty}; @@ -253,7 +253,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items // fill the set with current and super traits fn fill_trait_set(traitt: DefId, set: &mut DefIdSet, cx: &LateContext<'_>) { if set.insert(traitt) { - for supertrait in rustc_trait_selection::traits::supertrait_def_ids(cx.tcx, traitt) { + for supertrait in cx.tcx.supertrait_def_ids(traitt) { fill_trait_set(supertrait, set, cx); } } @@ -307,17 +307,12 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<& && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds && let Some(segment) = trait_ref.trait_ref.path.segments.last() && let Some(generic_args) = segment.args - && generic_args.bindings.len() == 1 - && let TypeBindingKind::Equality { - term: - rustc_hir::Term::Ty(rustc_hir::Ty { - kind: TyKind::Path(QPath::Resolved(_, path)), - .. - }), - } = &generic_args.bindings[0].kind - && path.segments.len() == 1 + && let [constraint] = generic_args.constraints + && let Some(ty) = constraint.ty() + && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind + && let [segment] = path.segments { - return Some(&path.segments[0]); + return Some(segment); } None diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs index 619e933b4fff..9fd4f509aa47 100644 --- a/src/tools/clippy/clippy_lints/src/let_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs @@ -12,9 +12,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for `let _ = ` where expr is `#[must_use]` /// - /// ### Why is this bad? - /// It's better to explicitly handle the value of a `#[must_use]` - /// expr + /// ### Why restrict this? + /// To ensure that all `#[must_use]` types are used rather than ignored. /// /// ### Example /// ```no_run @@ -96,8 +95,8 @@ declare_clippy_lint! { /// Checks for `let _ = ` without a type annotation, and suggests to either provide one, /// or remove the `let` keyword altogether. /// - /// ### Why is this bad? - /// The `let _ = ` expression ignores the value of `` but will remain doing so even + /// ### Why restrict this? + /// The `let _ = ` expression ignores the value of ``, but will continue to do so even /// if the type were to change, thus potentially introducing subtle bugs. By supplying a type /// annotation, one will be forced to re-visit the decision to ignore the value in such cases. /// diff --git a/src/tools/clippy/clippy_lints/src/literal_representation.rs b/src/tools/clippy/clippy_lints/src/literal_representation.rs index 2348dd18220f..d2a140a36a83 100644 --- a/src/tools/clippy/clippy_lints/src/literal_representation.rs +++ b/src/tools/clippy/clippy_lints/src/literal_representation.rs @@ -132,8 +132,8 @@ declare_clippy_lint! { /// ### What it does /// Warns if there is a better representation for a numeric literal. /// - /// ### Why is this bad? - /// Especially for big powers of 2 a hexadecimal representation is more + /// ### Why restrict this? + /// Especially for big powers of 2, a hexadecimal representation is usually more /// readable than a decimal representation. /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs index 3dcb050d77e6..086829421530 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mod.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs @@ -675,9 +675,9 @@ declare_clippy_lint! { /// Checks for infinite loops in a function where the return type is not `!` /// and lint accordingly. /// - /// ### Why is this bad? - /// A loop should be gently exited somewhere, or at least mark its parent function as - /// never return (`!`). + /// ### Why restrict this? + /// Making the return type `!` serves as documentation that the function does not return. + /// If the function is not intended to loop infinitely, then this lint may detect a bug. /// /// ### Example /// ```no_run,ignore diff --git a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs index aea3d26e1878..d1ae243877d7 100644 --- a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs +++ b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs @@ -186,7 +186,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BodyVisitor<'a, 'tcx> { } impl<'tcx> LateLintPass<'tcx> for ExprMetavarsInUnsafe { - fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx rustc_hir::Body<'tcx>) { + fn check_body(&mut self, cx: &LateContext<'tcx>, body: &rustc_hir::Body<'tcx>) { if is_lint_allowed(cx, MACRO_METAVARS_IN_UNSAFE, body.value.hir_id) { return; } diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index 4cd5f3b81e52..25c7e5d38b31 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -4,8 +4,7 @@ use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; use rustc_hir::{ Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl, - FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, Term, TraitRef, Ty, TyKind, - TypeBindingKind, + FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, TraitRef, Ty, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -138,10 +137,9 @@ fn future_trait_ref<'tcx>( fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'tcx>> { if let Some(segment) = trait_ref.path.segments.last() && let Some(args) = segment.args - && args.bindings.len() == 1 - && let binding = &args.bindings[0] - && binding.ident.name == sym::Output - && let TypeBindingKind::Equality { term: Term::Ty(output) } = binding.kind + && let [constraint] = args.constraints + && constraint.ident.name == sym::Output + && let Some(output) = constraint.ty() { return Some(output); } diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs index ee9f48d71ad8..691ecd57535a 100644 --- a/src/tools/clippy/clippy_lints/src/matches/mod.rs +++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs @@ -260,7 +260,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for wildcard enum matches using `_`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// New enum variants added by library updates can be missed. /// /// ### Known problems @@ -435,7 +435,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Correctness and readability. It's like having a wildcard pattern after /// matching all enum variants explicitly. /// @@ -861,7 +861,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of `Err(x)?`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// The `?` operator is designed to allow calls that /// can fail to be easily chained. For example, `foo()?.bar()` or /// `foo(bar()?)`. Because `Err(x)?` can't be used that way (it will diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index 6ac0705abb21..2f72e59834fa 100644 --- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -1,12 +1,17 @@ +use std::ops::ControlFlow; + use crate::FxHashSet; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{indent_of, snippet}; +use clippy_utils::ty::{for_each_top_level_late_bound_region, is_copy}; use clippy_utils::{get_attr, is_lint_allowed}; +use itertools::Itertools; +use rustc_ast::Mutability; use rustc_errors::{Applicability, Diag}; use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::{Arm, Expr, ExprKind, MatchSource}; use rustc_lint::{LateContext, LintContext}; -use rustc_middle::ty::{GenericArgKind, Ty}; +use rustc_middle::ty::{GenericArgKind, Region, RegionKind, Ty, TyCtxt, TypeVisitable, TypeVisitor}; use rustc_span::Span; use super::SIGNIFICANT_DROP_IN_SCRUTINEE; @@ -22,43 +27,34 @@ pub(super) fn check<'tcx>( return; } - if let Some((suggestions, message)) = has_significant_drop_in_scrutinee(cx, scrutinee, source) { - for found in suggestions { - span_lint_and_then(cx, SIGNIFICANT_DROP_IN_SCRUTINEE, found.found_span, message, |diag| { - set_diagnostic(diag, cx, expr, found); - let s = Span::new(expr.span.hi(), expr.span.hi(), expr.span.ctxt(), None); - diag.span_label(s, "temporary lives until here"); - for span in has_significant_drop_in_arms(cx, arms) { - diag.span_label(span, "another value with significant `Drop` created here"); - } - diag.note("this might lead to deadlocks or other unexpected behavior"); - }); - } + let (suggestions, message) = has_significant_drop_in_scrutinee(cx, scrutinee, source); + for found in suggestions { + span_lint_and_then(cx, SIGNIFICANT_DROP_IN_SCRUTINEE, found.found_span, message, |diag| { + set_diagnostic(diag, cx, expr, found); + let s = Span::new(expr.span.hi(), expr.span.hi(), expr.span.ctxt(), None); + diag.span_label(s, "temporary lives until here"); + for span in has_significant_drop_in_arms(cx, arms) { + diag.span_label(span, "another value with significant `Drop` created here"); + } + diag.note("this might lead to deadlocks or other unexpected behavior"); + }); } } fn set_diagnostic<'tcx>(diag: &mut Diag<'_, ()>, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, found: FoundSigDrop) { - if found.lint_suggestion == LintSuggestion::MoveAndClone { - // If our suggestion is to move and clone, then we want to leave it to the user to - // decide how to address this lint, since it may be that cloning is inappropriate. - // Therefore, we won't to emit a suggestion. - return; - } - let original = snippet(cx, found.found_span, ".."); let trailing_indent = " ".repeat(indent_of(cx, found.found_span).unwrap_or(0)); - let replacement = if found.lint_suggestion == LintSuggestion::MoveAndDerefToCopy { - format!("let value = *{original};\n{trailing_indent}") - } else if found.is_unit_return_val { - // If the return value of the expression to be moved is unit, then we don't need to - // capture the result in a temporary -- we can just replace it completely with `()`. - format!("{original};\n{trailing_indent}") - } else { - format!("let value = {original};\n{trailing_indent}") + let replacement = { + let (def_part, deref_part) = if found.is_unit_return_val { + ("", String::new()) + } else { + ("let value = ", "*".repeat(found.peel_ref_times)) + }; + format!("{def_part}{deref_part}{original};\n{trailing_indent}") }; - let suggestion_message = if found.lint_suggestion == LintSuggestion::MoveOnly { + let suggestion_message = if found.peel_ref_times == 0 { "try moving the temporary above the match" } else { "try moving the temporary above the match and create a copy" @@ -66,8 +62,11 @@ fn set_diagnostic<'tcx>(diag: &mut Diag<'_, ()>, cx: &LateContext<'tcx>, expr: & let scrutinee_replacement = if found.is_unit_return_val { "()".to_owned() - } else { + } else if found.peel_ref_times == 0 { "value".to_owned() + } else { + let ref_part = "&".repeat(found.peel_ref_times); + format!("({ref_part}value)") }; diag.multipart_suggestion( @@ -86,20 +85,18 @@ fn has_significant_drop_in_scrutinee<'tcx>( cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'tcx>, source: MatchSource, -) -> Option<(Vec, &'static str)> { +) -> (Vec, &'static str) { let mut helper = SigDropHelper::new(cx); let scrutinee = match (source, &scrutinee.kind) { (MatchSource::ForLoopDesugar, ExprKind::Call(_, [e])) => e, _ => scrutinee, }; - helper.find_sig_drop(scrutinee).map(|drops| { - let message = if source == MatchSource::Normal { - "temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression" - } else { - "temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression" - }; - (drops, message) - }) + let message = if source == MatchSource::Normal { + "temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression" + } else { + "temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression" + }; + (helper.find_sig_drop(scrutinee), message) } struct SigDropChecker<'a, 'tcx> { @@ -172,205 +169,248 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> { } } +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +enum SigDropHolder { + /// No values with significant drop present in this expression. + /// + /// Expressions that we've emited lints do not count. + None, + /// Some field in this expression references to values with significant drop. + /// + /// Example: `(1, &data.lock().field)`. + PackedRef, + /// The value of this expression references to values with significant drop. + /// + /// Example: `data.lock().field`. + DirectRef, + /// This expression should be moved out to avoid significant drop in scrutinee. + Moved, +} + +impl Default for SigDropHolder { + fn default() -> Self { + Self::None + } +} + struct SigDropHelper<'a, 'tcx> { cx: &'a LateContext<'tcx>, - is_chain_end: bool, - has_significant_drop: bool, - current_sig_drop: Option, - sig_drop_spans: Option>, - special_handling_for_binary_op: bool, + parent_expr: Option<&'tcx Expr<'tcx>>, + sig_drop_holder: SigDropHolder, + sig_drop_spans: Vec, sig_drop_checker: SigDropChecker<'a, 'tcx>, } -#[expect(clippy::enum_variant_names)] -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -enum LintSuggestion { - MoveOnly, - MoveAndDerefToCopy, - MoveAndClone, -} - -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] struct FoundSigDrop { found_span: Span, is_unit_return_val: bool, - lint_suggestion: LintSuggestion, + peel_ref_times: usize, } impl<'a, 'tcx> SigDropHelper<'a, 'tcx> { fn new(cx: &'a LateContext<'tcx>) -> SigDropHelper<'a, 'tcx> { SigDropHelper { cx, - is_chain_end: true, - has_significant_drop: false, - current_sig_drop: None, - sig_drop_spans: None, - special_handling_for_binary_op: false, + parent_expr: None, + sig_drop_holder: SigDropHolder::None, + sig_drop_spans: Vec::new(), sig_drop_checker: SigDropChecker::new(cx), } } - fn find_sig_drop(&mut self, match_expr: &'tcx Expr<'_>) -> Option> { + fn find_sig_drop(&mut self, match_expr: &'tcx Expr<'_>) -> Vec { self.visit_expr(match_expr); - // If sig drop spans is empty but we found a significant drop, it means that we didn't find - // a type that was trivially copyable as we moved up the chain after finding a significant - // drop, so move the entire scrutinee. - if self.has_significant_drop && self.sig_drop_spans.is_none() { - self.try_setting_current_suggestion(match_expr, true); - self.move_current_suggestion(); - } - - self.sig_drop_spans.take() + core::mem::take(&mut self.sig_drop_spans) } - fn replace_current_sig_drop( - &mut self, - found_span: Span, - is_unit_return_val: bool, - lint_suggestion: LintSuggestion, - ) { - self.current_sig_drop.replace(FoundSigDrop { + fn replace_current_sig_drop(&mut self, found_span: Span, is_unit_return_val: bool, peel_ref_times: usize) { + self.sig_drop_spans.clear(); + self.sig_drop_spans.push(FoundSigDrop { found_span, is_unit_return_val, - lint_suggestion, + peel_ref_times, }); } - /// This will try to set the current suggestion (so it can be moved into the suggestions vec - /// later). If `allow_move_and_clone` is false, the suggestion *won't* be set -- this gives us - /// an opportunity to look for another type in the chain that will be trivially copyable. - /// However, if we are at the end of the chain, we want to accept whatever is there. (The - /// suggestion won't actually be output, but the diagnostic message will be output, so the user - /// can determine the best way to handle the lint.) - fn try_setting_current_suggestion(&mut self, expr: &'tcx Expr<'_>, allow_move_and_clone: bool) { - if self.current_sig_drop.is_some() { - return; + fn try_move_sig_drop(&mut self, expr: &'tcx Expr<'_>, parent_expr: &'tcx Expr<'_>) { + if self.sig_drop_holder == SigDropHolder::Moved { + self.sig_drop_holder = SigDropHolder::None; } - let ty = self.cx.typeck_results().expr_ty(expr); - if ty.is_ref() { - // We checked that the type was ref, so builtin_deref will return Some, - // but let's avoid any chance of an ICE. - if let Some(ty) = ty.builtin_deref(true) { - if ty.is_trivially_pure_clone_copy() { - self.replace_current_sig_drop(expr.span, false, LintSuggestion::MoveAndDerefToCopy); - } else if allow_move_and_clone { - self.replace_current_sig_drop(expr.span, false, LintSuggestion::MoveAndClone); - } + + if self.sig_drop_holder == SigDropHolder::DirectRef { + self.sig_drop_holder = SigDropHolder::PackedRef; + self.try_move_sig_drop_direct_ref(expr, parent_expr); + } else if self.sig_drop_checker.is_sig_drop_expr(expr) { + // The values with significant drop can be moved to some other functions. For example, consider + // `drop(data.lock())`. We use `SigDropHolder::None` here to avoid emitting lints in such scenarios. + self.sig_drop_holder = SigDropHolder::None; + self.try_move_sig_drop_direct_ref(expr, parent_expr); + } + + if self.sig_drop_holder != SigDropHolder::None { + let parent_ty = self.cx.typeck_results().expr_ty(parent_expr); + if !ty_has_erased_regions(parent_ty) && !parent_expr.is_syntactic_place_expr() { + self.replace_current_sig_drop(parent_expr.span, parent_ty.is_unit(), 0); + self.sig_drop_holder = SigDropHolder::Moved; + } + + let (peel_ref_ty, peel_ref_times) = ty_peel_refs(parent_ty); + if !ty_has_erased_regions(peel_ref_ty) && is_copy(self.cx, peel_ref_ty) { + self.replace_current_sig_drop(parent_expr.span, peel_ref_ty.is_unit(), peel_ref_times); + self.sig_drop_holder = SigDropHolder::Moved; } - } else if ty.is_trivially_pure_clone_copy() { - self.replace_current_sig_drop(expr.span, false, LintSuggestion::MoveOnly); - } else if allow_move_and_clone { - self.replace_current_sig_drop(expr.span, false, LintSuggestion::MoveAndClone); } } - fn move_current_suggestion(&mut self) { - if let Some(current) = self.current_sig_drop.take() { - self.sig_drop_spans.get_or_insert_with(Vec::new).push(current); + fn try_move_sig_drop_direct_ref(&mut self, expr: &'tcx Expr<'_>, parent_expr: &'tcx Expr<'_>) { + let arg_idx = match parent_expr.kind { + ExprKind::MethodCall(_, receiver, exprs, _) => std::iter::once(receiver) + .chain(exprs.iter()) + .find_position(|ex| ex.hir_id == expr.hir_id) + .map(|(idx, _)| idx), + ExprKind::Call(_, exprs) => exprs + .iter() + .find_position(|ex| ex.hir_id == expr.hir_id) + .map(|(idx, _)| idx), + ExprKind::Binary(_, lhs, rhs) | ExprKind::AssignOp(_, lhs, rhs) => [lhs, rhs] + .iter() + .find_position(|ex| ex.hir_id == expr.hir_id) + .map(|(idx, _)| idx), + ExprKind::Unary(_, ex) => (ex.hir_id == expr.hir_id).then_some(0), + _ => { + // Here we assume that all other expressions create or propagate the reference to the value with + // significant drop. + self.sig_drop_holder = SigDropHolder::DirectRef; + return; + }, + }; + let Some(arg_idx) = arg_idx else { + return; + }; + + let fn_sig = if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(parent_expr.hir_id) { + self.cx.tcx.fn_sig(def_id).instantiate_identity() + } else { + return; + }; + + let input_re = if let Some(input_ty) = fn_sig.skip_binder().inputs().get(arg_idx) + && let rustc_middle::ty::Ref(input_re, _, _) = input_ty.kind() + { + input_re + } else { + return; + }; + + // Late bound lifetime parameters are not related to any constraints, so we can track them in a very + // simple manner. For other lifetime parameters, we give up and update the state to `PackedRef`. + let RegionKind::ReBound(_, input_re_bound) = input_re.kind() else { + self.sig_drop_holder = SigDropHolder::PackedRef; + return; + }; + let contains_input_re = |re_bound| { + if re_bound == input_re_bound { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + }; + + let output_ty = fn_sig.skip_binder().output(); + if let rustc_middle::ty::Ref(output_re, peel_ref_ty, _) = output_ty.kind() + && input_re == output_re + && for_each_top_level_late_bound_region(*peel_ref_ty, contains_input_re).is_continue() + { + // We're lucky! The output type is still a direct reference to the value with significant drop. + self.sig_drop_holder = SigDropHolder::DirectRef; + } else if for_each_top_level_late_bound_region(output_ty, contains_input_re).is_continue() { + // The lifetime to the value with significant drop goes away. So we can emit a lint that suggests to + // move the expression out. + self.replace_current_sig_drop(parent_expr.span, output_ty.is_unit(), 0); + self.sig_drop_holder = SigDropHolder::Moved; + } else { + // TODO: The lifetime is still there but it's for a inner type. For instance, consider + // `Some(&mutex.lock().field)`, which has a type of `Option<&u32>`. How to address this scenario? + self.sig_drop_holder = SigDropHolder::PackedRef; + } + } +} + +fn ty_peel_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) { + let mut n = 0; + while let rustc_middle::ty::Ref(_, new_ty, Mutability::Not) = ty.kind() { + ty = *new_ty; + n += 1; + } + (ty, n) +} + +fn ty_has_erased_regions(ty: Ty<'_>) -> bool { + struct V; + + impl<'tcx> TypeVisitor> for V { + type Result = ControlFlow<()>; + + fn visit_region(&mut self, region: Region<'tcx>) -> Self::Result { + if region.is_erased() { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } } } - fn visit_exprs_for_binary_ops( - &mut self, - left: &'tcx Expr<'_>, - right: &'tcx Expr<'_>, - is_unit_return_val: bool, - span: Span, - ) { - self.special_handling_for_binary_op = true; - self.visit_expr(left); - self.visit_expr(right); - - // If either side had a significant drop, suggest moving the entire scrutinee to avoid - // unnecessary copies and to simplify cases where both sides have significant drops. - if self.has_significant_drop { - self.replace_current_sig_drop(span, is_unit_return_val, LintSuggestion::MoveOnly); - } - - self.special_handling_for_binary_op = false; - } + ty.visit_with(&mut V).is_break() } impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { fn visit_expr(&mut self, ex: &'tcx Expr<'_>) { - if !self.is_chain_end && self.sig_drop_checker.is_sig_drop_expr(ex) { - self.has_significant_drop = true; + // We've emited a lint on some neighborhood expression. That lint will suggest to move out the + // _parent_ expression (not the expression itself). Since we decide to move out the parent + // expression, it is pointless to continue to process the current expression. + if self.sig_drop_holder == SigDropHolder::Moved { return; } - self.is_chain_end = false; + + // These states are of neighborhood expressions. We save and clear them here, and we'll later merge + // the states of the current expression with them at the end of the method. + let sig_drop_holder_before = core::mem::take(&mut self.sig_drop_holder); + let sig_drop_spans_before = core::mem::take(&mut self.sig_drop_spans); + let parent_expr_before = self.parent_expr.replace(ex); match ex.kind { - ExprKind::MethodCall(_, expr, ..) => { - self.visit_expr(expr); - } - ExprKind::Binary(_, left, right) => { - self.visit_exprs_for_binary_ops(left, right, false, ex.span); - } - ExprKind::Assign(left, right, _) | ExprKind::AssignOp(_, left, right) => { - self.visit_exprs_for_binary_ops(left, right, true, ex.span); - } - ExprKind::Tup(exprs) => { - for expr in exprs { - self.visit_expr(expr); - if self.has_significant_drop { - // We may have not have set current_sig_drop if all the suggestions were - // MoveAndClone, so add this tuple item's full expression in that case. - if self.current_sig_drop.is_none() { - self.try_setting_current_suggestion(expr, true); - } + // Skip blocks because values in blocks will be dropped as usual. + ExprKind::Block(..) => (), + _ => walk_expr(self, ex), + } - // Now we are guaranteed to have something, so add it to the final vec. - self.move_current_suggestion(); - } - // Reset `has_significant_drop` after each tuple expression so we can look for - // additional cases. - self.has_significant_drop = false; - } - if self.sig_drop_spans.is_some() { - self.has_significant_drop = true; - } - } - ExprKind::Array(..) | - ExprKind::Call(..) | - ExprKind::Unary(..) | - ExprKind::If(..) | - ExprKind::Match(..) | - ExprKind::Field(..) | - ExprKind::Index(..) | - ExprKind::Ret(..) | - ExprKind::Become(..) | - ExprKind::Repeat(..) | - ExprKind::Yield(..) => walk_expr(self, ex), - ExprKind::AddrOf(_, _, _) | - ExprKind::Block(_, _) | - ExprKind::Break(_, _) | - ExprKind::Cast(_, _) | - // Don't want to check the closure itself, only invocation, which is covered by MethodCall - ExprKind::Closure { .. } | - ExprKind::ConstBlock(_) | - ExprKind::Continue(_) | - ExprKind::DropTemps(_) | - ExprKind::Err(_) | - ExprKind::InlineAsm(_) | - ExprKind::OffsetOf(_, _) | - ExprKind::Let(_) | - ExprKind::Lit(_) | - ExprKind::Loop(_, _, _, _) | - ExprKind::Path(_) | - ExprKind::Struct(_, _, _) | - ExprKind::Type(_, _) => { - return; + if let Some(parent_ex) = parent_expr_before { + match parent_ex.kind { + ExprKind::Assign(lhs, _, _) | ExprKind::AssignOp(_, lhs, _) + if lhs.hir_id == ex.hir_id && self.sig_drop_holder == SigDropHolder::Moved => + { + // Never move out only the assignee. Instead, we should always move out the whole assigment. + self.replace_current_sig_drop(parent_ex.span, true, 0); + }, + _ => { + self.try_move_sig_drop(ex, parent_ex); + }, } } - // Once a significant temporary has been found, we need to go back up at least 1 level to - // find the span to extract for replacement, so the temporary gets dropped. However, for - // binary ops, we want to move the whole scrutinee so we avoid unnecessary copies and to - // simplify cases where both sides have significant drops. - if self.has_significant_drop && !self.special_handling_for_binary_op { - self.try_setting_current_suggestion(ex, false); + self.sig_drop_holder = std::cmp::max(self.sig_drop_holder, sig_drop_holder_before); + + // We do not need those old spans in neighborhood expressions if we emit a lint that suggests to + // move out the _parent_ expression (i.e., `self.sig_drop_holder == SigDropHolder::Moved`). + if self.sig_drop_holder != SigDropHolder::Moved { + let mut sig_drop_spans = sig_drop_spans_before; + sig_drop_spans.append(&mut self.sig_drop_spans); + self.sig_drop_spans = sig_drop_spans; } + + self.parent_expr = parent_expr_before; } } diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs index 6c9bdcff8262..7f6b666e434e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs @@ -1,8 +1,12 @@ +use std::iter::once; + use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; use clippy_utils::{get_expr_use_or_unification_node, is_res_lang_ctor, path_res, std_or_core}; use rustc_errors::Applicability; +use rustc_hir::def_id::DefId; +use rustc_hir::hir_id::HirId; use rustc_hir::LangItem::{OptionNone, OptionSome}; use rustc_hir::{Expr, ExprKind, Node}; use rustc_lint::LateContext; @@ -25,7 +29,29 @@ impl IterType { } } -pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) { +fn is_arg_ty_unified_in_fn<'tcx>( + cx: &LateContext<'tcx>, + fn_id: DefId, + arg_id: HirId, + args: impl IntoIterator>, +) -> bool { + let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity(); + let arg_id_in_args = args.into_iter().position(|e| e.hir_id == arg_id).unwrap(); + let arg_ty_in_args = fn_sig.input(arg_id_in_args).skip_binder(); + + cx.tcx.predicates_of(fn_id).predicates.iter().any(|(clause, _)| { + clause + .as_projection_clause() + .and_then(|p| p.map_bound(|p| p.term.as_type()).transpose()) + .is_some_and(|ty| ty.skip_binder() == arg_ty_in_args) + }) || fn_sig + .inputs() + .iter() + .enumerate() + .any(|(i, ty)| i != arg_id_in_args && ty.skip_binder().walk().any(|arg| arg.as_type() == Some(arg_ty_in_args))) +} + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method_name: &str, recv: &'tcx Expr<'tcx>) { let item = match recv.kind { ExprKind::Array([]) => None, ExprKind::Array([e]) => Some(e), @@ -43,6 +69,25 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re let is_unified = match get_expr_use_or_unification_node(cx.tcx, expr) { Some((Node::Expr(parent), child_id)) => match parent.kind { ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id == child_id => false, + ExprKind::Call( + Expr { + kind: ExprKind::Path(path), + hir_id, + .. + }, + args, + ) => cx + .typeck_results() + .qpath_res(path, *hir_id) + .opt_def_id() + .filter(|fn_id| cx.tcx.def_kind(fn_id).is_fn_like()) + .is_some_and(|fn_id| is_arg_ty_unified_in_fn(cx, fn_id, child_id, args)), + ExprKind::MethodCall(_name, recv, args, _span) => is_arg_ty_unified_in_fn( + cx, + cx.typeck_results().type_dependent_def_id(parent.hir_id).unwrap(), + child_id, + once(recv).chain(args.iter()), + ), ExprKind::If(_, _, _) | ExprKind::Match(_, _, _) | ExprKind::Closure(_) diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 9d67aa233797..75a86c0c8344 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -257,7 +257,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s. /// - /// ### Why is this bad? + /// ### Why restrict this? /// It is better to handle the `None` or `Err` case, /// or at least call `.expect(_)` with a more helpful message. Still, for a lot of /// quick-and-dirty code, `unwrap` is a good choice, which is why this lint is @@ -333,7 +333,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Usually it is better to handle the `None` or `Err` case. /// Still, for a lot of quick-and-dirty code, `expect` is a good choice, which is why /// this lint is `Allow` by default. @@ -1029,8 +1029,8 @@ declare_clippy_lint! { /// (`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified /// function syntax instead (e.g., `Rc::clone(foo)`). /// - /// ### Why is this bad? - /// Calling '.clone()' on an Rc, Arc, or Weak + /// ### Why restrict this? + /// Calling `.clone()` on an `Rc`, `Arc`, or `Weak` /// can obscure the fact that only the pointer is being cloned, not the underlying /// data. /// @@ -1051,7 +1051,7 @@ declare_clippy_lint! { #[clippy::version = "pre 1.29.0"] pub CLONE_ON_REF_PTR, restriction, - "using 'clone' on a ref-counted pointer" + "using `clone` on a ref-counted pointer" } declare_clippy_lint! { @@ -1359,7 +1359,7 @@ declare_clippy_lint! { /// Checks for usage of `.get().unwrap()` (or /// `.get_mut().unwrap`) on a standard library type which implements `Index` /// - /// ### Why is this bad? + /// ### Why restrict this? /// Using the Index trait (`[]`) is more clear and more /// concise. /// @@ -1743,7 +1743,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for `FileType::is_file()`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// When people testing a file type with `FileType::is_file` /// they are testing whether a path is something they can get bytes from. But /// `is_file` doesn't cover special file types in unix-like systems, and doesn't cover @@ -2688,8 +2688,9 @@ declare_clippy_lint! { /// ### What it does /// Checks for instances of `map_err(|_| Some::Enum)` /// - /// ### Why is this bad? - /// This `map_err` throws away the original error rather than allowing the enum to contain and report the cause of the error + /// ### Why restrict this? + /// This `map_err` throws away the original error rather than allowing the enum to + /// contain and report the cause of the error. /// /// ### Example /// Before: @@ -3145,7 +3146,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of File::read_to_end and File::read_to_string. /// - /// ### Why is this bad? + /// ### Why restrict this? /// `fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values. /// See also: [fs::read docs](https://doc.rust-lang.org/std/fs/fn.read.html), [fs::read_to_string docs](https://doc.rust-lang.org/std/fs/fn.read_to_string.html) /// diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs index efec9dd716dc..ca331f3e7568 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -59,8 +59,8 @@ pub(super) fn check<'tcx>( }; let map = cx.tcx.hir(); - let body = map.body(map.body_owned_by(map.enclosing_body_owner(expr.hir_id))); - reference_visitor.visit_body(body); + let body = map.body_owned_by(map.enclosing_body_owner(expr.hir_id)); + reference_visitor.visit_body(&body); if reference_visitor.found_reference { return; diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs index 7431dc1cf0b1..d1300dd43c28 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs @@ -38,7 +38,7 @@ pub fn check_for_loop_iter( ) -> bool { if let Some(grandparent) = get_parent_expr(cx, expr).and_then(|parent| get_parent_expr(cx, parent)) && let Some(ForLoop { pat, body, .. }) = ForLoop::hir(grandparent) - && let (clone_or_copy_needed, addr_of_exprs) = clone_or_copy_needed(cx, pat, body) + && let (clone_or_copy_needed, references_to_binding) = clone_or_copy_needed(cx, pat, body) && !clone_or_copy_needed && let Some(receiver_snippet) = snippet_opt(cx, receiver.span) { @@ -123,14 +123,12 @@ pub fn check_for_loop_iter( Applicability::MachineApplicable }; diag.span_suggestion(expr.span, "use", snippet, applicability); - for addr_of_expr in addr_of_exprs { - match addr_of_expr.kind { - ExprKind::AddrOf(_, _, referent) => { - let span = addr_of_expr.span.with_hi(referent.span.lo()); - diag.span_suggestion(span, "remove this `&`", "", applicability); - }, - _ => unreachable!(), - } + if !references_to_binding.is_empty() { + diag.multipart_suggestion( + "remove any references to the binding", + references_to_binding, + applicability, + ); } }, ); diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs index 34d7b9acbe4b..1a55b7160fb1 100644 --- a/src/tools/clippy/clippy_lints/src/methods/utils.rs +++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs @@ -9,6 +9,7 @@ use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::sym; +use rustc_span::Span; pub(super) fn derefs_to_slice<'tcx>( cx: &LateContext<'tcx>, @@ -96,15 +97,15 @@ pub(super) fn clone_or_copy_needed<'tcx>( cx: &LateContext<'tcx>, pat: &Pat<'tcx>, body: &'tcx Expr<'tcx>, -) -> (bool, Vec<&'tcx Expr<'tcx>>) { +) -> (bool, Vec<(Span, String)>) { let mut visitor = CloneOrCopyVisitor { cx, binding_hir_ids: pat_bindings(pat), clone_or_copy_needed: false, - addr_of_exprs: Vec::new(), + references_to_binding: Vec::new(), }; visitor.visit_expr(body); - (visitor.clone_or_copy_needed, visitor.addr_of_exprs) + (visitor.clone_or_copy_needed, visitor.references_to_binding) } /// Returns a vector of all `HirId`s bound by the pattern. @@ -127,7 +128,7 @@ struct CloneOrCopyVisitor<'cx, 'tcx> { cx: &'cx LateContext<'tcx>, binding_hir_ids: Vec, clone_or_copy_needed: bool, - addr_of_exprs: Vec<&'tcx Expr<'tcx>>, + references_to_binding: Vec<(Span, String)>, } impl<'cx, 'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'cx, 'tcx> { @@ -142,8 +143,11 @@ impl<'cx, 'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'cx, 'tcx> { if self.is_binding(expr) { if let Some(parent) = get_parent_expr(self.cx, expr) { match parent.kind { - ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, _) => { - self.addr_of_exprs.push(parent); + ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, referent) => { + if !parent.span.from_expansion() { + self.references_to_binding + .push((parent.span.until(referent.span), String::new())); + } return; }, ExprKind::MethodCall(.., args, _) => { diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs index c6b7f5b0ce27..e43b712021ae 100644 --- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs +++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs @@ -12,14 +12,13 @@ use std::borrow::Cow; declare_clippy_lint! { /// ### What it does - /// Checks for idents which comprise of a single letter. + /// Checks for identifiers which consist of a single character (or fewer than the configured threshold). /// /// Note: This lint can be very noisy when enabled; it may be desirable to only enable it /// temporarily. /// - /// ### Why is this bad? - /// In many cases it's not, but at times it can severely hinder readability. Some codebases may - /// wish to disallow this to improve readability. + /// ### Why restrict this? + /// To improve readability by requiring that every variable has a name more specific than a single letter can be. /// /// ### Example /// ```rust,ignore diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs index 2f5499d7656f..fedcfd11fdcc 100644 --- a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs +++ b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs @@ -23,7 +23,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for structure field patterns bound to wildcards. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Using `..` instead is shorter and leaves the focus on /// the fields that are actually bound. /// @@ -138,7 +138,7 @@ declare_clippy_lint! { /// To enforce unseparated literal suffix style, /// see the `separated_literal_suffix` lint. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Suffix style should be consistent. /// /// ### Example @@ -166,7 +166,7 @@ declare_clippy_lint! { /// To enforce separated literal suffix style, /// see the `unseparated_literal_suffix` lint. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Suffix style should be consistent. /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/missing_assert_message.rs b/src/tools/clippy/clippy_lints/src/missing_assert_message.rs index 04df7b7a7e5a..dd98352da860 100644 --- a/src/tools/clippy/clippy_lints/src/missing_assert_message.rs +++ b/src/tools/clippy/clippy_lints/src/missing_assert_message.rs @@ -10,7 +10,7 @@ declare_clippy_lint! { /// ### What it does /// Checks assertions without a custom panic message. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Without a good custom message, it'd be hard to understand what went wrong when the assertion fails. /// A good custom message should be more about why the failure of the assertion is problematic /// and not what is failed because the assertion already conveys that. diff --git a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs index c29e46b941c6..752723a0c68e 100644 --- a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs @@ -21,7 +21,7 @@ declare_clippy_lint! { /// Checks for repeated slice indexing without asserting beforehand that the length /// is greater than the largest index used to index into the slice. /// - /// ### Why is this bad? + /// ### Why restrict this? /// In the general case where the compiler does not have a lot of information /// about the length of a slice, indexing it repeatedly will generate a bounds check /// for every single index. diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 2fb784dae1cd..ca344dc5c810 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -20,9 +20,9 @@ use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does - /// Warns if there is missing doc for any private documentable item + /// Warns if there is missing documentation for any private documentable item. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Doc is good. *rustc* has a `MISSING_DOCS` /// allowed-by-default lint for /// public members, but has no way to enforce documentation of private items. diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index c6a76478806a..33a14d8b7fed 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -10,13 +10,16 @@ declare_clippy_lint! { /// It lints if an exported function, method, trait method with default impl, /// or trait method impl is not `#[inline]`. /// - /// ### Why is this bad? - /// In general, it is not. Functions can be inlined across - /// crates when that's profitable as long as any form of LTO is used. When LTO is disabled, - /// functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates - /// might intend for most of the methods in their public API to be able to be inlined across - /// crates even when LTO is disabled. For these types of crates, enabling this lint might make - /// sense. It allows the crate to require all exported methods to be `#[inline]` by default, and + /// ### Why restrict this? + /// When a function is not marked `#[inline]`, it is not + /// [a “small” candidate for automatic inlining][small], and LTO is not in use, then it is not + /// possible for the function to be inlined into the code of any crate other than the one in + /// which it is defined. Depending on the role of the function and the relationship of the crates, + /// this could significantly reduce performance. + /// + /// Certain types of crates might intend for most of the methods in their public API to be able + /// to be inlined across crates even when LTO is disabled. + /// This lint allows those crates to require all exported methods to be `#[inline]` by default, and /// then opt out for specific methods where this might not make sense. /// /// ### Example @@ -51,6 +54,8 @@ declare_clippy_lint! { /// fn def_bar() {} // missing #[inline] /// } /// ``` + /// + /// [small]: https://github.com/rust-lang/rust/pull/116505 #[clippy::version = "pre 1.29.0"] pub MISSING_INLINE_IN_PUBLIC_ITEMS, restriction, diff --git a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs index 6f844bc646a2..85029a5e6a0d 100644 --- a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs +++ b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs @@ -10,16 +10,16 @@ use rustc_session::declare_lint_pass; declare_clippy_lint! { /// ### What it does /// Checks if a provided method is used implicitly by a trait - /// implementation. A usage example would be a wrapper where every method - /// should perform some operation before delegating to the inner type's /// implementation. /// + /// ### Why restrict this? + /// To ensure that a certain implementation implements every method; for example, + /// a wrapper type where every method should delegate to the corresponding method of + /// the inner type's implementation. + /// /// This lint should typically be enabled on a specific trait `impl` item /// rather than globally. /// - /// ### Why is this bad? - /// Indicates that a method is missing. - /// /// ### Example /// ```no_run /// trait Trait { diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs index 181351910db6..9c5a8a0cfcdf 100644 --- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs @@ -12,9 +12,10 @@ declare_clippy_lint! { /// whether the read occurs before or after the write depends on the evaluation /// order of sub-expressions. /// - /// ### Why is this bad? - /// It is often confusing to read. As described [here](https://doc.rust-lang.org/reference/expressions.html?highlight=subexpression#evaluation-order-of-operands), - /// the operands of these expressions are evaluated before applying the effects of the expression. + /// ### Why restrict this? + /// While [the evaluation order of sub-expressions] is fully specified in Rust, + /// it still may be confusing to read an expression where the evaluation order + /// affects its behavior. /// /// ### Known problems /// Code which intentionally depends on the evaluation @@ -40,6 +41,8 @@ declare_clippy_lint! { /// }; /// let a = tmp + x; /// ``` + /// + /// [order]: (https://doc.rust-lang.org/reference/expressions.html?highlight=subexpression#evaluation-order-of-operands) #[clippy::version = "pre 1.29.0"] pub MIXED_READ_WRITE_IN_EXPRESSION, restriction, diff --git a/src/tools/clippy/clippy_lints/src/module_style.rs b/src/tools/clippy/clippy_lints/src/module_style.rs index 6c031c081750..305499f9da43 100644 --- a/src/tools/clippy/clippy_lints/src/module_style.rs +++ b/src/tools/clippy/clippy_lints/src/module_style.rs @@ -10,9 +10,9 @@ use std::path::{Component, Path}; declare_clippy_lint! { /// ### What it does - /// Checks that module layout uses only self named module files, bans `mod.rs` files. + /// Checks that module layout uses only self named module files; bans `mod.rs` files. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Having multiple module layout styles in a project can be confusing. /// /// ### Example @@ -41,7 +41,7 @@ declare_clippy_lint! { /// ### What it does /// Checks that module layout uses only `mod.rs` files. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Having multiple module layout styles in a project can be confusing. /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 5306205aed7e..5b4ef852f0d9 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::visitors::{for_each_expr_with_closures, Descend, Visitable}; use core::ops::ControlFlow::Continue; use hir::def::{DefKind, Res}; -use hir::{BlockCheckMode, ExprKind, Safety, QPath, UnOp}; +use hir::{BlockCheckMode, ExprKind, QPath, Safety, UnOp}; use rustc_ast::Mutability; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; @@ -15,7 +15,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for `unsafe` blocks that contain more than one unsafe operation. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Combined with `undocumented_unsafe_blocks`, /// this lint ensures that each unsafe operation must be independently justified. /// Combined with `unused_unsafe`, this lint also ensures diff --git a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs index 7ecc86176942..853e476a006c 100644 --- a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs +++ b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs @@ -14,7 +14,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of `Mutex` where an atomic will do. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Using a mutex just to make access to a plain bool or /// reference sequential is shooting flies with cannons. /// `std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs index f9ee4a3dc93a..e1866eaa18a7 100644 --- a/src/tools/clippy/clippy_lints/src/needless_bool.rs +++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs @@ -6,8 +6,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; use clippy_utils::{ - higher, is_else_clause, is_expn_of, is_parent_stmt, peel_blocks, peel_blocks_with_stmt, span_extract_comment, - SpanlessEq, + higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt, peel_blocks, peel_blocks_with_stmt, + span_extract_comment, SpanlessEq, }; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; @@ -121,14 +121,7 @@ fn condition_needs_parentheses(e: &Expr<'_>) -> bool { | ExprKind::Type(i, _) | ExprKind::Index(i, _, _) = inner.kind { - if matches!( - i.kind, - ExprKind::Block(..) - | ExprKind::ConstBlock(..) - | ExprKind::If(..) - | ExprKind::Loop(..) - | ExprKind::Match(..) - ) { + if is_block_like(i) { return true; } inner = i; diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index daf166bad90d..4f99eaa40c29 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -129,7 +129,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> { } } - fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { + fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'_>) { if self.possible_borrowers.last().map_or(false, |&(local_def_id, _)| { local_def_id == cx.tcx.hir().body_owner_def_id(body.id()) }) { @@ -311,7 +311,7 @@ fn is_mixed_projection_predicate<'tcx>( ) -> bool { let generics = cx.tcx.generics_of(callee_def_id); // The predicate requires the projected type to equal a type parameter from the parent context. - if let Some(term_ty) = projection_predicate.term.ty() + if let Some(term_ty) = projection_predicate.term.as_type() && let ty::Param(term_param_ty) = term_ty.kind() && (term_param_ty.index as usize) < generics.parent_count { @@ -370,7 +370,7 @@ fn replace_types<'tcx>( if replaced.insert(param_ty.index) { for projection_predicate in projection_predicates { if projection_predicate.projection_term.self_ty() == param_ty.to_ty(cx.tcx) - && let Some(term_ty) = projection_predicate.term.ty() + && let Some(term_ty) = projection_predicate.term.as_type() && let ty::Param(term_param_ty) = term_ty.kind() { let projection = projection_predicate diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs index 7b26235291a5..eacfe9ff328d 100644 --- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs +++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs @@ -98,6 +98,10 @@ struct SimilarNamesLocalVisitor<'a, 'tcx> { impl<'a, 'tcx> SimilarNamesLocalVisitor<'a, 'tcx> { fn check_single_char_names(&self) { + if self.single_char_names.last().map(Vec::len) == Some(0) { + return; + } + let num_single_char_names = self.single_char_names.iter().flatten().count(); let threshold = self.lint.single_char_binding_names_threshold; if num_single_char_names as u64 > threshold { diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index b3ff5ecae862..8b8aabe7accc 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -221,7 +221,7 @@ pub struct OnlyUsedInRecursion { } impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { - fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'tcx>) { + fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) { if body.value.span.from_expansion() { return; } @@ -350,7 +350,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { } } - fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'tcx>) { + fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) { if self.entered_body == Some(body.value.hir_id) { self.entered_body = None; self.params.flag_for_linting(); diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs index e002429e3a47..48a442705b29 100644 --- a/src/tools/clippy/clippy_lints/src/operators/mod.rs +++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs @@ -70,7 +70,7 @@ declare_clippy_lint! { /// Known safe built-in types like `Wrapping` or `Saturating`, floats, operations in constant /// environments, allowed types and non-constant operations that won't overflow are ignored. /// - /// ### Why is this bad? + /// ### Why restrict this? /// For integers, overflow will trigger a panic in debug builds or wrap the result in /// release mode; division by zero will cause a panic in either mode. As a result, it is /// desirable to explicitly call checked, wrapping or saturating arithmetic methods. @@ -100,7 +100,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for float arithmetic. /// - /// ### Why is this bad? + /// ### Why restrict this? /// For some embedded systems or kernel development, it /// can be useful to rule out floating-point numbers. /// @@ -502,7 +502,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for division of integers /// - /// ### Why is this bad? + /// ### Why restrict this? /// When outside of some very specific algorithms, /// integer division is very often a mistake because it discards the /// remainder. @@ -596,7 +596,7 @@ declare_clippy_lint! { /// value and constant, except in functions called `*eq*` (which probably /// implement equality for a type involving floats). /// - /// ### Why is this bad? + /// ### Why restrict this? /// Floating point calculations are usually imprecise, so /// asking if two values are *exactly* equal is asking for trouble. For a good /// guide on what to do, see [the floating point @@ -653,8 +653,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for modulo arithmetic. /// - /// ### Why is this bad? - /// The results of modulo (%) operation might differ + /// ### Why restrict this? + /// The results of modulo (`%`) operation might differ /// depending on the language, when negative numbers are involved. /// If you interop with different languages it might be beneficial /// to double check all places that use modulo arithmetic. @@ -868,11 +868,11 @@ impl<'tcx> LateLintPass<'tcx> for Operators { self.arithmetic_context.expr_post(e.hir_id); } - fn check_body(&mut self, cx: &LateContext<'tcx>, b: &'tcx Body<'_>) { + fn check_body(&mut self, cx: &LateContext<'tcx>, b: &Body<'_>) { self.arithmetic_context.enter_body(cx, b); } - fn check_body_post(&mut self, cx: &LateContext<'tcx>, b: &'tcx Body<'_>) { + fn check_body_post(&mut self, cx: &LateContext<'tcx>, b: &Body<'_>) { self.arithmetic_context.body_post(cx, b); } } diff --git a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs index f821a4efee7b..806638c0505b 100644 --- a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs +++ b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs @@ -13,9 +13,9 @@ use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does - /// Checks for usage of `panic!` or assertions in a function of type result. + /// Checks for usage of `panic!` or assertions in a function whose return type is `Result`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// For some codebases, it is desirable for functions of type result to return an error instead of crashing. Hence panicking macros should be avoided. /// /// ### Known problems diff --git a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs index 75066c1f0d2e..80ef761906e0 100644 --- a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs +++ b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs @@ -14,8 +14,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of `panic!`. /// - /// ### Why is this bad? - /// `panic!` will stop the execution of the executable. + /// ### Why restrict this? + /// This macro, or panics in general, may be unwanted in production code. /// /// ### Example /// ```no_run @@ -31,8 +31,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of `unimplemented!`. /// - /// ### Why is this bad? - /// This macro should not be present in production code. + /// ### Why restrict this? + /// This macro, or panics in general, may be unwanted in production code. /// /// ### Example /// ```no_run @@ -48,9 +48,9 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of `todo!`. /// - /// ### Why is this bad? - /// The `todo!` macro is often used for unfinished code, and it causes - /// code to panic. It should not be present in production code. + /// ### Why restrict this? + /// The `todo!` macro indicates the presence of unfinished code, + /// so it should not be present in production code. /// /// ### Example /// ```no_run @@ -70,8 +70,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of `unreachable!`. /// - /// ### Why is this bad? - /// This macro can cause code to panic. + /// ### Why restrict this? + /// This macro, or panics in general, may be unwanted in production code. /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/partial_pub_fields.rs b/src/tools/clippy/clippy_lints/src/partial_pub_fields.rs index ffa403e27ca3..2d20cbea698f 100644 --- a/src/tools/clippy/clippy_lints/src/partial_pub_fields.rs +++ b/src/tools/clippy/clippy_lints/src/partial_pub_fields.rs @@ -5,15 +5,16 @@ use rustc_session::declare_lint_pass; declare_clippy_lint! { /// ### What it does - /// Checks whether partial fields of a struct are public. + /// Checks whether some but not all fields of a `struct` are public. /// /// Either make all fields of a type public, or make none of them public /// - /// ### Why is this bad? + /// ### Why restrict this? /// Most types should either be: /// * Abstract data types: complex objects with opaque implementation which guard - /// interior invariants and expose intentionally limited API to the outside world. - /// * Data: relatively simple objects which group a bunch of related attributes together. + /// interior invariants and expose intentionally limited API to the outside world. + /// * Data: relatively simple objects which group a bunch of related attributes together, + /// but have no invariants. /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs index 44db061b8bee..9661a57b8b95 100644 --- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs +++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs @@ -30,9 +30,8 @@ declare_clippy_lint! { /// this lint can still be used to highlight areas of interest and ensure a good understanding /// of ownership semantics. /// - /// ### Why is this bad? - /// It isn't bad in general. But in some contexts it can be desirable - /// because it increases ownership hints in the code, and will guard against some changes + /// ### Why restrict this? + /// It increases ownership hints in the code, and will guard against some changes /// in ownership. /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 38580dc58226..02c05e0aaf9c 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -188,7 +188,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { } } - fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { + fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) { let hir = cx.tcx.hir(); let mut parents = hir.parent_iter(body.value.hir_id); let (item_id, sig, is_trait_item) = match parents.next() { @@ -525,7 +525,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>( }) } -fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Option<&'tcx Body<'_>>) { +fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Option<&Body<'tcx>>) { if let FnRetTy::Return(ty) = sig.decl.output && let Some((out, Mutability::Mut, _)) = get_ref_lm(ty) { @@ -559,7 +559,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio } #[expect(clippy::too_many_lines)] -fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args: &[PtrArg<'tcx>]) -> Vec { +fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[PtrArg<'tcx>]) -> Vec { struct V<'cx, 'tcx> { cx: &'cx LateContext<'tcx>, /// Map from a local id to which argument it came from (index into `Self::args` and diff --git a/src/tools/clippy/clippy_lints/src/pub_use.rs b/src/tools/clippy/clippy_lints/src/pub_use.rs index c0e999e76ef2..ab8f8a1689dc 100644 --- a/src/tools/clippy/clippy_lints/src/pub_use.rs +++ b/src/tools/clippy/clippy_lints/src/pub_use.rs @@ -5,13 +5,11 @@ use rustc_session::declare_lint_pass; declare_clippy_lint! { /// ### What it does - /// /// Restricts the usage of `pub use ...` /// - /// ### Why is this bad? - /// - /// `pub use` is usually fine, but a project may wish to limit `pub use` instances to prevent - /// unintentional exports or to encourage placing exported items directly in public modules + /// ### Why restrict this? + /// A project may wish to limit `pub use` instances to prevent + /// unintentional exports, or to encourage placing exported items directly in public modules. /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs index 1f1ce147ca24..7cf98ad9e09a 100644 --- a/src/tools/clippy/clippy_lints/src/question_mark.rs +++ b/src/tools/clippy/clippy_lints/src/question_mark.rs @@ -370,11 +370,11 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark { } } - fn check_body(&mut self, _: &LateContext<'tcx>, _: &'tcx Body<'tcx>) { + fn check_body(&mut self, _: &LateContext<'tcx>, _: &Body<'tcx>) { self.try_block_depth_stack.push(0); } - fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &'tcx Body<'tcx>) { + fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &Body<'tcx>) { self.try_block_depth_stack.pop(); } diff --git a/src/tools/clippy/clippy_lints/src/question_mark_used.rs b/src/tools/clippy/clippy_lints/src/question_mark_used.rs index ddfc53083c46..f5e6cb804da1 100644 --- a/src/tools/clippy/clippy_lints/src/question_mark_used.rs +++ b/src/tools/clippy/clippy_lints/src/question_mark_used.rs @@ -9,7 +9,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for expressions that use the question mark operator and rejects them. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Sometimes code wants to avoid the question mark operator because for instance a local /// block requires a macro to re-throw errors to attach additional information to the /// error. diff --git a/src/tools/clippy/clippy_lints/src/raw_strings.rs b/src/tools/clippy/clippy_lints/src/raw_strings.rs index 7e71f48c6d9a..3a0042454592 100644 --- a/src/tools/clippy/clippy_lints/src/raw_strings.rs +++ b/src/tools/clippy/clippy_lints/src/raw_strings.rs @@ -15,8 +15,10 @@ declare_clippy_lint! { /// ### What it does /// Checks for raw string literals where a string literal can be used instead. /// - /// ### Why is this bad? - /// It's just unnecessary, but there are many cases where using a raw string literal is more + /// ### Why restrict this? + /// For consistent style by using simpler string literals whenever possible. + /// + /// However, there are many cases where using a raw string literal is more /// idiomatic than a string literal, so it's opt-in. /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index c99b657c23a2..7f87d18e5023 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -46,7 +46,7 @@ declare_clippy_lint! { /// Checks for slicing expressions which are equivalent to dereferencing the /// value. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Some people may prefer to dereference rather than slice. /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs index 11b95ee3a54c..81556f396141 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs @@ -11,7 +11,7 @@ declare_clippy_lint! { /// ### What it does /// Warns about needless / redundant type annotations. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Code without type annotations is shorter and in most cases /// more idiomatic and easier to modify. /// diff --git a/src/tools/clippy/clippy_lints/src/ref_patterns.rs b/src/tools/clippy/clippy_lints/src/ref_patterns.rs index 607a0740b843..467038523b49 100644 --- a/src/tools/clippy/clippy_lints/src/ref_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/ref_patterns.rs @@ -6,9 +6,11 @@ use rustc_session::declare_lint_pass; declare_clippy_lint! { /// ### What it does /// Checks for usages of the `ref` keyword. - /// ### Why is this bad? + /// + /// ### Why restrict this? /// The `ref` keyword can be confusing for people unfamiliar with it, and often /// it is more concise to use `&` instead. + /// /// ### Example /// ```no_run /// let opt = Some(5); diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index e8f9d4381047..48d6fb3c0378 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -3,8 +3,8 @@ use clippy_utils::source::{snippet_opt, snippet_with_context}; use clippy_utils::sugg::has_enclosing_paren; use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; use clippy_utils::{ - fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res, path_to_local_id, span_contains_cfg, - span_find_starting_semi, + binary_expr_needs_parentheses, fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res, + path_to_local_id, span_contains_cfg, span_find_starting_semi, }; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -129,7 +129,7 @@ enum RetReplacement<'tcx> { Empty, Block, Unit, - IfSequence(Cow<'tcx, str>, Applicability), + NeedsPar(Cow<'tcx, str>, Applicability), Expr(Cow<'tcx, str>, Applicability), } @@ -139,13 +139,13 @@ impl<'tcx> RetReplacement<'tcx> { Self::Empty | Self::Expr(..) => "remove `return`", Self::Block => "replace `return` with an empty block", Self::Unit => "replace `return` with a unit value", - Self::IfSequence(..) => "remove `return` and wrap the sequence with parentheses", + Self::NeedsPar(..) => "remove `return` and wrap the sequence with parentheses", } } fn applicability(&self) -> Applicability { match self { - Self::Expr(_, ap) | Self::IfSequence(_, ap) => *ap, + Self::Expr(_, ap) | Self::NeedsPar(_, ap) => *ap, _ => Applicability::MachineApplicable, } } @@ -157,7 +157,7 @@ impl<'tcx> Display for RetReplacement<'tcx> { Self::Empty => write!(f, ""), Self::Block => write!(f, "{{}}"), Self::Unit => write!(f, "()"), - Self::IfSequence(inner, _) => write!(f, "({inner})"), + Self::NeedsPar(inner, _) => write!(f, "({inner})"), Self::Expr(inner, _) => write!(f, "{inner}"), } } @@ -244,7 +244,11 @@ impl<'tcx> LateLintPass<'tcx> for Return { err.span_label(local.span, "unnecessary `let` binding"); if let Some(mut snippet) = snippet_opt(cx, initexpr.span) { - if !cx.typeck_results().expr_adjustments(retexpr).is_empty() { + if binary_expr_needs_parentheses(initexpr) { + if !has_enclosing_paren(&snippet) { + snippet = format!("({snippet})"); + } + } else if !cx.typeck_results().expr_adjustments(retexpr).is_empty() { if !has_enclosing_paren(&snippet) { snippet = format!("({snippet})"); } @@ -349,8 +353,8 @@ fn check_final_expr<'tcx>( let mut applicability = Applicability::MachineApplicable; let (snippet, _) = snippet_with_context(cx, inner_expr.span, ret_span.ctxt(), "..", &mut applicability); - if expr_contains_conjunctive_ifs(inner_expr) { - RetReplacement::IfSequence(snippet, applicability) + if binary_expr_needs_parentheses(inner_expr) { + RetReplacement::NeedsPar(snippet, applicability) } else { RetReplacement::Expr(snippet, applicability) } @@ -404,18 +408,6 @@ fn check_final_expr<'tcx>( } } -fn expr_contains_conjunctive_ifs<'tcx>(expr: &'tcx Expr<'tcx>) -> bool { - fn contains_if(expr: &Expr<'_>, on_if: bool) -> bool { - match expr.kind { - ExprKind::If(..) => on_if, - ExprKind::Binary(_, left, right) => contains_if(left, true) || contains_if(right, true), - _ => false, - } - } - - contains_if(expr, false) -} - fn emit_return_lint( cx: &LateContext<'_>, ret_span: Span, diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 7e27f70bcf94..8fdd19c549f5 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -14,7 +14,7 @@ declare_clippy_lint! { /// It lints if a struct has two methods with the same name: /// one from a trait, another not from trait. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Confusing. /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/semicolon_block.rs b/src/tools/clippy/clippy_lints/src/semicolon_block.rs index 0b3adfb7a4b8..0e77acdfd77f 100644 --- a/src/tools/clippy/clippy_lints/src/semicolon_block.rs +++ b/src/tools/clippy/clippy_lints/src/semicolon_block.rs @@ -11,8 +11,7 @@ declare_clippy_lint! { /// Suggests moving the semicolon after a block to the inside of the block, after its last /// expression. /// - /// ### Why is this bad? - /// + /// ### Why restrict this? /// For consistency it's best to have the semicolon inside/outside the block. Either way is fine /// and this lint suggests inside the block. /// Take a look at `semicolon_outside_block` for the other alternative. @@ -40,8 +39,7 @@ declare_clippy_lint! { /// /// Suggests moving the semicolon from a block's final expression outside of the block. /// - /// ### Why is this bad? - /// + /// ### Why restrict this? /// For consistency it's best to have the semicolon inside/outside the block. Either way is fine /// and this lint suggests outside the block. /// Take a look at `semicolon_inside_block` for the other alternative. diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 9db08acb03b2..80f5fd0b4944 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -15,10 +15,10 @@ declare_clippy_lint! { /// Checks for bindings that shadow other bindings already in /// scope, while just changing reference level or mutability. /// - /// ### Why is this bad? - /// Not much, in fact it's a very common pattern in Rust - /// code. Still, some may opt to avoid it in their code base, they can set this - /// lint to `Warn`. + /// ### Why restrict this? + /// To require that what are formally distinct variables be given distinct names. + /// + /// See also `shadow_reuse` and `shadow_unrelated` for other restrictions on shadowing. /// /// ### Example /// ```no_run @@ -42,12 +42,13 @@ declare_clippy_lint! { /// Checks for bindings that shadow other bindings already in /// scope, while reusing the original value. /// - /// ### Why is this bad? - /// Not too much, in fact it's a common pattern in Rust - /// code. Still, some argue that name shadowing like this hurts readability, + /// ### Why restrict this? + /// Some argue that name shadowing like this hurts readability, /// because a value may be bound to different things depending on position in /// the code. /// + /// See also `shadow_same` and `shadow_unrelated` for other restrictions on shadowing. + /// /// ### Example /// ```no_run /// let x = 2; @@ -70,11 +71,14 @@ declare_clippy_lint! { /// scope, either without an initialization or with one that does not even use /// the original value. /// - /// ### Why is this bad? - /// Name shadowing can hurt readability, especially in + /// ### Why restrict this? + /// Shadowing a binding with a closely related one is part of idiomatic Rust, + /// but shadowing a binding by accident with an unrelated one may indicate a mistake. + /// + /// Additionally, name shadowing in general can hurt readability, especially in /// large code bases, because it is easy to lose track of the active binding at - /// any place in the code. This can be alleviated by either giving more specific - /// names to bindings or introducing more scopes to contain the bindings. + /// any place in the code. If linting against all shadowing is desired, you may wish + /// to use the `shadow_same` and `shadow_reuse` lints as well. /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs index 2ce7e714c642..23bbeae0e31d 100644 --- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs +++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs @@ -13,13 +13,20 @@ declare_clippy_lint! { /// ### What it does /// Checks for functions that are only used once. Does not lint tests. /// - /// ### Why is this bad? - /// It's usually not, splitting a function into multiple parts often improves readability and in - /// the case of generics, can prevent the compiler from duplicating the function dozens of - /// time; instead, only duplicating a thunk. But this can prevent segmentation across a - /// codebase, where many small functions are used only once. + /// ### Why restrict this? + /// If a function is only used once (perhaps because it used to be used more widely), + /// then the code could be simplified by moving that function's code into its caller. /// - /// Note: If this lint is used, prepare to allow this a lot. + /// However, there are reasons not to do this everywhere: + /// + /// * Splitting a large function into multiple parts often improves readability + /// by giving names to its parts. + /// * A function’s signature might serve a necessary purpose, such as constraining + /// the type of a closure passed to it. + /// * Generic functions might call non-generic functions to reduce duplication + /// in the produced machine code. + /// + /// If this lint is used, prepare to `#[allow]` it a lot. /// /// ### Example /// ```no_run @@ -79,7 +86,6 @@ impl SingleCallFn { .tcx .hir() .maybe_body_owned_by(fn_def_id) - .map(|body| cx.tcx.hir().body(body)) .map_or(true, |body| is_in_test_function(cx.tcx, body.value.hir_id)) || match cx.tcx.hir_node(fn_hir_id) { Node::Item(item) => is_from_proc_macro(cx, item), diff --git a/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs b/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs index 42f1564db353..72feb977c310 100644 --- a/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs +++ b/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs @@ -9,11 +9,10 @@ declare_clippy_lint! { /// Checks for lifetimes with names which are one character /// long. /// - /// ### Why is this bad? + /// ### Why restrict this? /// A single character is likely not enough to express the /// purpose of a lifetime. Using a longer name can make code - /// easier to understand, especially for those who are new to - /// Rust. + /// easier to understand. /// /// ### Known problems /// Rust programmers and learning resources tend to use single diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs index 926c56332cc1..12b70075a3d5 100644 --- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs +++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs @@ -12,11 +12,9 @@ use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does - /// /// Finds items imported through `std` when available through `core`. /// - /// ### Why is this bad? - /// + /// ### Why restrict this? /// Crates which have `no_std` compatibility may wish to ensure types are imported from core to ensure /// disabling `std` does not cause the crate to fail to compile. This lint is also useful for crates /// migrating to become `no_std` compatible. @@ -37,11 +35,9 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// /// Finds items imported through `std` when available through `alloc`. /// - /// ### Why is this bad? - /// + /// ### Why restrict this? /// Crates which have `no_std` compatibility and require alloc may wish to ensure types are imported from /// alloc to ensure disabling `std` does not cause the crate to fail to compile. This lint is also useful /// for crates migrating to become `no_std` compatible. @@ -63,11 +59,9 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// /// Finds items imported through `alloc` when available through `core`. /// - /// ### Why is this bad? - /// + /// ### Why restrict this? /// Crates which have `no_std` compatibility and may optionally require alloc may wish to ensure types are /// imported from core to ensure disabling `alloc` does not cause the crate to fail to compile. This lint /// is also useful for crates migrating to become `no_std` compatible. diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index 292124196ff6..f8d36d6b92f6 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -45,10 +45,10 @@ declare_clippy_lint! { /// `String`, but only if [`string_add_assign`](#string_add_assign) does *not* /// match. /// - /// ### Why is this bad? - /// It's not bad in and of itself. However, this particular + /// ### Why restrict this? + /// This particular /// `Add` implementation is asymmetric (the other operand need not be `String`, - /// but `x` does), while addition as mathematically defined is symmetric, also + /// but `x` does), while addition as mathematically defined is symmetric, and /// the `String::push_str(_)` function is a perfectly good replacement. /// Therefore, some dislike it and wish not to have it in their code. /// @@ -123,7 +123,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for slice operations on strings /// - /// ### Why is this bad? + /// ### Why restrict this? /// UTF-8 characters span multiple bytes, and it is easy to inadvertently confuse character /// counts and string indices. This may lead to panics, and should warrant some test cases /// containing wide UTF-8 characters. This lint is most useful in code that should avoid @@ -364,10 +364,10 @@ declare_clippy_lint! { /// ### What it does /// This lint checks for `.to_string()` method calls on values of type `&str`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// The `to_string` method is also used on other types to convert them to a string. - /// When called on a `&str` it turns the `&str` into the owned variant `String`, which can be better - /// expressed with `.to_owned()`. + /// When called on a `&str` it turns the `&str` into the owned variant `String`, which can be + /// more specifically expressed with `.to_owned()`. /// /// ### Example /// ```no_run @@ -415,9 +415,10 @@ declare_clippy_lint! { /// ### What it does /// This lint checks for `.to_string()` method calls on values of type `String`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// The `to_string` method is also used on other types to convert them to a string. - /// When called on a `String` it only clones the `String`, which can be better expressed with `.clone()`. + /// When called on a `String` it only clones the `String`, which can be more specifically + /// expressed with `.clone()`. /// /// ### Example /// ```no_run diff --git a/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs b/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs index 1cc27670fa8b..d150a5f858aa 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs @@ -11,8 +11,10 @@ use rustc_session::declare_lint_pass; declare_clippy_lint! { /// ### What it does /// Warns for a Bitwise XOR (`^`) operator being probably confused as a powering. It will not trigger if any of the numbers are not in decimal. - /// ### Why is this bad? + /// + /// ### Why restrict this? /// It's most probably a typo and may lead to unexpected behaviours. + /// /// ### Example /// ```no_run /// let x = 3_i32 ^ 4_i32; diff --git a/src/tools/clippy/clippy_lints/src/tests_outside_test_module.rs b/src/tools/clippy/clippy_lints/src/tests_outside_test_module.rs index da5575826475..58e42892c41d 100644 --- a/src/tools/clippy/clippy_lints/src/tests_outside_test_module.rs +++ b/src/tools/clippy/clippy_lints/src/tests_outside_test_module.rs @@ -11,9 +11,11 @@ declare_clippy_lint! { /// ### What it does /// Triggers when a testing function (marked with the `#[test]` attribute) isn't inside a testing module /// (marked with `#[cfg(test)]`). - /// ### Why is this bad? + /// + /// ### Why restrict this? /// The idiomatic (and more performant) way of writing tests is inside a testing module (flagged with `#[cfg(test)]`), /// having test functions outside of this module is confusing and may lead to them being "hidden". + /// /// ### Example /// ```no_run /// #[test] diff --git a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs index cc6ff1cf3b42..f98ea59a15d8 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs @@ -30,8 +30,8 @@ fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool { let def_id = cx.tcx.hir().enclosing_body_owner(expr_hir_id); - if let Some(body_id) = cx.tcx.hir().maybe_body_owned_by(def_id) { - let body = cx.tcx.hir().body(body_id); + if let Some(body) = cx.tcx.hir().maybe_body_owned_by(def_id) { + let body = cx.tcx.hir().body(body.id()); return body.value.peel_blocks().hir_id == expr_hir_id; } false diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index 5e45ab211efd..62ef65ca122f 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -217,7 +217,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for `Rc` and `Arc` when `T` is a mutable buffer type such as `String` or `Vec`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Expressions such as `Rc` usually have no advantage over `Rc`, since /// it is larger and involves an extra level of indirection, and doesn't implement `Borrow`. /// @@ -274,7 +274,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for `Rc>`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// `Rc` is used in single thread and `Mutex` is used in multi thread. /// Consider using `Rc>` in single thread or `Arc>` in multi thread. /// diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index 0c4e2c91aec5..5e41b3f4914f 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -336,7 +336,7 @@ impl UnconditionalRecursion { // We need to use typeck here to infer the actual function being called. && let body_def_id = cx.tcx.hir().enclosing_body_owner(call_expr.hir_id) && let Some(body_owner) = cx.tcx.hir().maybe_body_owned_by(body_def_id) - && let typeck = cx.tcx.typeck_body(body_owner) + && let typeck = cx.tcx.typeck_body(body_owner.id()) && let Some(call_def_id) = typeck.type_dependent_def_id(call_expr.hir_id) { self.default_impl_for_type.insert(self_def_id, call_def_id); diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index 4120bb1331bd..6cf9229fdd08 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -38,10 +38,9 @@ declare_clippy_lint! { /// ); /// ``` /// - /// ### Why is this bad? - /// Undocumented unsafe blocks and impls can make it difficult to - /// read and maintain code, as well as uncover unsoundness - /// and bugs. + /// ### Why restrict this? + /// Undocumented unsafe blocks and impls can make it difficult to read and maintain code. + /// Writing out the safety justification may help in discovering unsoundness or bugs. /// /// ### Example /// ```no_run @@ -67,7 +66,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for `// SAFETY: ` comments on safe code. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Safe code has no safety requirements, so there is no need to /// describe safety invariants. /// diff --git a/src/tools/clippy/clippy_lints/src/unicode.rs b/src/tools/clippy/clippy_lints/src/unicode.rs index 3d319b9fe767..d42697b31d1f 100644 --- a/src/tools/clippy/clippy_lints/src/unicode.rs +++ b/src/tools/clippy/clippy_lints/src/unicode.rs @@ -31,7 +31,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for non-ASCII characters in string and char literals. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Yeah, we know, the 90's called and wanted their charset /// back. Even so, there still are editors and other programs out there that /// don't work well with Unicode. So if the code is meant to be used diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index f0d1458a59b2..a8cc2f979633 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -100,12 +100,12 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve { if ord_preds .iter() - .any(|ord| Some(ord.self_ty()) == return_ty_pred.term.ty()) + .any(|ord| Some(ord.self_ty()) == return_ty_pred.term.as_type()) { args_to_check.push((i, "Ord".to_string())); } else if partial_ord_preds .iter() - .any(|pord| pord.self_ty() == return_ty_pred.term.ty().unwrap()) + .any(|pord| pord.self_ty() == return_ty_pred.term.expect_type()) { args_to_check.push((i, "PartialOrd".to_string())); } diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs b/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs index 528a1dfcfc10..93dff1b85796 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs @@ -9,7 +9,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for imports ending in `::{self}`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// In most cases, this can be written much more cleanly by omitting `::{self}`. /// /// ### Known problems diff --git a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs index aca500590cef..197ab0f173bd 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs @@ -13,8 +13,10 @@ declare_clippy_lint! { /// ### What it does /// Checks for functions of type `Result` that contain `expect()` or `unwrap()` /// - /// ### Why is this bad? - /// These functions promote recoverable errors to non-recoverable errors which may be undesirable in code bases which wish to avoid panics. + /// ### Why restrict this? + /// These functions promote recoverable errors to non-recoverable errors, + /// which may be undesirable in code bases which wish to avoid panics, + /// or be a bug in the specific function. /// /// ### Known problems /// This can cause false positives in functions that handle both recoverable and non recoverable errors. diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 4448c9ae3df7..18a31abddd0a 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -137,9 +137,9 @@ impl<'tcx> LateLintPass<'tcx> for Author { fn check_item(cx: &LateContext<'_>, hir_id: HirId) { let hir = cx.tcx.hir(); - if let Some(body_id) = hir.maybe_body_owned_by(hir_id.expect_owner().def_id) { + if let Some(body) = hir.maybe_body_owned_by(hir_id.expect_owner().def_id) { check_node(cx, hir_id, |v| { - v.expr(&v.bind("expr", hir.body(body_id).value)); + v.expr(&v.bind("expr", body.value)); }); } } diff --git a/src/tools/clippy/clippy_lints/src/visibility.rs b/src/tools/clippy/clippy_lints/src/visibility.rs index 9818b98dd5b4..11dcceca7abb 100644 --- a/src/tools/clippy/clippy_lints/src/visibility.rs +++ b/src/tools/clippy/clippy_lints/src/visibility.rs @@ -32,7 +32,7 @@ declare_clippy_lint! { /// ### What it does /// Checks for usage of `pub()` with `in`. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Consistency. Use it or don't, just be consistent about it. /// /// Also see the `pub_without_shorthand` lint for an alternative. @@ -57,7 +57,7 @@ declare_clippy_lint! { /// Note: As you cannot write a module's path in `pub()`, this will only trigger on /// `pub(super)` and the like. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Consistency. Use it or don't, just be consistent about it. /// /// Also see the `pub_with_shorthand` lint for an alternative. diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs index ff6ee0d10ad5..652ce88bd951 100644 --- a/src/tools/clippy/clippy_lints/src/write.rs +++ b/src/tools/clippy/clippy_lints/src/write.rs @@ -66,7 +66,7 @@ declare_clippy_lint! { /// Checks for printing on *stdout*. The purpose of this lint /// is to catch debugging remnants. /// - /// ### Why is this bad? + /// ### Why restrict this? /// People often print on *stdout* while debugging an /// application and might forget to remove those prints afterward. /// @@ -88,7 +88,7 @@ declare_clippy_lint! { /// Checks for printing on *stderr*. The purpose of this lint /// is to catch debugging remnants. /// - /// ### Why is this bad? + /// ### Why restrict this? /// People often print on *stderr* while debugging an /// application and might forget to remove those prints afterward. /// @@ -110,15 +110,18 @@ declare_clippy_lint! { /// Checks for usage of `Debug` formatting. The purpose of this /// lint is to catch debugging remnants. /// - /// ### Why is this bad? - /// The purpose of the `Debug` trait is to facilitate - /// debugging Rust code. It should not be used in user-facing output. + /// ### Why restrict this? + /// The purpose of the `Debug` trait is to facilitate debugging Rust code, + /// and [no guarantees are made about its output][stability]. + /// It should not be used in user-facing output. /// /// ### Example /// ```no_run /// # let foo = "bar"; /// println!("{:?}", foo); /// ``` + /// + /// [stability]: https://doc.rust-lang.org/stable/std/fmt/trait.Debug.html#stability #[clippy::version = "pre 1.29.0"] pub USE_DEBUG, restriction, diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index d4a5f547211a..bbdde3049dbd 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -108,7 +108,7 @@ pub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool { pub fn eq_angle_arg(l: &AngleBracketedArg, r: &AngleBracketedArg) -> bool { match (l, r) { (AngleBracketedArg::Arg(l), AngleBracketedArg::Arg(r)) => eq_generic_arg(l, r), - (AngleBracketedArg::Constraint(l), AngleBracketedArg::Constraint(r)) => eq_assoc_constraint(l, r), + (AngleBracketedArg::Constraint(l), AngleBracketedArg::Constraint(r)) => eq_assoc_item_constraint(l, r), _ => false, } } @@ -802,8 +802,8 @@ fn eq_term(l: &Term, r: &Term) -> bool { } } -pub fn eq_assoc_constraint(l: &AssocConstraint, r: &AssocConstraint) -> bool { - use AssocConstraintKind::*; +pub fn eq_assoc_item_constraint(l: &AssocItemConstraint, r: &AssocItemConstraint) -> bool { + use AssocItemConstraintKind::*; eq_id(l.ident, r.ident) && match (&l.kind, &r.kind) { (Equality { term: l }, Equality { term: r }) => eq_term(l, r), diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index f5d3967d130d..cd88ccd87cf0 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -412,8 +412,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { /// Simple constant folding: Insert an expression, get a constant or none. pub fn expr(&mut self, e: &Expr<'_>) -> Option> { match e.kind { - ExprKind::ConstBlock(e) | - ExprKind::DropTemps(e) => self.expr(e), + ExprKind::ConstBlock(e) | ExprKind::DropTemps(e) => self.expr(e), ExprKind::Path(ref qpath) => { self.fetch_path_and_apply(qpath, e.hir_id, self.typeck_results.expr_ty(e), |this, result| { let result = mir_to_const(this.lcx, result)?; @@ -491,8 +490,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { /// leaves the local crate. pub fn expr_is_empty(&mut self, e: &Expr<'_>) -> Option { match e.kind { - ExprKind::ConstBlock(e) | - ExprKind::DropTemps(e) => self.expr_is_empty(e), + ExprKind::ConstBlock(e) | ExprKind::DropTemps(e) => self.expr_is_empty(e), ExprKind::Path(ref qpath) => { if !self .typeck_results diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index cc5ccd4053a2..c649c1794684 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -9,7 +9,7 @@ use rustc_hir::MatchSource::TryDesugar; use rustc_hir::{ ArrayLen, BinOpKind, BindingMode, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField, PatKind, Path, - PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding, + PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, AssocItemConstraint, }; use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::LateContext; @@ -486,7 +486,7 @@ impl HirEqInterExpr<'_, '_, '_> { fn eq_path_parameters(&mut self, left: &GenericArgs<'_>, right: &GenericArgs<'_>) -> bool { if left.parenthesized == right.parenthesized { over(left.args, right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work - && over(left.bindings, right.bindings, |l, r| self.eq_type_binding(l, r)) + && over(left.constraints, right.constraints, |l, r| self.eq_assoc_type_binding(l, r)) } else { false } @@ -518,8 +518,8 @@ impl HirEqInterExpr<'_, '_, '_> { } } - fn eq_type_binding(&mut self, left: &TypeBinding<'_>, right: &TypeBinding<'_>) -> bool { - left.ident.name == right.ident.name && self.eq_ty(left.ty(), right.ty()) + fn eq_assoc_type_binding(&mut self, left: &AssocItemConstraint<'_>, right: &AssocItemConstraint<'_>) -> bool { + left.ident.name == right.ident.name && self.eq_ty(left.ty().expect("expected assoc type binding"), right.ty().expect("expected assoc type binding")) } fn check_ctxt(&mut self, left: SyntaxContext, right: SyntaxContext) -> bool { @@ -769,7 +769,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { // closures inherit TypeckResults self.hash_expr(self.cx.tcx.hir().body(body).value); }, - ExprKind::ConstBlock(ref l_id) => { + ExprKind::ConstBlock(l_id) => { self.hash_expr(l_id); }, ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 94d4656377f9..b10830b24e1f 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -3370,3 +3370,25 @@ pub fn is_parent_stmt(cx: &LateContext<'_>, id: HirId) -> bool { Node::Stmt(..) | Node::Block(Block { stmts: &[], .. }) ) } + +/// Returns true if the given `expr` is a block or resembled as a block, +/// such as `if`, `loop`, `match` expressions etc. +pub fn is_block_like(expr: &Expr<'_>) -> bool { + matches!( + expr.kind, + ExprKind::Block(..) | ExprKind::ConstBlock(..) | ExprKind::If(..) | ExprKind::Loop(..) | ExprKind::Match(..) + ) +} + +/// Returns true if the given `expr` is binary expression that needs to be wrapped in parentheses. +pub fn binary_expr_needs_parentheses(expr: &Expr<'_>) -> bool { + fn contains_block(expr: &Expr<'_>, is_operand: bool) -> bool { + match expr.kind { + ExprKind::Binary(_, lhs, _) => contains_block(lhs, true), + _ if is_block_like(expr) => is_operand, + _ => false, + } + } + + contains_block(expr, false) +} diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 2dacc34867f0..f0dac6f5d9c4 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{Expr, FnDecl, Safety, LangItem, TyKind}; +use rustc_hir::{Expr, FnDecl, LangItem, Safety, TyKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::interpret::Scalar; @@ -18,8 +18,8 @@ use rustc_middle::traits::EvaluationResult; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, GenericArgsRef, - GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, Upcast, TraitRef, Ty, TyCtxt, - TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, VariantDef, VariantDiscr, + GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, }; use rustc_span::symbol::Ident; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; @@ -750,7 +750,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option None, @@ -798,7 +798,7 @@ fn sig_from_bounds<'tcx>( // Multiple different fn trait impls. Is this even allowed? return None; } - output = Some(pred.kind().rebind(p.term.ty().unwrap())); + output = Some(pred.kind().rebind(p.term.expect_type())); }, _ => (), } @@ -836,7 +836,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option // Multiple different fn trait impls. Is this even allowed? return None; } - output = pred.kind().rebind(p.term.ty()).transpose(); + output = pred.kind().rebind(p.term.as_type()).transpose(); }, _ => (), } diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain index a0585ffdb45b..dd8b9ece773e 100644 --- a/src/tools/clippy/rust-toolchain +++ b/src/tools/clippy/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-16" +channel = "nightly-2024-05-30" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs index b91a83308b5f..ca71dddcc24f 100644 --- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs +++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs @@ -11,11 +11,15 @@ use rustc_lint::{Lint, LintContext}; use rustc_middle::ty::TyCtxt; pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into, msg: impl Into) { - cx.span_lint(lint, span, |lint| { lint.primary_message(msg); }); + cx.span_lint(lint, span, |lint| { + lint.primary_message(msg); + }); } pub fn b(tcx: TyCtxt<'_>, lint: &'static Lint, hir_id: HirId, span: impl Into, msg: impl Into) { - tcx.node_span_lint(lint, hir_id, span, |lint| { lint.primary_message(msg); }); + tcx.node_span_lint(lint, hir_id, span, |lint| { + lint.primary_message(msg); + }); } fn main() {} diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr index 1cfbc8efc8ed..1be4b665bcba 100644 --- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr +++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr @@ -1,18 +1,22 @@ error: use of a disallowed method `rustc_lint::context::LintContext::span_lint` --> tests/ui-internal/disallow_span_lint.rs:14:5 | -LL | cx.span_lint(lint, span, |lint| { lint.primary_message(msg); }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / cx.span_lint(lint, span, |lint| { +LL | | lint.primary_message(msg); +LL | | }); + | |______^ | = note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint*` functions instead (from clippy.toml) = note: `-D clippy::disallowed-methods` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]` error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint` - --> tests/ui-internal/disallow_span_lint.rs:18:5 + --> tests/ui-internal/disallow_span_lint.rs:20:5 | -LL | tcx.node_span_lint(lint, hir_id, span, |lint| { lint.primary_message(msg); }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / tcx.node_span_lint(lint, hir_id, span, |lint| { +LL | | lint.primary_message(msg); +LL | | }); + | |______^ | = note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead (from clippy.toml) diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed index 6f42487bbf49..eb93eb8e8ed4 100644 --- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed +++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed @@ -1,3 +1,4 @@ +#![feature(lint_reasons)] #![allow(unused)] #![warn(clippy::derive_partial_eq_without_eq)] @@ -14,6 +15,22 @@ pub struct MissingEq { bar: String, } +// Check that we honor the `allow` attribute +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Debug, PartialEq)] +pub struct AllowedMissingEq { + foo: u32, + bar: String, +} + +// Check that we honor the `expect` attribute +#[expect(clippy::derive_partial_eq_without_eq)] +#[derive(Debug, PartialEq)] +pub struct ExpectedMissingEq { + foo: u32, + bar: String, +} + // Eq is derived #[derive(PartialEq, Eq)] pub struct NotMissingEq { diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs index 24f687c6c9db..42dc435bdd52 100644 --- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs +++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs @@ -1,3 +1,4 @@ +#![feature(lint_reasons)] #![allow(unused)] #![warn(clippy::derive_partial_eq_without_eq)] @@ -14,6 +15,22 @@ pub struct MissingEq { bar: String, } +// Check that we honor the `allow` attribute +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Debug, PartialEq)] +pub struct AllowedMissingEq { + foo: u32, + bar: String, +} + +// Check that we honor the `expect` attribute +#[expect(clippy::derive_partial_eq_without_eq)] +#[derive(Debug, PartialEq)] +pub struct ExpectedMissingEq { + foo: u32, + bar: String, +} + // Eq is derived #[derive(PartialEq, Eq)] pub struct NotMissingEq { diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr index 3d92112dc36d..29cd7da6b77d 100644 --- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr +++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr @@ -1,5 +1,5 @@ error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:11:17 + --> tests/ui/derive_partial_eq_without_eq.rs:12:17 | LL | #[derive(Debug, PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` @@ -8,73 +8,73 @@ LL | #[derive(Debug, PartialEq)] = help: to override `-D warnings` add `#[allow(clippy::derive_partial_eq_without_eq)]` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:53:10 + --> tests/ui/derive_partial_eq_without_eq.rs:70:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:59:10 + --> tests/ui/derive_partial_eq_without_eq.rs:76:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:65:10 + --> tests/ui/derive_partial_eq_without_eq.rs:82:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:68:10 + --> tests/ui/derive_partial_eq_without_eq.rs:85:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:74:10 + --> tests/ui/derive_partial_eq_without_eq.rs:91:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:80:10 + --> tests/ui/derive_partial_eq_without_eq.rs:97:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:93:17 + --> tests/ui/derive_partial_eq_without_eq.rs:110:17 | LL | #[derive(Debug, PartialEq, Clone)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:96:10 + --> tests/ui/derive_partial_eq_without_eq.rs:113:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:103:14 + --> tests/ui/derive_partial_eq_without_eq.rs:120:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:106:14 + --> tests/ui/derive_partial_eq_without_eq.rs:123:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:166:14 + --> tests/ui/derive_partial_eq_without_eq.rs:183:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:174:14 + --> tests/ui/derive_partial_eq_without_eq.rs:191:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed index 7e22c847b1bc..84673f1f43fd 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed @@ -240,3 +240,6 @@ extern { /// `foo()` fn in_extern(); } + +/// +fn check_autofix_for_base_urls() {} diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs index 3e2cb0df54b0..4d017a99e0fb 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs @@ -240,3 +240,6 @@ extern { /// foo() fn in_extern(); } + +/// https://github.com/rust-lang/rust-clippy/pull/12836 +fn check_autofix_for_base_urls() {} diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr index cd2228c47e35..a9263f62d38d 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr @@ -363,5 +363,11 @@ help: try LL | /// `foo()` | ~~~~~~~ -error: aborting due to 33 previous errors +error: you should put bare URLs between `<`/`>` or make a proper Markdown link + --> tests/ui/doc/doc-fixable.rs:244:5 + | +LL | /// https://github.com/rust-lang/rust-clippy/pull/12836 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `` + +error: aborting due to 34 previous errors diff --git a/src/tools/clippy/tests/ui/doc/issue_12795.fixed b/src/tools/clippy/tests/ui/doc/issue_12795.fixed new file mode 100644 index 000000000000..ade23bf975c2 --- /dev/null +++ b/src/tools/clippy/tests/ui/doc/issue_12795.fixed @@ -0,0 +1,9 @@ +#![warn(clippy::doc_markdown)] + +//! A comment with `a_b(x)` and `a_c` in it and (`a_b((c))` ) too and (maybe `a_b((c))`) +//~^ ERROR: item in documentation is missing backticks +//~| ERROR: item in documentation is missing backticks +//~| ERROR: item in documentation is missing backticks +//~| ERROR: item in documentation is missing backticks + +pub fn main() {} diff --git a/src/tools/clippy/tests/ui/doc/issue_12795.rs b/src/tools/clippy/tests/ui/doc/issue_12795.rs new file mode 100644 index 000000000000..6d94a07e3036 --- /dev/null +++ b/src/tools/clippy/tests/ui/doc/issue_12795.rs @@ -0,0 +1,9 @@ +#![warn(clippy::doc_markdown)] + +//! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) +//~^ ERROR: item in documentation is missing backticks +//~| ERROR: item in documentation is missing backticks +//~| ERROR: item in documentation is missing backticks +//~| ERROR: item in documentation is missing backticks + +pub fn main() {} diff --git a/src/tools/clippy/tests/ui/doc/issue_12795.stderr b/src/tools/clippy/tests/ui/doc/issue_12795.stderr new file mode 100644 index 000000000000..5700145ec8f7 --- /dev/null +++ b/src/tools/clippy/tests/ui/doc/issue_12795.stderr @@ -0,0 +1,48 @@ +error: item in documentation is missing backticks + --> tests/ui/doc/issue_12795.rs:3:20 + | +LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) + | ^^^^^^ + | + = note: `-D clippy::doc-markdown` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` +help: try + | +LL | //! A comment with `a_b(x)` and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) + | ~~~~~~~~ + +error: item in documentation is missing backticks + --> tests/ui/doc/issue_12795.rs:3:31 + | +LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) + | ^^^ + | +help: try + | +LL | //! A comment with a_b(x) and `a_c` in it and (a_b((c)) ) too and (maybe a_b((c))) + | ~~~~~ + +error: item in documentation is missing backticks + --> tests/ui/doc/issue_12795.rs:3:46 + | +LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) + | ^^^^^^^^ + | +help: try + | +LL | //! A comment with a_b(x) and a_c in it and (`a_b((c))` ) too and (maybe a_b((c))) + | ~~~~~~~~~~ + +error: item in documentation is missing backticks + --> tests/ui/doc/issue_12795.rs:3:72 + | +LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) + | ^^^^^^^^ + | +help: try + | +LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe `a_b((c))`) + | ~~~~~~~~~~ + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed b/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed index 794629f240eb..0f28b48d9ab8 100644 --- a/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed +++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed @@ -20,6 +20,28 @@ fn array() { }; let _ = if false { ["test"].iter() } else { [].iter() }; + + let smth = Some(vec![1, 2, 3]); + + // Don't trigger when the empty collection iter is relied upon for its concrete type + // But do trigger if it is just an iterator, despite being an argument to a method + for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain(std::iter::empty()) { + println!("{i}"); + } + + // Same as above, but for empty collection iters with extra layers + for i in smth.as_ref().map_or({ [].iter() }, |s| s.iter()) { + println!("{y}", y = i + 1); + } + + // Same as above, but for regular function calls + for i in Option::map_or(smth.as_ref(), [].iter(), |s| s.iter()) { + println!("{i}"); + } + + // Same as above, but when there are no predicates that mention the collection iter type. + let mut iter = [34, 228, 35].iter(); + let _ = std::mem::replace(&mut iter, [].iter()); } macro_rules! in_macros { diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.rs b/src/tools/clippy/tests/ui/iter_on_empty_collections.rs index a6461a702eb2..702da514df7d 100644 --- a/src/tools/clippy/tests/ui/iter_on_empty_collections.rs +++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.rs @@ -20,6 +20,28 @@ fn array() { }; let _ = if false { ["test"].iter() } else { [].iter() }; + + let smth = Some(vec![1, 2, 3]); + + // Don't trigger when the empty collection iter is relied upon for its concrete type + // But do trigger if it is just an iterator, despite being an argument to a method + for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain([].iter()) { + println!("{i}"); + } + + // Same as above, but for empty collection iters with extra layers + for i in smth.as_ref().map_or({ [].iter() }, |s| s.iter()) { + println!("{y}", y = i + 1); + } + + // Same as above, but for regular function calls + for i in Option::map_or(smth.as_ref(), [].iter(), |s| s.iter()) { + println!("{i}"); + } + + // Same as above, but when there are no predicates that mention the collection iter type. + let mut iter = [34, 228, 35].iter(); + let _ = std::mem::replace(&mut iter, [].iter()); } macro_rules! in_macros { diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr b/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr index ade20ff26a01..da9caa6925bd 100644 --- a/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr +++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr @@ -37,5 +37,11 @@ error: `iter` call on an empty collection LL | assert_eq!(None.iter().next(), Option::<&i32>::None); | ^^^^^^^^^^^ help: try: `std::iter::empty()` -error: aborting due to 6 previous errors +error: `iter` call on an empty collection + --> tests/ui/iter_on_empty_collections.rs:28:66 + | +LL | for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain([].iter()) { + | ^^^^^^^^^ help: try: `std::iter::empty()` + +error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/let_and_return.fixed b/src/tools/clippy/tests/ui/let_and_return.fixed index 4187019e5894..b68b41cdca23 100644 --- a/src/tools/clippy/tests/ui/let_and_return.fixed +++ b/src/tools/clippy/tests/ui/let_and_return.fixed @@ -210,4 +210,38 @@ fn issue9150() -> usize { x } +fn issue12801() { + fn left_is_if() -> String { + + (if true { "a".to_string() } else { "b".to_string() } + "c") + //~^ ERROR: returning the result of a `let` binding from a block + } + + fn no_par_needed() -> String { + + "c".to_string() + if true { "a" } else { "b" } + //~^ ERROR: returning the result of a `let` binding from a block + } + + fn conjunctive_blocks() -> String { + + ({ "a".to_string() } + "b" + { "c" } + "d") + //~^ ERROR: returning the result of a `let` binding from a block + } + + #[allow(clippy::overly_complex_bool_expr)] + fn other_ops() { + let _ = || { + + (if true { 2 } else { 3 } << 4) + //~^ ERROR: returning the result of a `let` binding from a block + }; + let _ = || { + + ({ true } || { false } && { 2 <= 3 }) + //~^ ERROR: returning the result of a `let` binding from a block + }; + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/let_and_return.rs b/src/tools/clippy/tests/ui/let_and_return.rs index 54444957b7d5..6b9035f94288 100644 --- a/src/tools/clippy/tests/ui/let_and_return.rs +++ b/src/tools/clippy/tests/ui/let_and_return.rs @@ -210,4 +210,38 @@ fn issue9150() -> usize { x } +fn issue12801() { + fn left_is_if() -> String { + let s = if true { "a".to_string() } else { "b".to_string() } + "c"; + s + //~^ ERROR: returning the result of a `let` binding from a block + } + + fn no_par_needed() -> String { + let s = "c".to_string() + if true { "a" } else { "b" }; + s + //~^ ERROR: returning the result of a `let` binding from a block + } + + fn conjunctive_blocks() -> String { + let s = { "a".to_string() } + "b" + { "c" } + "d"; + s + //~^ ERROR: returning the result of a `let` binding from a block + } + + #[allow(clippy::overly_complex_bool_expr)] + fn other_ops() { + let _ = || { + let s = if true { 2 } else { 3 } << 4; + s + //~^ ERROR: returning the result of a `let` binding from a block + }; + let _ = || { + let s = { true } || { false } && { 2 <= 3 }; + s + //~^ ERROR: returning the result of a `let` binding from a block + }; + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/let_and_return.stderr b/src/tools/clippy/tests/ui/let_and_return.stderr index ff5962ec196e..75efa05d770a 100644 --- a/src/tools/clippy/tests/ui/let_and_return.stderr +++ b/src/tools/clippy/tests/ui/let_and_return.stderr @@ -78,5 +78,75 @@ LL + E::B(x) => x, LL + }) as _ | -error: aborting due to 5 previous errors +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:216:9 + | +LL | let s = if true { "a".to_string() } else { "b".to_string() } + "c"; + | ------------------------------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ (if true { "a".to_string() } else { "b".to_string() } + "c") + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:222:9 + | +LL | let s = "c".to_string() + if true { "a" } else { "b" }; + | ------------------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ "c".to_string() + if true { "a" } else { "b" } + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:228:9 + | +LL | let s = { "a".to_string() } + "b" + { "c" } + "d"; + | -------------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ ({ "a".to_string() } + "b" + { "c" } + "d") + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:236:13 + | +LL | let s = if true { 2 } else { 3 } << 4; + | -------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ (if true { 2 } else { 3 } << 4) + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:241:13 + | +LL | let s = { true } || { false } && { 2 <= 3 }; + | -------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ ({ true } || { false } && { 2 <= 3 }) + | + +error: aborting due to 10 previous errors diff --git a/src/tools/clippy/tests/ui/many_single_char_names.rs b/src/tools/clippy/tests/ui/many_single_char_names.rs index 2af45eaab8af..68578340d90e 100644 --- a/src/tools/clippy/tests/ui/many_single_char_names.rs +++ b/src/tools/clippy/tests/ui/many_single_char_names.rs @@ -1,5 +1,3 @@ -//@compile-flags: -Zdeduplicate-diagnostics=yes - #![allow(clippy::too_many_arguments, clippy::diverging_sub_expression)] #![warn(clippy::many_single_char_names)] diff --git a/src/tools/clippy/tests/ui/many_single_char_names.stderr b/src/tools/clippy/tests/ui/many_single_char_names.stderr index 3b2460b5c077..131836ef7c88 100644 --- a/src/tools/clippy/tests/ui/many_single_char_names.stderr +++ b/src/tools/clippy/tests/ui/many_single_char_names.stderr @@ -1,5 +1,5 @@ error: 5 bindings with single-character names in scope - --> tests/ui/many_single_char_names.rs:7:9 + --> tests/ui/many_single_char_names.rs:5:9 | LL | let a: i32; | ^ @@ -14,7 +14,7 @@ LL | let e: i32; = help: to override `-D warnings` add `#[allow(clippy::many_single_char_names)]` error: 6 bindings with single-character names in scope - --> tests/ui/many_single_char_names.rs:7:9 + --> tests/ui/many_single_char_names.rs:5:9 | LL | let a: i32; | ^ @@ -28,7 +28,7 @@ LL | let f: i32; | ^ error: 5 bindings with single-character names in scope - --> tests/ui/many_single_char_names.rs:7:9 + --> tests/ui/many_single_char_names.rs:5:9 | LL | let a: i32; | ^ @@ -40,13 +40,13 @@ LL | e => panic!(), | ^ error: 8 bindings with single-character names in scope - --> tests/ui/many_single_char_names.rs:36:13 + --> tests/ui/many_single_char_names.rs:34:13 | LL | fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {} | ^ ^ ^ ^ ^ ^ ^ ^ error: 8 bindings with single-character names in scope - --> tests/ui/many_single_char_names.rs:40:10 + --> tests/ui/many_single_char_names.rs:38:10 | LL | let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!(); | ^ ^ ^ ^ ^ ^ ^ ^ diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed index 2575f2449e18..a9271cb399d8 100644 --- a/src/tools/clippy/tests/ui/needless_return.fixed +++ b/src/tools/clippy/tests/ui/needless_return.fixed @@ -323,4 +323,8 @@ fn allow_works() -> i32 { } } +fn conjunctive_blocks() -> String { + ({ "a".to_string() } + "b" + { "c" }) +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs index 04f21834d885..dc888bf667f1 100644 --- a/src/tools/clippy/tests/ui/needless_return.rs +++ b/src/tools/clippy/tests/ui/needless_return.rs @@ -333,4 +333,8 @@ fn allow_works() -> i32 { } } +fn conjunctive_blocks() -> String { + return { "a".to_string() } + "b" + { "c" }; +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr index 758ff6d985cd..bf5a89d8b75d 100644 --- a/src/tools/clippy/tests/ui/needless_return.stderr +++ b/src/tools/clippy/tests/ui/needless_return.stderr @@ -653,5 +653,17 @@ LL - return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 LL + (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }) | -error: aborting due to 52 previous errors +error: unneeded `return` statement + --> tests/ui/needless_return.rs:337:5 + | +LL | return { "a".to_string() } + "b" + { "c" }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove `return` and wrap the sequence with parentheses + | +LL - return { "a".to_string() } + "b" + { "c" }; +LL + ({ "a".to_string() } + "b" + { "c" }) + | + +error: aborting due to 53 previous errors diff --git a/src/tools/clippy/tests/ui/numbered_fields.fixed b/src/tools/clippy/tests/ui/numbered_fields.fixed index dc88081ba0a7..108520eed38d 100644 --- a/src/tools/clippy/tests/ui/numbered_fields.fixed +++ b/src/tools/clippy/tests/ui/numbered_fields.fixed @@ -34,4 +34,9 @@ fn main() { // Aliases can't be tuple constructed #8638 let _ = Alias { 0: 0, 1: 1, 2: 2 }; + + // Issue #12367 + struct TupleStructVec(Vec); + + let _ = TupleStructVec(vec![0, 1, 2, 3]); } diff --git a/src/tools/clippy/tests/ui/numbered_fields.rs b/src/tools/clippy/tests/ui/numbered_fields.rs index e8fa652e3c1d..c718661a6826 100644 --- a/src/tools/clippy/tests/ui/numbered_fields.rs +++ b/src/tools/clippy/tests/ui/numbered_fields.rs @@ -42,4 +42,9 @@ fn main() { // Aliases can't be tuple constructed #8638 let _ = Alias { 0: 0, 1: 1, 2: 2 }; + + // Issue #12367 + struct TupleStructVec(Vec); + + let _ = TupleStructVec { 0: vec![0, 1, 2, 3] }; } diff --git a/src/tools/clippy/tests/ui/numbered_fields.stderr b/src/tools/clippy/tests/ui/numbered_fields.stderr index 96426cab1e62..9d3f59cd3769 100644 --- a/src/tools/clippy/tests/ui/numbered_fields.stderr +++ b/src/tools/clippy/tests/ui/numbered_fields.stderr @@ -23,5 +23,11 @@ LL | | 1: 3u32, LL | | }; | |_____^ help: try: `TupleStruct(1u32, 3u32, 2u8)` -error: aborting due to 2 previous errors +error: used a field initializer for a tuple struct + --> tests/ui/numbered_fields.rs:49:13 + | +LL | let _ = TupleStructVec { 0: vec![0, 1, 2, 3] }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `TupleStructVec(vec![0, 1, 2, 3])` + +error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs index 7fc89bb95380..8ee15440ccf0 100644 --- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs @@ -274,11 +274,20 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { }, (_, _, _) => {}, }; + } +} +// Should not trigger lint since `String::as_str` returns a reference (i.e., `&str`) +// to the locked data (i.e., the `String`) and it is not surprising that matching such +// a reference needs to keep the data locked until the end of the match block. +fn should_not_trigger_lint_for_string_as_str() { + let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() }); + + { + let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() }); let mutex3 = Mutex::new(StateWithField { s: "three".to_owned() }); + match mutex3.lock().unwrap().s.as_str() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until - //~| NOTE: this might lead to deadlocks or other unexpected behavior "three" => { println!("started"); mutex1.lock().unwrap().s.len(); @@ -289,8 +298,6 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { }; match (true, mutex3.lock().unwrap().s.as_str()) { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until - //~| NOTE: this might lead to deadlocks or other unexpected behavior (_, "three") => { println!("started"); mutex1.lock().unwrap().s.len(); @@ -514,16 +521,15 @@ impl StateStringWithBoxedMutexGuard { } } -fn should_trigger_lint_for_boxed_mutex_guard_holding_string() { +fn should_not_trigger_lint_for_string_ref() { let s = StateStringWithBoxedMutexGuard::new(); let matcher = String::from("A String"); - // Should trigger lint because a temporary Box holding a type with a significant drop in a match - // scrutinee may have a potentially surprising lifetime. + // Should not trigger lint because the second `deref` returns a string reference (`&String`). + // So it is not surprising that matching the reference implies that the lock needs to be held + // until the end of the block. match s.lock().deref().deref() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior matcher => println!("Value is {}", s.lock().deref()), _ => println!("Value was not a match"), }; @@ -639,13 +645,12 @@ fn should_trigger_lint_for_non_ref_move_and_clone_suggestion() { }; } -fn should_trigger_lint_for_read_write_lock_for_loop() { - // For-in loops desugar to match expressions and are prone to the type of deadlock this lint is - // designed to look for. +fn should_not_trigger_lint_for_read_write_lock_for_loop() { let rwlock = RwLock::>::new(vec!["1".to_string()]); + // Should not trigger lint. Since we're iterating over the data, it's obvious that the lock + // has to be held until the iteration finishes. + // https://github.com/rust-lang/rust-clippy/issues/8987 for s in rwlock.read().unwrap().iter() { - //~^ ERROR: temporary with significant `Drop` in `for` loop condition will live until - //~| NOTE: this might lead to deadlocks or other unexpected behavior println!("{}", s); } } @@ -731,4 +736,69 @@ fn should_not_trigger_for_significant_drop_ref() { }; } +struct Foo<'a>(&'a Vec); + +impl<'a> Foo<'a> { + fn copy_old_lifetime(&self) -> &'a Vec { + self.0 + } + + fn reborrow_new_lifetime(&self) -> &Vec { + self.0 + } +} + +fn should_trigger_lint_if_and_only_if_lifetime_is_irrelevant() { + let vec = Vec::new(); + let mutex = Mutex::new(Foo(&vec)); + + // Should trigger lint even if `copy_old_lifetime()` has a lifetime, as the lifetime of + // `&vec` is unrelated to the temporary with significant drop (i.e., the `MutexGuard`). + for val in mutex.lock().unwrap().copy_old_lifetime() { + //~^ ERROR: temporary with significant `Drop` in `for` loop condition will live until the + //~| NOTE: this might lead to deadlocks or other unexpected behavior + println!("{}", val); + } + + // Should not trigger lint because `reborrow_new_lifetime()` has a lifetime and the + // lifetime is related to the temporary with significant drop (i.e., the `MutexGuard`). + for val in mutex.lock().unwrap().reborrow_new_lifetime() { + println!("{}", val); + } +} + +fn should_not_trigger_lint_for_complex_lifetime() { + let mutex = Mutex::new(vec!["hello".to_owned()]); + let string = "world".to_owned(); + + // Should not trigger lint due to the relevant lifetime. + for c in mutex.lock().unwrap().first().unwrap().chars() { + println!("{}", c); + } + + // Should trigger lint due to the irrelevant lifetime. + // + // FIXME: The lifetime is too complex to analyze. In order to avoid false positives, we do not + // trigger lint. + for c in mutex.lock().unwrap().first().map(|_| &string).unwrap().chars() { + println!("{}", c); + } +} + +fn should_not_trigger_lint_with_explicit_drop() { + let mutex = Mutex::new(vec![1]); + + // Should not trigger lint since the drop explicitly happens. + for val in [drop(mutex.lock().unwrap()), ()] { + println!("{:?}", val); + } + + // Should trigger lint if there is no explicit drop. + for val in [mutex.lock().unwrap()[0], 2] { + //~^ ERROR: temporary with significant `Drop` in `for` loop condition will live until the + //~| NOTE: this might lead to deadlocks or other unexpected behavior + println!("{:?}", val); + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr index 811bb0655279..4a483e79d8ad 100644 --- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr +++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr @@ -160,42 +160,10 @@ LL ~ match (mutex1.lock().unwrap().s.len(), true, value) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:279:15 - | -LL | match mutex3.lock().unwrap().s.as_str() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | mutex1.lock().unwrap().s.len(); - | ---------------------- another value with significant `Drop` created here -LL | mutex2.lock().unwrap().s.len(); - | ---------------------- another value with significant `Drop` created here -... -LL | }; - | - temporary lives until here - | - = note: this might lead to deadlocks or other unexpected behavior - -error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:291:22 - | -LL | match (true, mutex3.lock().unwrap().s.as_str()) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | mutex1.lock().unwrap().s.len(); - | ---------------------- another value with significant `Drop` created here -LL | mutex2.lock().unwrap().s.len(); - | ---------------------- another value with significant `Drop` created here -... -LL | }; - | - temporary lives until here - | - = note: this might lead to deadlocks or other unexpected behavior - -error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:312:11 + --> tests/ui/significant_drop_in_scrutinee.rs:319:11 | LL | match mutex.lock().unwrap().s.len() > 1 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | mutex.lock().unwrap().s.len(); | --------------------- another value with significant `Drop` created here @@ -206,15 +174,15 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | -LL ~ let value = mutex.lock().unwrap().s.len() > 1; -LL ~ match value { +LL ~ let value = mutex.lock().unwrap().s.len(); +LL ~ match value > 1 { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:321:11 + --> tests/ui/significant_drop_in_scrutinee.rs:328:15 | LL | match 1 < mutex.lock().unwrap().s.len() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | mutex.lock().unwrap().s.len(); | --------------------- another value with significant `Drop` created here @@ -225,15 +193,15 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | -LL ~ let value = 1 < mutex.lock().unwrap().s.len(); -LL ~ match value { +LL ~ let value = mutex.lock().unwrap().s.len(); +LL ~ match 1 < value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:341:11 + --> tests/ui/significant_drop_in_scrutinee.rs:348:11 | LL | match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | mutex1.lock().unwrap().s.len(), | ---------------------- another value with significant `Drop` created here @@ -246,15 +214,36 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | -LL ~ let value = mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len(); -LL ~ match value { +LL ~ let value = mutex1.lock().unwrap().s.len(); +LL ~ match value < mutex2.lock().unwrap().s.len() { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:354:11 + --> tests/ui/significant_drop_in_scrutinee.rs:348:44 + | +LL | match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mutex1.lock().unwrap().s.len(), + | ---------------------- another value with significant `Drop` created here +LL | mutex2.lock().unwrap().s.len() + | ---------------------- another value with significant `Drop` created here +... +LL | }; + | - temporary lives until here + | + = note: this might lead to deadlocks or other unexpected behavior +help: try moving the temporary above the match + | +LL ~ let value = mutex2.lock().unwrap().s.len(); +LL ~ match mutex1.lock().unwrap().s.len() < value { + | + +error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression + --> tests/ui/significant_drop_in_scrutinee.rs:361:11 | LL | match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | mutex1.lock().unwrap().s.len(), | ---------------------- another value with significant `Drop` created here @@ -267,15 +256,36 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | -LL ~ let value = mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len(); -LL ~ match value { +LL ~ let value = mutex1.lock().unwrap().s.len(); +LL ~ match value >= mutex2.lock().unwrap().s.len() { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:391:11 + --> tests/ui/significant_drop_in_scrutinee.rs:361:45 + | +LL | match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mutex1.lock().unwrap().s.len(), + | ---------------------- another value with significant `Drop` created here +LL | mutex2.lock().unwrap().s.len() + | ---------------------- another value with significant `Drop` created here +... +LL | }; + | - temporary lives until here + | + = note: this might lead to deadlocks or other unexpected behavior +help: try moving the temporary above the match + | +LL ~ let value = mutex2.lock().unwrap().s.len(); +LL ~ match mutex1.lock().unwrap().s.len() >= value { + | + +error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression + --> tests/ui/significant_drop_in_scrutinee.rs:398:11 | LL | match get_mutex_guard().s.len() > 1 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | mutex1.lock().unwrap().s.len(); | ---------------------- another value with significant `Drop` created here @@ -286,12 +296,12 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | -LL ~ let value = get_mutex_guard().s.len() > 1; -LL ~ match value { +LL ~ let value = get_mutex_guard().s.len(); +LL ~ match value > 1 { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:410:11 + --> tests/ui/significant_drop_in_scrutinee.rs:417:11 | LL | match match i { | ___________^ @@ -299,9 +309,9 @@ LL | | LL | | LL | | 100 => mutex1.lock().unwrap(), ... | +LL | | .s LL | | .len() -LL | | > 1 - | |___________^ + | |__________^ ... LL | mutex1.lock().unwrap().s.len(); | ---------------------- another value with significant `Drop` created here @@ -319,13 +329,12 @@ LL + 100 => mutex1.lock().unwrap(), LL + _ => mutex2.lock().unwrap(), LL + } LL + .s -LL + .len() -LL + > 1; +LL + .len(); LL ~ match value | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:438:11 + --> tests/ui/significant_drop_in_scrutinee.rs:445:11 | LL | match if i > 1 { | ___________^ @@ -333,9 +342,9 @@ LL | | LL | | LL | | mutex1.lock().unwrap() ... | +LL | | .s LL | | .len() -LL | | > 1 - | |___________^ + | |__________^ ... LL | mutex1.lock().unwrap().s.len(); | ---------------------- another value with significant `Drop` created here @@ -354,13 +363,12 @@ LL + } else { LL + mutex2.lock().unwrap() LL + } LL + .s -LL + .len() -LL + > 1; +LL + .len(); LL ~ match value | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:494:11 + --> tests/ui/significant_drop_in_scrutinee.rs:501:11 | LL | match s.lock().deref().deref() { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -374,25 +382,11 @@ LL | }; help: try moving the temporary above the match and create a copy | LL ~ let value = *s.lock().deref().deref(); -LL ~ match value { +LL ~ match (&value) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:524:11 - | -LL | match s.lock().deref().deref() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | matcher => println!("Value is {}", s.lock().deref()), - | -------- another value with significant `Drop` created here -LL | _ => println!("Value was not a match"), -LL | }; - | - temporary lives until here - | - = note: this might lead to deadlocks or other unexpected behavior - -error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:545:11 + --> tests/ui/significant_drop_in_scrutinee.rs:551:11 | LL | match mutex.lock().unwrap().i = i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -411,10 +405,10 @@ LL ~ match () { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:553:11 + --> tests/ui/significant_drop_in_scrutinee.rs:559:15 | LL | match i = mutex.lock().unwrap().i { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ ... LL | println!("{}", mutex.lock().unwrap().i); | --------------------- another value with significant `Drop` created here @@ -425,12 +419,12 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | -LL ~ i = mutex.lock().unwrap().i; -LL ~ match () { +LL ~ let value = mutex.lock().unwrap().i; +LL ~ match i = value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:561:11 + --> tests/ui/significant_drop_in_scrutinee.rs:567:11 | LL | match mutex.lock().unwrap().i += 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -449,10 +443,10 @@ LL ~ match () { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:569:11 + --> tests/ui/significant_drop_in_scrutinee.rs:575:16 | LL | match i += mutex.lock().unwrap().i { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ ... LL | println!("{}", mutex.lock().unwrap().i); | --------------------- another value with significant `Drop` created here @@ -463,12 +457,12 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior help: try moving the temporary above the match | -LL ~ i += mutex.lock().unwrap().i; -LL ~ match () { +LL ~ let value = mutex.lock().unwrap().i; +LL ~ match i += value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:634:11 + --> tests/ui/significant_drop_in_scrutinee.rs:640:11 | LL | match rwlock.read().unwrap().to_number() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -477,20 +471,14 @@ LL | }; | - temporary lives until here | = note: this might lead to deadlocks or other unexpected behavior - -error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression - --> tests/ui/significant_drop_in_scrutinee.rs:646:14 +help: try moving the temporary above the match | -LL | for s in rwlock.read().unwrap().iter() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | } - | - temporary lives until here +LL ~ let value = rwlock.read().unwrap().to_number(); +LL ~ match value { | - = note: this might lead to deadlocks or other unexpected behavior error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:663:11 + --> tests/ui/significant_drop_in_scrutinee.rs:668:11 | LL | match mutex.lock().unwrap().foo() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -506,7 +494,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:726:11 + --> tests/ui/significant_drop_in_scrutinee.rs:731:11 | LL | match guard.take().len() { | ^^^^^^^^^^^^^^^^^^ @@ -521,5 +509,37 @@ LL ~ let value = guard.take().len(); LL ~ match value { | +error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression + --> tests/ui/significant_drop_in_scrutinee.rs:757:16 + | +LL | for val in mutex.lock().unwrap().copy_old_lifetime() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | } + | - temporary lives until here + | + = note: this might lead to deadlocks or other unexpected behavior +help: try moving the temporary above the match + | +LL ~ let value = mutex.lock().unwrap().copy_old_lifetime(); +LL ~ for val in value { + | + +error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression + --> tests/ui/significant_drop_in_scrutinee.rs:797:17 + | +LL | for val in [mutex.lock().unwrap()[0], 2] { + | ^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | } + | - temporary lives until here + | + = note: this might lead to deadlocks or other unexpected behavior +help: try moving the temporary above the match + | +LL ~ let value = mutex.lock().unwrap()[0]; +LL ~ for val in [value, 2] { + | + error: aborting due to 27 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed index 2c582c90ba8c..dc5e163ff04e 100644 --- a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed @@ -170,3 +170,32 @@ fn check_mut_iteratee_and_modify_inner_variable() { } } } + +mod issue_12821 { + fn foo() { + let v: Vec<_> = "hello".chars().collect(); + for c in v.iter() { + //~^ ERROR: unnecessary use of `cloned` + println!("{c}"); // should not suggest to remove `&` + } + } + + fn bar() { + let v: Vec<_> = "hello".chars().collect(); + for c in v.iter() { + //~^ ERROR: unnecessary use of `cloned` + let ref_c = c; //~ HELP: remove any references to the binding + println!("{ref_c}"); + } + } + + fn baz() { + let v: Vec<_> = "hello".chars().enumerate().collect(); + for (i, c) in v.iter() { + //~^ ERROR: unnecessary use of `cloned` + let ref_c = c; //~ HELP: remove any references to the binding + let ref_i = i; + println!("{i} {ref_c}"); // should not suggest to remove `&` from `i` + } + } +} diff --git a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs index a28ccd1efef2..8f797ac717fb 100644 --- a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs +++ b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs @@ -170,3 +170,32 @@ fn check_mut_iteratee_and_modify_inner_variable() { } } } + +mod issue_12821 { + fn foo() { + let v: Vec<_> = "hello".chars().collect(); + for c in v.iter().cloned() { + //~^ ERROR: unnecessary use of `cloned` + println!("{c}"); // should not suggest to remove `&` + } + } + + fn bar() { + let v: Vec<_> = "hello".chars().collect(); + for c in v.iter().cloned() { + //~^ ERROR: unnecessary use of `cloned` + let ref_c = &c; //~ HELP: remove any references to the binding + println!("{ref_c}"); + } + } + + fn baz() { + let v: Vec<_> = "hello".chars().enumerate().collect(); + for (i, c) in v.iter().cloned() { + //~^ ERROR: unnecessary use of `cloned` + let ref_c = &c; //~ HELP: remove any references to the binding + let ref_i = &i; + println!("{i} {ref_c}"); // should not suggest to remove `&` from `i` + } + } +} diff --git a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.stderr b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.stderr index fb98cfddc262..0bdb37a521fc 100644 --- a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.stderr @@ -10,7 +10,7 @@ help: use | LL | for (t, path) in files { | ~~~~~ -help: remove this `&` +help: remove any references to the binding | LL - let other = match get_file_path(&t) { LL + let other = match get_file_path(t) { @@ -26,11 +26,49 @@ help: use | LL | for (t, path) in files.iter() { | ~~~~~~~~~~~~ -help: remove this `&` +help: remove any references to the binding | LL - let other = match get_file_path(&t) { LL + let other = match get_file_path(t) { | -error: aborting due to 2 previous errors +error: unnecessary use of `cloned` + --> tests/ui/unnecessary_iter_cloned.rs:177:18 + | +LL | for c in v.iter().cloned() { + | ^^^^^^^^^^^^^^^^^ help: use: `v.iter()` + +error: unnecessary use of `cloned` + --> tests/ui/unnecessary_iter_cloned.rs:185:18 + | +LL | for c in v.iter().cloned() { + | ^^^^^^^^^^^^^^^^^ + | +help: use + | +LL | for c in v.iter() { + | ~~~~~~~~ +help: remove any references to the binding + | +LL - let ref_c = &c; +LL + let ref_c = c; + | + +error: unnecessary use of `cloned` + --> tests/ui/unnecessary_iter_cloned.rs:194:23 + | +LL | for (i, c) in v.iter().cloned() { + | ^^^^^^^^^^^^^^^^^ + | +help: use + | +LL | for (i, c) in v.iter() { + | ~~~~~~~~ +help: remove any references to the binding + | +LL ~ let ref_c = c; +LL ~ let ref_i = i; + | + +error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr index 5475df9c7b93..2829f3cd6e98 100644 --- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr @@ -487,7 +487,7 @@ help: use | LL | for t in file_types { | ~~~~~~~~~~ -help: remove this `&` +help: remove any references to the binding | LL - let path = match get_file_path(&t) { LL + let path = match get_file_path(t) { diff --git a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs index 70dcaa3afa45..5187e0790423 100644 --- a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs +++ b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs @@ -1,3 +1,4 @@ +#![feature(lint_reasons)] #![warn(clippy::unsafe_derive_deserialize)] #![allow(unused, clippy::missing_safety_doc)] @@ -71,4 +72,14 @@ impl G { } } +// Check that we honor the `expect` attribute on the ADT +#[expect(clippy::unsafe_derive_deserialize)] +#[derive(Deserialize)] +pub struct H; +impl H { + pub fn unsafe_block(&self) { + unsafe {} + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr index f2d4429f707a..06719f23d57f 100644 --- a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr +++ b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr @@ -1,5 +1,5 @@ error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe` - --> tests/ui/unsafe_derive_deserialize.rs:8:10 + --> tests/ui/unsafe_derive_deserialize.rs:9:10 | LL | #[derive(Deserialize)] | ^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | #[derive(Deserialize)] = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe` - --> tests/ui/unsafe_derive_deserialize.rs:17:10 + --> tests/ui/unsafe_derive_deserialize.rs:18:10 | LL | #[derive(Deserialize)] | ^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | #[derive(Deserialize)] = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe` - --> tests/ui/unsafe_derive_deserialize.rs:24:10 + --> tests/ui/unsafe_derive_deserialize.rs:25:10 | LL | #[derive(Deserialize)] | ^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | #[derive(Deserialize)] = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe` - --> tests/ui/unsafe_derive_deserialize.rs:33:10 + --> tests/ui/unsafe_derive_deserialize.rs:34:10 | LL | #[derive(Deserialize)] | ^^^^^^^^^^^ diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 7ff45edd4b26..b0047770564c 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -187,9 +187,6 @@ pub struct Config { /// The rustdoc executable. pub rustdoc_path: Option, - /// The rust-demangler executable. - pub rust_demangler_path: Option, - /// The coverage-dump executable. pub coverage_dump_path: Option, diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index c11d3da13a8b..7a5abc51d043 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -57,6 +57,18 @@ pub struct Error { pub msg: String, } +impl Error { + pub fn render_for_expected(&self) -> String { + use colored::Colorize; + format!( + "{: <10}line {: >3}: {}", + self.kind.map(|kind| kind.to_string()).unwrap_or_default().to_uppercase(), + self.line_num, + self.msg.cyan(), + ) + } +} + #[derive(PartialEq, Debug)] enum WhichLine { ThisLine, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index dc5818201b6d..a2cdf800a971 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1436,7 +1436,7 @@ pub fn make_test_description( if config.target == "wasm32-unknown-unknown" { if config.parse_name_directive(ln, directives::CHECK_RUN_RESULTS) { decision!(IgnoreDecision::Ignore { - reason: "ignored when checking the run results on WASM".into(), + reason: "ignored on WASM as the run results cannot be checked there".into(), }); } } @@ -1577,8 +1577,11 @@ fn ignore_llvm(config: &Config, line: &str) -> IgnoreDecision { .split_whitespace() .find(|needed_component| !components.contains(needed_component)) { - if env::var_os("COMPILETEST_NEEDS_ALL_LLVM_COMPONENTS").is_some() { - panic!("missing LLVM component: {}", missing_component); + if env::var_os("COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS").is_some() { + panic!( + "missing LLVM component {}, and COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS is set", + missing_component + ); } return IgnoreDecision::Ignore { reason: format!("ignored when the {missing_component} LLVM component is missing"), diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 99bde107f3a4..62e71e9b59dd 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -46,7 +46,6 @@ pub fn parse_config(args: Vec) -> Config { .reqopt("", "run-lib-path", "path to target shared libraries", "PATH") .reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH") .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH") - .optopt("", "rust-demangler-path", "path to rust-demangler to use in tests", "PATH") .optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH") .reqopt("", "python", "path to python to use for doc tests", "PATH") .optopt("", "jsondocck-path", "path to jsondocck to use for doc tests", "PATH") @@ -232,7 +231,6 @@ pub fn parse_config(args: Vec) -> Config { run_lib_path: make_absolute(opt_path(matches, "run-lib-path")), rustc_path: opt_path(matches, "rustc-path"), rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from), - rust_demangler_path: matches.opt_str("rust-demangler-path").map(PathBuf::from), coverage_dump_path: matches.opt_str("coverage-dump-path").map(PathBuf::from), python: matches.opt_str("python").unwrap(), jsondocck_path: matches.opt_str("jsondocck-path"), @@ -337,7 +335,6 @@ pub fn log_config(config: &Config) { logv(c, format!("run_lib_path: {:?}", config.run_lib_path)); logv(c, format!("rustc_path: {:?}", config.rustc_path.display())); logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path)); - logv(c, format!("rust_demangler_path: {:?}", config.rust_demangler_path)); logv(c, format!("src_base: {:?}", config.src_base.display())); logv(c, format!("build_base: {:?}", config.build_base.display())); logv(c, format!("stage_id: {}", config.stage_id)); diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 42c751bb6bed..1ec3f0a0552e 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -1,10 +1,18 @@ -use std::{env, sync::Arc}; +use std::{env, io::IsTerminal, sync::Arc}; use compiletest::{common::Mode, log_config, parse_config, run_tests}; fn main() { tracing_subscriber::fmt::init(); + // colored checks stdout by default, but for some reason only stderr is a terminal. + // compiletest *does* print many things to stdout, but it doesn't really matter. + if std::io::stderr().is_terminal() + && matches!(std::env::var("NO_COLOR").as_deref(), Err(_) | Ok("0")) + { + colored::control::set_override(true); + } + let config = Arc::new(parse_config(env::args().collect())); if config.valgrind_path.is_none() && config.force_valgrind { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 910a829fbea1..9bd0002a3d9a 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -17,10 +17,10 @@ use crate::json; use crate::read2::{read2_abbreviated, Truncated}; use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt}; use crate::ColorConfig; +use colored::Colorize; use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile}; use regex::{Captures, Regex}; use rustfix::{apply_suggestions, get_suggestions_from_json, Filter}; - use std::collections::{HashMap, HashSet}; use std::env; use std::ffi::{OsStr, OsString}; @@ -506,8 +506,20 @@ impl<'test> TestCx<'test> { } } + /// Runs a [`Command`] and waits for it to finish, then converts its exit + /// status and output streams into a [`ProcRes`]. + /// + /// The command might have succeeded or failed; it is the caller's + /// responsibility to check the exit status and take appropriate action. + /// + /// # Panics + /// Panics if the command couldn't be executed at all + /// (e.g. because the executable could not be found). + #[must_use = "caller should check whether the command succeeded"] fn run_command_to_procres(&self, cmd: &mut Command) -> ProcRes { - let output = cmd.output().unwrap_or_else(|e| panic!("failed to exec `{cmd:?}`: {e:?}")); + let output = cmd + .output() + .unwrap_or_else(|e| self.fatal(&format!("failed to exec `{cmd:?}` because: {e}"))); let proc_res = ProcRes { status: output.status, @@ -1232,7 +1244,7 @@ impl<'test> TestCx<'test> { } else { self.config.lldb_python_dir.as_ref().unwrap().to_string() }; - self.cmd2procres( + self.run_command_to_procres( Command::new(&self.config.python) .arg(&lldb_script_path) .arg(test_executable) @@ -1242,28 +1254,6 @@ impl<'test> TestCx<'test> { ) } - fn cmd2procres(&self, cmd: &mut Command) -> ProcRes { - let (status, out, err) = match cmd.output() { - Ok(Output { status, stdout, stderr }) => { - (status, String::from_utf8(stdout).unwrap(), String::from_utf8(stderr).unwrap()) - } - Err(e) => self.fatal(&format!( - "Failed to setup Python process for \ - LLDB script: {}", - e - )), - }; - - self.dump_output(&out, &err); - ProcRes { - status, - stdout: out, - stderr: err, - truncated: Truncated::No, - cmdline: format!("{:?}", cmd), - } - } - fn cleanup_debug_info_options(&self, options: &Vec) -> Vec { // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS. let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()]; @@ -1503,14 +1493,22 @@ impl<'test> TestCx<'test> { unexpected.len(), not_found.len() )); - println!("status: {}\ncommand: {}", proc_res.status, proc_res.cmdline); + println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline); if !unexpected.is_empty() { - println!("unexpected errors (from JSON output): {:#?}\n", unexpected); + println!("{}", "--- unexpected errors (from JSON output) ---".green()); + for error in &unexpected { + println!("{}", error.render_for_expected()); + } + println!("{}", "---".green()); } if !not_found.is_empty() { - println!("not found errors (from test file): {:#?}\n", not_found); + println!("{}", "--- not found errors (from test file) ---".red()); + for error in ¬_found { + println!("{}", error.render_for_expected()); + } + println!("{}", "---\n".red()); } - panic!(); + panic!("errors differ from expected"); } } @@ -2683,7 +2681,7 @@ impl<'test> TestCx<'test> { if self.config.bless { cmd.arg("--bless"); } - let res = self.cmd2procres(&mut cmd); + let res = self.run_command_to_procres(&mut cmd); if !res.status.success() { self.fatal_proc_rec_with_ctx("htmldocck failed!", &res, |mut this| { this.compare_to_default_rustdoc(&out_dir) @@ -2860,7 +2858,7 @@ impl<'test> TestCx<'test> { let root = self.config.find_rust_src_root().unwrap(); let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap()); json_out.set_extension("json"); - let res = self.cmd2procres( + let res = self.run_command_to_procres( Command::new(self.config.jsondocck_path.as_ref().unwrap()) .arg("--doc-dir") .arg(root.join(&out_dir)) @@ -2878,7 +2876,7 @@ impl<'test> TestCx<'test> { let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap()); json_out.set_extension("json"); - let res = self.cmd2procres( + let res = self.run_command_to_procres( Command::new(self.config.jsondoclint_path.as_ref().unwrap()).arg(&json_out), ); @@ -3441,11 +3439,23 @@ impl<'test> TestCx<'test> { let build_root = self.config.build_base.parent().unwrap().parent().unwrap(); let build_root = cwd.join(&build_root); - let tmpdir = cwd.join(self.output_base_name()); - if tmpdir.exists() { - self.aggressive_rm_rf(&tmpdir).unwrap(); + // We construct the following directory tree for each rmake.rs test: + // ``` + // base_dir/ + // rmake.exe + // rmake_out/ + // ``` + // having the executable separate from the output artifacts directory allows the recipes to + // `remove_dir_all($TMPDIR)` without running into permission denied issues because + // the executable is not under the `rmake_out/` directory. + // + // This setup intentionally diverges from legacy Makefile run-make tests. + let base_dir = cwd.join(self.output_base_name()); + if base_dir.exists() { + self.aggressive_rm_rf(&base_dir).unwrap(); } - create_dir_all(&tmpdir).unwrap(); + let rmake_out_dir = base_dir.join("rmake_out"); + create_dir_all(&rmake_out_dir).unwrap(); // HACK: assume stageN-target, we only want stageN. let stage = self.config.stage_id.split('-').next().unwrap(); @@ -3462,8 +3472,11 @@ impl<'test> TestCx<'test> { stage_std_path.push("lib"); // Then, we need to build the recipe `rmake.rs` and link in the support library. - let recipe_bin = - tmpdir.join(if self.config.target.contains("windows") { "rmake.exe" } else { "rmake" }); + let recipe_bin = base_dir.join(if self.config.target.contains("windows") { + "rmake.exe" + } else { + "rmake" + }); let mut support_lib_deps = PathBuf::new(); support_lib_deps.push(&build_root); @@ -3504,7 +3517,7 @@ impl<'test> TestCx<'test> { .env("S", &src_root) .env("RUST_BUILD_STAGE", &self.config.stage_id) .env("RUSTC", cwd.join(&self.config.rustc_path)) - .env("TMPDIR", &tmpdir) + .env("TMPDIR", &rmake_out_dir) .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) .env(dylib_env_var(), &host_dylib_env_paths) .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) @@ -3526,7 +3539,7 @@ impl<'test> TestCx<'test> { cmd.arg("--sysroot").arg(&stage0_sysroot); } - let res = self.cmd2procres(&mut cmd); + let res = self.run_command_to_procres(&mut cmd); if !res.status.success() { self.fatal_proc_rec("run-make test failed: could not build `rmake.rs` recipe", &res); } @@ -3540,7 +3553,7 @@ impl<'test> TestCx<'test> { let dylib_env_paths = env::join_paths(dylib_env_paths).unwrap(); let mut target_rpath_env_path = Vec::new(); - target_rpath_env_path.push(&tmpdir); + target_rpath_env_path.push(&rmake_out_dir); target_rpath_env_path.extend(&orig_dylib_env_paths); let target_rpath_env_path = env::join_paths(target_rpath_env_path).unwrap(); @@ -3556,7 +3569,7 @@ impl<'test> TestCx<'test> { .env("S", &src_root) .env("RUST_BUILD_STAGE", &self.config.stage_id) .env("RUSTC", cwd.join(&self.config.rustc_path)) - .env("TMPDIR", &tmpdir) + .env("TMPDIR", &rmake_out_dir) .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path)) .env("LLVM_COMPONENTS", &self.config.llvm_components) @@ -3571,10 +3584,6 @@ impl<'test> TestCx<'test> { cmd.env("RUSTDOC", cwd.join(rustdoc)); } - if let Some(ref rust_demangler) = self.config.rust_demangler_path { - cmd.env("RUST_DEMANGLER", cwd.join(rust_demangler)); - } - if let Some(ref node) = self.config.nodejs { cmd.env("NODE", node); } @@ -3687,7 +3696,7 @@ impl<'test> TestCx<'test> { let root = self.config.find_rust_src_root().unwrap(); let file_stem = self.testpaths.file.file_stem().and_then(|f| f.to_str()).expect("no file stem"); - let res = self.cmd2procres( + let res = self.run_command_to_procres( Command::new(&nodejs) .arg(root.join("src/tools/rustdoc-js/tester.js")) .arg("--doc-folder") diff --git a/src/tools/compiletest/src/runtest/coverage.rs b/src/tools/compiletest/src/runtest/coverage.rs index dad3fb301333..8bd7c7e808d3 100644 --- a/src/tools/compiletest/src/runtest/coverage.rs +++ b/src/tools/compiletest/src/runtest/coverage.rs @@ -10,10 +10,15 @@ use crate::common::{UI_COVERAGE, UI_COVERAGE_MAP}; use crate::runtest::{static_regex, Emit, ProcRes, TestCx, WillExecute}; impl<'test> TestCx<'test> { + fn coverage_dump_path(&self) -> &Path { + self.config + .coverage_dump_path + .as_deref() + .unwrap_or_else(|| self.fatal("missing --coverage-dump")) + } + pub(crate) fn run_coverage_map_test(&self) { - let Some(coverage_dump_path) = &self.config.coverage_dump_path else { - self.fatal("missing --coverage-dump"); - }; + let coverage_dump_path = self.coverage_dump_path(); let (proc_res, llvm_ir_path) = self.compile_test_and_save_ir(); if !proc_res.status.success() { @@ -102,8 +107,10 @@ impl<'test> TestCx<'test> { let proc_res = self.run_llvm_tool("llvm-cov", |cmd| { cmd.args(["show", "--format=text", "--show-line-counts-or-regions"]); - cmd.arg("--Xdemangler"); - cmd.arg(self.config.rust_demangler_path.as_ref().unwrap()); + // Specify the demangler binary and its arguments. + let coverage_dump_path = self.coverage_dump_path(); + cmd.arg("--Xdemangler").arg(coverage_dump_path); + cmd.arg("--Xdemangler").arg("--demangle"); cmd.arg("--instr-profile"); cmd.arg(&profdata_path); diff --git a/src/tools/coverage-dump/README.md b/src/tools/coverage-dump/README.md index e2625d5adf27..49d8e14c7bcc 100644 --- a/src/tools/coverage-dump/README.md +++ b/src/tools/coverage-dump/README.md @@ -6,3 +6,8 @@ The output format is mostly arbitrary, so it's OK to change the output as long as any affected tests are also re-blessed. However, the output should be consistent across different executions on different platforms, so avoid printing any information that is platform-specific or non-deterministic. + +## Demangle mode + +When run as `coverage-dump --demangle`, this tool instead functions as a +command-line demangler that can be invoked by `llvm-cov`. diff --git a/src/tools/coverage-dump/src/main.rs b/src/tools/coverage-dump/src/main.rs index 93fed1799e04..b21e3e292f2b 100644 --- a/src/tools/coverage-dump/src/main.rs +++ b/src/tools/coverage-dump/src/main.rs @@ -7,6 +7,13 @@ fn main() -> anyhow::Result<()> { let args = std::env::args().collect::>(); + // The coverage-dump tool already needs `rustc_demangle` in order to read + // coverage metadata, so it's very easy to also have a separate mode that + // turns it into a command-line demangler for use by coverage-run tests. + if &args[1..] == &["--demangle"] { + return demangle(); + } + let llvm_ir_path = args.get(1).context("LLVM IR file not specified")?; let llvm_ir = std::fs::read_to_string(llvm_ir_path).context("couldn't read LLVM IR file")?; @@ -15,3 +22,15 @@ fn main() -> anyhow::Result<()> { Ok(()) } + +fn demangle() -> anyhow::Result<()> { + use std::fmt::Write as _; + + let stdin = std::io::read_to_string(std::io::stdin())?; + let mut output = String::with_capacity(stdin.len()); + for line in stdin.lines() { + writeln!(output, "{:#}", rustc_demangle::demangle(line))?; + } + print!("{output}"); + Ok(()) +} diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.rs b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.rs index ff23f1e729e8..0c305eed6e18 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.rs +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.rs @@ -7,10 +7,12 @@ use std::intrinsics::mir::*; #[custom_mir(dialect = "runtime")] pub unsafe fn deref_meta(p: *const *const [i32]) -> usize { - mir!({ - RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data - Return() - }) + mir! { + { + RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data + Return() + } + } } fn main() { diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr index 61e1541d1ee4..6478dcc2507f 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory --> $DIR/ptr_metadata_uninit_slice_data.rs:LL:CC | -LL | RET = PtrMetadata(*p); - | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory +LL | RET = PtrMetadata(*p); + | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | = 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 diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs index 65f74c0acdd6..a2ffdc92c4e2 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs @@ -7,10 +7,12 @@ use std::intrinsics::mir::*; #[custom_mir(dialect = "runtime")] pub unsafe fn deref_meta(p: *const *const [i32]) -> usize { - mir!({ - RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data - Return() - }) + mir! { + { + RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data + Return() + } + } } fn main() { diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr index de559263a326..4e2e72184323 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr @@ -16,8 +16,8 @@ LL | (*p.as_mut_ptr().cast::<[*const i32; 2]>())[0] = 4 as *const i32; error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory --> $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC | -LL | RET = PtrMetadata(*p); - | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory +LL | RET = PtrMetadata(*p); + | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | = 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 diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.rs b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.rs index ad2e9fc800eb..e5a51289a8ae 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.rs +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.rs @@ -7,10 +7,12 @@ use std::intrinsics::mir::*; #[custom_mir(dialect = "runtime")] pub unsafe fn deref_meta(p: *const *const i32) -> () { - mir!({ - RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data - Return() - }) + mir! { + { + RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data + Return() + } + } } fn main() { diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr index 3ab2643afa72..0e218de0eeb5 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory --> $DIR/ptr_metadata_uninit_thin.rs:LL:CC | -LL | RET = PtrMetadata(*p); - | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory +LL | RET = PtrMetadata(*p); + | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | = 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 diff --git a/src/tools/miri/tests/fail/issue-miri-2432.rs b/src/tools/miri/tests/fail/issue-miri-2432.rs deleted file mode 100644 index f822479c4368..000000000000 --- a/src/tools/miri/tests/fail/issue-miri-2432.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![allow(where_clauses_object_safety)] - -trait Trait {} - -trait X { - fn foo(&self) - where - Self: Trait; -} - -impl X for () { - fn foo(&self) {} -} - -impl Trait for dyn X {} - -pub fn main() { - ::foo(&()); //~ERROR: trying to call something that is not a method -} diff --git a/src/tools/miri/tests/fail/issue-miri-2432.stderr b/src/tools/miri/tests/fail/issue-miri-2432.stderr deleted file mode 100644 index 3befe31dc5a0..000000000000 --- a/src/tools/miri/tests/fail/issue-miri-2432.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: `dyn` call trying to call something that is not a method - --> $DIR/issue-miri-2432.rs:LL:CC - | -LL | ::foo(&()); - | ^^^^^^^^^^^^^^^^^^^^^^ `dyn` call trying to call something that is not a method - | - = 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 $DIR/issue-miri-2432.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/async-drop.rs b/src/tools/miri/tests/pass/async-drop.rs index f16206f3db62..92ecbdd29fdb 100644 --- a/src/tools/miri/tests/pass/async-drop.rs +++ b/src/tools/miri/tests/pass/async-drop.rs @@ -1,6 +1,11 @@ //@revisions: stack tree //@compile-flags: -Zmiri-strict-provenance //@[tree]compile-flags: -Zmiri-tree-borrows + +// WARNING: If you would ever want to modify this test, +// please consider modifying rustc's async drop test at +// `tests/ui/async-await/async-drop.rs`. + #![feature(async_drop, impl_trait_in_assoc_type, noop_waker, async_closure)] #![allow(incomplete_features, dead_code)] diff --git a/src/tools/miri/tests/pass/drop_in_place.rs b/src/tools/miri/tests/pass/drop_in_place.rs new file mode 100644 index 000000000000..0615a43c8000 --- /dev/null +++ b/src/tools/miri/tests/pass/drop_in_place.rs @@ -0,0 +1,12 @@ +// Miri currently doesn't require types without drop glue to be +// valid when dropped. This test confirms that behavior. +// This is not a stable guarantee! + +use std::ptr; + +fn main() { + let mut not_a_bool = 13u8; + unsafe { + ptr::drop_in_place(&mut not_a_bool as *mut u8 as *mut bool) + }; +} diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs index 799c36b10499..0012e7b66af3 100644 --- a/src/tools/run-make-support/src/cc.rs +++ b/src/tools/run-make-support/src/cc.rs @@ -80,6 +80,13 @@ impl Cc { self } + /// Specify path of the output binary. + pub fn output>(&mut self, path: P) -> &mut Self { + self.cmd.arg("-o"); + self.cmd.arg(path.as_ref()); + self + } + /// Get the [`Output`][::std::process::Output] of the finished process. pub fn command_output(&mut self) -> ::std::process::Output { self.cmd.output().expect("failed to get output of finished process") diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 0cf64db6ac9c..323fc40e6481 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -123,12 +123,23 @@ pub fn dynamic_lib_name(name: &str) -> String { // ``` assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace"); + let extension = dynamic_lib_extension(); if is_darwin() { - format!("lib{name}.dylib") + format!("lib{name}.{extension}") } else if is_windows() { - format!("{name}.dll") + format!("{name}.{extension}") } else { - format!("lib{name}.so") + format!("lib{name}.{extension}") + } +} + +pub fn dynamic_lib_extension() -> &'static str { + if is_darwin() { + "dylib" + } else if is_windows() { + "dll" + } else { + "so" } } @@ -249,16 +260,13 @@ pub fn recursive_diff(dir1: impl AsRef, dir2: impl AsRef) { } let dir2 = dir2.as_ref(); - for entry in fs::read_dir(dir1).unwrap() { - let entry = entry.unwrap(); - let entry_name = entry.file_name(); - let path = entry.path(); - - if path.is_dir() { - recursive_diff(&path, &dir2.join(entry_name)); + read_dir(dir1, |entry_path| { + let entry_name = entry_path.file_name().unwrap(); + if entry_path.is_dir() { + recursive_diff(&entry_path, &dir2.join(entry_name)); } else { let path2 = dir2.join(entry_name); - let file1 = read_file(&path); + let file1 = read_file(&entry_path); let file2 = read_file(&path2); // We don't use `assert_eq!` because they are `Vec`, so not great for display. @@ -267,10 +275,16 @@ pub fn recursive_diff(dir1: impl AsRef, dir2: impl AsRef) { assert!( file1 == file2, "`{}` and `{}` have different content", - path.display(), + entry_path.display(), path2.display(), ); } + }); +} + +pub fn read_dir(dir: impl AsRef, callback: F) { + for entry in fs::read_dir(dir).unwrap() { + callback(&entry.unwrap().path()); } } diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs index 9aad91f1b463..da4f265efc3b 100644 --- a/src/tools/run-make-support/src/run.rs +++ b/src/tools/run-make-support/src/run.rs @@ -4,12 +4,12 @@ use std::process::{Command, Output}; use crate::is_windows; -use super::{bin_name, handle_failed_output}; +use super::handle_failed_output; fn run_common(name: &str) -> (Command, Output) { let mut bin_path = PathBuf::new(); bin_path.push(env::var("TMPDIR").unwrap()); - bin_path.push(&bin_name(name)); + bin_path.push(name); let ld_lib_path_envvar = env::var("LD_LIB_PATH_ENVVAR").unwrap(); let mut cmd = Command::new(bin_path); cmd.env(&ld_lib_path_envvar, { diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 8eb872514a5d..3558c39bb32c 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -216,16 +216,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "command-group" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5080df6b0f0ecb76cab30808f00d937ba725cebe266a3da8cd89dff92f2a9916" -dependencies = [ - "nix 0.26.4", - "winapi", -] - [[package]] name = "countme" version = "3.0.1" @@ -292,7 +282,7 @@ version = "3.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" dependencies = [ - "nix 0.28.0", + "nix", "windows-sys 0.52.0", ] @@ -432,9 +422,9 @@ name = "flycheck" version = "0.0.0" dependencies = [ "cargo_metadata", - "command-group", "crossbeam-channel", "paths", + "process-wrap", "rustc-hash", "serde", "serde_json", @@ -1121,17 +1111,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "nix" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", -] - [[package]] name = "nix" version = "0.28.0" @@ -1397,6 +1376,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "process-wrap" +version = "8.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ee68ae331824036479c84060534b18254c864fa73366c58d86db3b7b811619" +dependencies = [ + "indexmap", + "nix", + "tracing", + "windows", +] + [[package]] name = "profile" version = "0.0.0" @@ -2374,22 +2365,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" version = "0.1.8" @@ -2400,10 +2375,57 @@ dependencies = [ ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" +dependencies = [ + "windows-core", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-implement" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "749f0da9cc72d82e600d8d2e44cadd0b9eedb9038f71a1c58556ac1c5791813b" +dependencies = [ + "windows-targets 0.52.5", +] [[package]] name = "windows-sys" diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 3108c1b3dfe5..ccc27e21333b 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -111,7 +111,6 @@ chalk-solve = { version = "0.97.0", default-features = false } chalk-ir = "0.97.0" chalk-recursive = { version = "0.97.0", default-features = false } chalk-derive = "0.97.0" -command-group = "2.0.1" crossbeam-channel = "0.5.8" dissimilar = "1.0.7" dot = "0.1.4" @@ -132,6 +131,7 @@ object = { version = "0.33.0", default-features = false, features = [ "macho", "pe", ] } +process-wrap = { version = "8.0.2", features = ["std"] } pulldown-cmark-to-cmark = "10.0.4" pulldown-cmark = { version = "0.9.0", default-features = false } rayon = "1.8.0" diff --git a/src/tools/rust-analyzer/crates/flycheck/Cargo.toml b/src/tools/rust-analyzer/crates/flycheck/Cargo.toml index b8c10da1b6e3..d81a5fe34006 100644 --- a/src/tools/rust-analyzer/crates/flycheck/Cargo.toml +++ b/src/tools/rust-analyzer/crates/flycheck/Cargo.toml @@ -18,7 +18,7 @@ tracing.workspace = true rustc-hash.workspace = true serde_json.workspace = true serde.workspace = true -command-group.workspace = true +process-wrap.workspace = true # local deps paths.workspace = true diff --git a/src/tools/rust-analyzer/crates/flycheck/src/command.rs b/src/tools/rust-analyzer/crates/flycheck/src/command.rs index 8ba7018316a1..38c7c81f57a1 100644 --- a/src/tools/rust-analyzer/crates/flycheck/src/command.rs +++ b/src/tools/rust-analyzer/crates/flycheck/src/command.rs @@ -9,8 +9,8 @@ use std::{ process::{ChildStderr, ChildStdout, Command, Stdio}, }; -use command_group::{CommandGroup, GroupChild}; use crossbeam_channel::Sender; +use process_wrap::std::{StdChildWrapper, StdCommandWrap}; use stdx::process::streaming_output; /// Cargo output is structured as a one JSON per line. This trait abstracts parsing one line of @@ -85,7 +85,7 @@ impl CargoActor { } } -struct JodGroupChild(GroupChild); +struct JodGroupChild(Box); impl Drop for JodGroupChild { fn drop(&mut self) { @@ -119,14 +119,20 @@ impl fmt::Debug for CommandHandle { impl CommandHandle { pub(crate) fn spawn(mut command: Command, sender: Sender) -> std::io::Result { command.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null()); - let mut child = command.group_spawn().map(JodGroupChild)?; let program = command.get_program().into(); let arguments = command.get_args().map(|arg| arg.into()).collect::>(); let current_dir = command.get_current_dir().map(|arg| arg.to_path_buf()); - let stdout = child.0.inner().stdout.take().unwrap(); - let stderr = child.0.inner().stderr.take().unwrap(); + let mut child = StdCommandWrap::from(command); + #[cfg(unix)] + child.wrap(process_wrap::std::ProcessSession); + #[cfg(windows)] + child.wrap(process_wrap::std::JobObject); + let mut child = child.spawn().map(JodGroupChild)?; + + let stdout = child.0.stdout().take().unwrap(); + let stderr = child.0.stderr().take().unwrap(); let actor = CargoActor::::new(sender, stdout, stderr); let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) diff --git a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs index 6d5ca8321e5d..afdc3e389b36 100644 --- a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs +++ b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs @@ -163,6 +163,9 @@ pub enum Message { /// Request adding a diagnostic with fixes included to a file AddDiagnostic { id: usize, workspace_root: AbsPathBuf, diagnostic: Diagnostic }, + /// Request clearing all previous diagnostics + ClearDiagnostics { id: usize }, + /// Request check progress notification to client Progress { /// Flycheck instance ID @@ -180,6 +183,9 @@ impl fmt::Debug for Message { .field("workspace_root", workspace_root) .field("diagnostic_code", &diagnostic.code.as_ref().map(|it| &it.code)) .finish(), + Message::ClearDiagnostics { id } => { + f.debug_struct("ClearDiagnostics").field("id", id).finish() + } Message::Progress { id, progress } => { f.debug_struct("Progress").field("id", id).field("progress", progress).finish() } @@ -220,6 +226,8 @@ struct FlycheckActor { command_handle: Option>, /// The receiver side of the channel mentioned above. command_receiver: Option>, + + status: FlycheckStatus, } enum Event { @@ -227,6 +235,13 @@ enum Event { CheckEvent(Option), } +#[derive(PartialEq)] +enum FlycheckStatus { + Started, + DiagnosticSent, + Finished, +} + const SAVED_FILE_PLACEHOLDER: &str = "$saved_file"; impl FlycheckActor { @@ -248,6 +263,7 @@ impl FlycheckActor { manifest_path, command_handle: None, command_receiver: None, + status: FlycheckStatus::Finished, } } @@ -298,12 +314,14 @@ impl FlycheckActor { self.command_handle = Some(command_handle); self.command_receiver = Some(receiver); self.report_progress(Progress::DidStart); + self.status = FlycheckStatus::Started; } Err(error) => { self.report_progress(Progress::DidFailToRestart(format!( "Failed to run the following command: {} error={}", formatted_command, error ))); + self.status = FlycheckStatus::Finished; } } } @@ -323,7 +341,11 @@ impl FlycheckActor { error ); } + if self.status == FlycheckStatus::Started { + self.send(Message::ClearDiagnostics { id: self.id }); + } self.report_progress(Progress::DidFinish(res)); + self.status = FlycheckStatus::Finished; } Event::CheckEvent(Some(message)) => match message { CargoCheckMessage::CompilerArtifact(msg) => { @@ -341,11 +363,15 @@ impl FlycheckActor { message = msg.message, "diagnostic received" ); + if self.status == FlycheckStatus::Started { + self.send(Message::ClearDiagnostics { id: self.id }); + } self.send(Message::AddDiagnostic { id: self.id, workspace_root: self.root.clone(), diagnostic: msg, }); + self.status = FlycheckStatus::DiagnosticSent; } }, } @@ -362,6 +388,7 @@ impl FlycheckActor { ); command_handle.cancel(); self.report_progress(Progress::DidCancel); + self.status = FlycheckStatus::Finished; } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 2e5fa6131a77..12421bbe7026 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -298,7 +298,7 @@ pub fn expand_speculative( // prefer tokens of the same kind and text // Note the inversion of the score here, as we want to prefer the first token in case // of all tokens having the same score - (t.kind() != token_to_map.kind()) as u8 + (t.text() != token_to_map.text()) as u8 + (t.kind() != token_to_map.kind()) as u8 + 2 * ((t.text() != token_to_map.text()) as u8) })?; Some((node.syntax_node(), token)) } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs index 04a4851ddb72..1ba85c5c7eac 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs @@ -153,24 +153,20 @@ impl InFileWrapper { // region:specific impls impl InFile<&SyntaxNode> { - /// Skips the attributed item that caused the macro invocation we are climbing up - pub fn ancestors_with_macros_skip_attr_item( + /// Traverse up macro calls and skips the macro invocation node + pub fn ancestors_with_macros( self, db: &dyn db::ExpandDatabase, ) -> impl Iterator> + '_ { let succ = move |node: &InFile| match node.value.parent() { Some(parent) => Some(node.with_value(parent)), - None => { - let macro_file_id = node.file_id.macro_file()?; - let parent_node = macro_file_id.call_node(db); - if macro_file_id.is_attr_macro(db) { - // macro call was an attributed item, skip it - // FIXME: does this fail if this is a direct expansion of another macro? - parent_node.map(|node| node.parent()).transpose() - } else { - Some(parent_node) - } - } + None => db + .lookup_intern_macro_call(node.file_id.macro_file()?.macro_call_id) + .to_node_item(db) + .syntax() + .cloned() + .map(|node| node.parent()) + .transpose(), }; iter::successors(succ(&self.cloned()), succ) } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index 4ab989bec2f0..83e92565f4d8 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -33,8 +33,8 @@ use std::{fmt, hash::Hash}; use base_db::{salsa::impl_intern_value_trivial, CrateId, FileId}; use either::Either; use span::{ - Edition, ErasedFileAstId, FileRange, HirFileIdRepr, Span, SpanAnchor, SyntaxContextData, - SyntaxContextId, + Edition, ErasedFileAstId, FileAstId, FileRange, HirFileIdRepr, Span, SpanAnchor, + SyntaxContextData, SyntaxContextId, }; use syntax::{ ast::{self, AstNode}, @@ -546,6 +546,18 @@ impl MacroCallLoc { } } + pub fn to_node_item(&self, db: &dyn ExpandDatabase) -> InFile { + match self.kind { + MacroCallKind::FnLike { ast_id, .. } => { + InFile::new(ast_id.file_id, ast_id.map(FileAstId::upcast).to_node(db)) + } + MacroCallKind::Derive { ast_id, .. } => { + InFile::new(ast_id.file_id, ast_id.map(FileAstId::upcast).to_node(db)) + } + MacroCallKind::Attr { ast_id, .. } => InFile::new(ast_id.file_id, ast_id.to_node(db)), + } + } + fn expand_to(&self) -> ExpandTo { match self.kind { MacroCallKind::FnLike { expand_to, .. } => expand_to, diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 6c70cc4baf0a..43de2a6ee7dc 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -380,6 +380,27 @@ impl<'db> SemanticsImpl<'db> { self.with_ctx(|ctx| ctx.has_derives(adt)) } + pub fn derive_helper(&self, attr: &ast::Attr) -> Option> { + let adt = attr.syntax().ancestors().find_map(ast::Item::cast).and_then(|it| match it { + ast::Item::Struct(it) => Some(ast::Adt::Struct(it)), + ast::Item::Enum(it) => Some(ast::Adt::Enum(it)), + ast::Item::Union(it) => Some(ast::Adt::Union(it)), + _ => None, + })?; + let attr_name = attr.path().and_then(|it| it.as_single_name_ref())?.as_name(); + let sa = self.analyze_no_infer(adt.syntax())?; + let id = self.db.ast_id_map(sa.file_id).ast_id(&adt); + let res: Vec<_> = sa + .resolver + .def_map() + .derive_helpers_in_scope(InFile::new(sa.file_id, id))? + .iter() + .filter(|&(name, _, _)| *name == attr_name) + .map(|&(_, macro_, call)| (macro_.into(), call.as_macro_file())) + .collect(); + res.is_empty().not().then_some(res) + } + pub fn is_attr_macro_call(&self, item: &ast::Item) -> bool { let file_id = self.find_file(item.syntax()).file_id; let src = InFile::new(file_id, item.clone()); @@ -409,6 +430,20 @@ impl<'db> SemanticsImpl<'db> { ) } + pub fn speculative_expand_raw( + &self, + macro_file: MacroFileId, + speculative_args: &SyntaxNode, + token_to_map: SyntaxToken, + ) -> Option<(SyntaxNode, SyntaxToken)> { + hir_expand::db::expand_speculative( + self.db.upcast(), + macro_file.macro_call_id, + speculative_args, + token_to_map, + ) + } + /// Expand the macro call with a different item as the input, mapping the `token_to_map` down into the /// expansion. `token_to_map` should be a token from the `speculative args` node. pub fn speculative_expand_attr_macro( @@ -826,107 +861,109 @@ impl<'db> SemanticsImpl<'db> { // Then check for token trees, that means we are either in a function-like macro or // secondary attribute inputs - let tt = token.parent_ancestors().map_while(ast::TokenTree::cast).last()?; - let parent = tt.syntax().parent()?; - - if tt.left_delimiter_token().map_or(false, |it| it == token) { - return None; - } - if tt.right_delimiter_token().map_or(false, |it| it == token) { - return None; - } - - if let Some(macro_call) = ast::MacroCall::cast(parent.clone()) { - let mcall: hir_expand::files::InFileWrapper = - InFile::new(file_id, macro_call); - let file_id = match mcache.get(&mcall) { - Some(&it) => it, - None => { - let it = sa.expand(self.db, mcall.as_ref())?; - mcache.insert(mcall, it); - it + let tt = token + .parent_ancestors() + .map_while(Either::::cast) + .last()?; + match tt { + Either::Left(tt) => { + if tt.left_delimiter_token().map_or(false, |it| it == token) { + return None; } - }; - let text_range = tt.syntax().text_range(); - // remove any other token in this macro input, all their mappings are the - // same as this one - tokens.retain(|t| !text_range.contains_range(t.text_range())); - - process_expansion_for_token(&mut stack, file_id).or(file_id - .eager_arg(self.db.upcast()) - .and_then(|arg| { - // also descend into eager expansions - process_expansion_for_token(&mut stack, arg.as_macro_file()) - })) - } else if let Some(meta) = ast::Meta::cast(parent) { - // attribute we failed expansion for earlier, this might be a derive invocation - // or derive helper attribute - let attr = meta.parent_attr()?; - - let adt = if let Some(adt) = attr.syntax().parent().and_then(ast::Adt::cast) - { - // this might be a derive, or a derive helper on an ADT - let derive_call = self.with_ctx(|ctx| { - // so try downmapping the token into the pseudo derive expansion - // see [hir_expand::builtin_attr_macro] for how the pseudo derive expansion works - ctx.attr_to_derive_macro_call( - InFile::new(file_id, &adt), - InFile::new(file_id, attr.clone()), - ) - .map(|(_, call_id, _)| call_id) - }); - - match derive_call { - Some(call_id) => { - // resolved to a derive - let file_id = call_id.as_macro_file(); - let text_range = attr.syntax().text_range(); - // remove any other token in this macro input, all their mappings are the - // same as this one - tokens.retain(|t| !text_range.contains_range(t.text_range())); - return process_expansion_for_token(&mut stack, file_id); + if tt.right_delimiter_token().map_or(false, |it| it == token) { + return None; + } + let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?; + let mcall: hir_expand::files::InFileWrapper = + InFile::new(file_id, macro_call); + let file_id = match mcache.get(&mcall) { + Some(&it) => it, + None => { + let it = sa.expand(self.db, mcall.as_ref())?; + mcache.insert(mcall, it); + it } - None => Some(adt), - } - } else { - // Otherwise this could be a derive helper on a variant or field - if let Some(field) = - attr.syntax().parent().and_then(ast::RecordField::cast) - { - field.syntax().ancestors().take(4).find_map(ast::Adt::cast) - } else if let Some(field) = - attr.syntax().parent().and_then(ast::TupleField::cast) - { - field.syntax().ancestors().take(4).find_map(ast::Adt::cast) - } else if let Some(variant) = - attr.syntax().parent().and_then(ast::Variant::cast) - { - variant.syntax().ancestors().nth(2).and_then(ast::Adt::cast) - } else { - None - } - }?; - if !self.with_ctx(|ctx| ctx.has_derives(InFile::new(file_id, &adt))) { - return None; + }; + let text_range = tt.syntax().text_range(); + // remove any other token in this macro input, all their mappings are the + // same as this one + tokens.retain(|t| !text_range.contains_range(t.text_range())); + + process_expansion_for_token(&mut stack, file_id).or(file_id + .eager_arg(self.db.upcast()) + .and_then(|arg| { + // also descend into eager expansions + process_expansion_for_token(&mut stack, arg.as_macro_file()) + })) } - // Not an attribute, nor a derive, so it's either a builtin or a derive helper - // Try to resolve to a derive helper and downmap - let attr_name = - attr.path().and_then(|it| it.as_single_name_ref())?.as_name(); - let id = self.db.ast_id_map(file_id).ast_id(&adt); - let helpers = def_map.derive_helpers_in_scope(InFile::new(file_id, id))?; - let mut res = None; - for (.., derive) in - helpers.iter().filter(|(helper, ..)| *helper == attr_name) - { - res = res.or(process_expansion_for_token( - &mut stack, - derive.as_macro_file(), - )); + Either::Right(meta) => { + // attribute we failed expansion for earlier, this might be a derive invocation + // or derive helper attribute + let attr = meta.parent_attr()?; + let adt = match attr.syntax().parent().and_then(ast::Adt::cast) { + Some(adt) => { + // this might be a derive on an ADT + let derive_call = self.with_ctx(|ctx| { + // so try downmapping the token into the pseudo derive expansion + // see [hir_expand::builtin_attr_macro] for how the pseudo derive expansion works + ctx.attr_to_derive_macro_call( + InFile::new(file_id, &adt), + InFile::new(file_id, attr.clone()), + ) + .map(|(_, call_id, _)| call_id) + }); + + match derive_call { + Some(call_id) => { + // resolved to a derive + let file_id = call_id.as_macro_file(); + let text_range = attr.syntax().text_range(); + // remove any other token in this macro input, all their mappings are the + // same as this + tokens.retain(|t| { + !text_range.contains_range(t.text_range()) + }); + return process_expansion_for_token( + &mut stack, file_id, + ); + } + None => Some(adt), + } + } + None => { + // Otherwise this could be a derive helper on a variant or field + attr.syntax().ancestors().find_map(ast::Item::cast).and_then( + |it| match it { + ast::Item::Struct(it) => Some(ast::Adt::Struct(it)), + ast::Item::Enum(it) => Some(ast::Adt::Enum(it)), + ast::Item::Union(it) => Some(ast::Adt::Union(it)), + _ => None, + }, + ) + } + }?; + if !self.with_ctx(|ctx| ctx.has_derives(InFile::new(file_id, &adt))) { + return None; + } + let attr_name = + attr.path().and_then(|it| it.as_single_name_ref())?.as_name(); + // Not an attribute, nor a derive, so it's either a builtin or a derive helper + // Try to resolve to a derive helper and downmap + let id = self.db.ast_id_map(file_id).ast_id(&adt); + let helpers = + def_map.derive_helpers_in_scope(InFile::new(file_id, id))?; + + let mut res = None; + for (.., derive) in + helpers.iter().filter(|(helper, ..)| *helper == attr_name) + { + res = res.or(process_expansion_for_token( + &mut stack, + derive.as_macro_file(), + )); + } + res } - res - } else { - None } })() .is_none(); diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index d2bd8b0e799f..77e7cdb58abc 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -139,7 +139,7 @@ impl SourceToDefCtx<'_, '_> { let _p = tracing::span!(tracing::Level::INFO, "module_to_def").entered(); let parent_declaration = src .syntax() - .ancestors_with_macros_skip_attr_item(self.db.upcast()) + .ancestors_with_macros(self.db.upcast()) .find_map(|it| it.map(Either::::cast).transpose()) .map(|it| it.transpose()); @@ -366,7 +366,7 @@ impl SourceToDefCtx<'_, '_> { } pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option { - for container in src.ancestors_with_macros_skip_attr_item(self.db.upcast()) { + for container in src.ancestors_with_macros(self.db.upcast()) { if let Some(res) = self.container_to_def(container) { return Some(res); } @@ -420,7 +420,7 @@ impl SourceToDefCtx<'_, '_> { } fn find_generic_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option { - let ancestors = src.ancestors_with_macros_skip_attr_item(self.db.upcast()); + let ancestors = src.ancestors_with_macros(self.db.upcast()); for InFile { file_id, value } in ancestors { let item = match ast::Item::cast(value) { Some(it) => it, @@ -429,6 +429,7 @@ impl SourceToDefCtx<'_, '_> { let res: GenericDefId = match item { ast::Item::Fn(it) => self.fn_to_def(InFile::new(file_id, it))?.into(), ast::Item::Struct(it) => self.struct_to_def(InFile::new(file_id, it))?.into(), + ast::Item::Union(it) => self.union_to_def(InFile::new(file_id, it))?.into(), ast::Item::Enum(it) => self.enum_to_def(InFile::new(file_id, it))?.into(), ast::Item::Trait(it) => self.trait_to_def(InFile::new(file_id, it))?.into(), ast::Item::TraitAlias(it) => { @@ -446,11 +447,18 @@ impl SourceToDefCtx<'_, '_> { } fn find_pat_or_label_container(&mut self, src: InFile<&SyntaxNode>) -> Option { - let ancestors = src.ancestors_with_macros_skip_attr_item(self.db.upcast()); + let ancestors = src.ancestors_with_macros(self.db.upcast()); for InFile { file_id, value } in ancestors { - let item = match ast::Item::cast(value) { + let item = match ast::Item::cast(value.clone()) { Some(it) => it, - None => continue, + None => { + if let Some(variant) = ast::Variant::cast(value.clone()) { + return self + .enum_variant_to_def(InFile::new(file_id, variant)) + .map(Into::into); + } + continue; + } }; let res: DefWithBodyId = match item { ast::Item::Const(it) => self.const_to_def(InFile::new(file_id, it))?.into(), diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search.rs b/src/tools/rust-analyzer/crates/hir/src/term_search.rs index 5c5ddae19e27..7b70cdf45994 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search.rs @@ -329,7 +329,7 @@ pub fn term_search(ctx: &TermSearchCtx<'_, DB>) -> Vec { while should_continue() { lookup.new_round(); - solutions.extend(tactics::type_constructor(ctx, &defs, &mut lookup, should_continue)); + solutions.extend(tactics::data_constructor(ctx, &defs, &mut lookup, should_continue)); solutions.extend(tactics::free_function(ctx, &defs, &mut lookup, should_continue)); solutions.extend(tactics::impl_method(ctx, &defs, &mut lookup, should_continue)); solutions.extend(tactics::struct_projection(ctx, &defs, &mut lookup, should_continue)); diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs index a26728272dc6..f95ff1dc0fa1 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs @@ -87,9 +87,9 @@ pub(super) fn trivial<'a, DB: HirDatabase>( }) } -/// # Type constructor tactic +/// # Data constructor tactic /// -/// Attempts different type constructors for enums and structs in scope +/// Attempts different data constructors for enums and structs in scope /// /// Updates lookup by new types reached and returns iterator that yields /// elements that unify with `goal`. @@ -99,7 +99,7 @@ pub(super) fn trivial<'a, DB: HirDatabase>( /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types /// * `should_continue` - Function that indicates when to stop iterating -pub(super) fn type_constructor<'a, DB: HirDatabase>( +pub(super) fn data_constructor<'a, DB: HirDatabase>( ctx: &'a TermSearchCtx<'a, DB>, defs: &'a FxHashSet, lookup: &'a mut LookupTable, @@ -308,7 +308,9 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>( // Early exit if some param cannot be filled from lookup let param_exprs: Vec> = fields .into_iter() - .map(|field| lookup.find(db, &field.ty(db))) + .map(|field| { + lookup.find(db, &field.ty_with_args(db, generics.iter().cloned())) + }) .collect::>()?; // Note that we need special case for 0 param constructors because of multi cartesian diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs new file mode 100644 index 000000000000..953119fd1ff9 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs @@ -0,0 +1,685 @@ +use itertools::Itertools; +use syntax::{ + ast::{self, edit::IndentLevel, Comment, CommentPlacement, Whitespace}, + AstToken, Direction, SyntaxElement, TextRange, +}; + +use crate::{AssistContext, AssistId, AssistKind, Assists}; + +// Assist: comment_to_doc +// +// Converts comments to documentation. +// +// ``` +// // Wow what $0a nice module +// // I sure hope this shows up when I hover over it +// ``` +// -> +// ``` +// //! Wow what a nice module +// //! I sure hope this shows up when I hover over it +// ``` +pub(crate) fn convert_comment_from_or_to_doc( + acc: &mut Assists, + ctx: &AssistContext<'_>, +) -> Option<()> { + let comment = ctx.find_token_at_offset::()?; + + match comment.kind().doc { + Some(_) => doc_to_comment(acc, comment), + None => can_be_doc_comment(&comment).and_then(|style| comment_to_doc(acc, comment, style)), + } +} + +fn doc_to_comment(acc: &mut Assists, comment: ast::Comment) -> Option<()> { + let target = if comment.kind().shape.is_line() { + line_comments_text_range(&comment)? + } else { + comment.syntax().text_range() + }; + + acc.add( + AssistId("doc_to_comment", AssistKind::RefactorRewrite), + "Replace comment with doc comment", + target, + |edit| { + // We need to either replace the first occurrence of /* with /***, or we need to replace + // the occurrences // at the start of each line with /// + let output = match comment.kind().shape { + ast::CommentShape::Line => { + let indentation = IndentLevel::from_token(comment.syntax()); + let line_start = comment.prefix(); + let prefix = format!("{indentation}//"); + relevant_line_comments(&comment) + .iter() + .map(|comment| comment.text()) + .flat_map(|text| text.lines()) + .map(|line| line.replacen(line_start, &prefix, 1)) + .join("\n") + } + ast::CommentShape::Block => { + let block_start = comment.prefix(); + comment + .text() + .lines() + .enumerate() + .map(|(idx, line)| { + if idx == 0 { + line.replacen(block_start, "/*", 1) + } else { + line.replacen("* ", "* ", 1) + } + }) + .join("\n") + } + }; + edit.replace(target, output) + }, + ) +} + +fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacement) -> Option<()> { + let target = if comment.kind().shape.is_line() { + line_comments_text_range(&comment)? + } else { + comment.syntax().text_range() + }; + + acc.add( + AssistId("comment_to_doc", AssistKind::RefactorRewrite), + "Replace doc comment with comment", + target, + |edit| { + // We need to either replace the first occurrence of /* with /***, or we need to replace + // the occurrences // at the start of each line with /// + let output = match comment.kind().shape { + ast::CommentShape::Line => { + let indentation = IndentLevel::from_token(comment.syntax()); + let line_start = match style { + CommentPlacement::Inner => format!("{indentation}//!"), + CommentPlacement::Outer => format!("{indentation}///"), + }; + relevant_line_comments(&comment) + .iter() + .map(|comment| comment.text()) + .flat_map(|text| text.lines()) + .map(|line| line.replacen("//", &line_start, 1)) + .join("\n") + } + ast::CommentShape::Block => { + let block_start = match style { + CommentPlacement::Inner => "/*!", + CommentPlacement::Outer => "/**", + }; + comment + .text() + .lines() + .enumerate() + .map(|(idx, line)| { + if idx == 0 { + // On the first line we replace the comment start with a doc comment + // start. + line.replacen("/*", block_start, 1) + } else { + // put one extra space after each * since we moved the first line to + // the right by one column as well. + line.replacen("* ", "* ", 1) + } + }) + .join("\n") + } + }; + edit.replace(target, output) + }, + ) +} + +/// Not all comments are valid candidates for conversion into doc comments. For example, the +/// comments in the code: +/// ```rust +/// // Brilliant module right here +/// +/// // Really good right +/// fn good_function(foo: Foo) -> Bar { +/// foo.into_bar() +/// } +/// +/// // So nice +/// mod nice_module {} +/// ``` +/// can be converted to doc comments. However, the comments in this example: +/// ```rust +/// fn foo_bar(foo: Foo /* not bar yet */) -> Bar { +/// foo.into_bar() +/// // Nicely done +/// } +/// // end of function +/// +/// struct S { +/// // The S struct +/// } +/// ``` +/// are not allowed to become doc comments. Moreover, some comments _are_ allowed, but aren't common +/// style in Rust. For example, the following comments are allowed to be doc comments, but it is not +/// common style for them to be: +/// ```rust +/// fn foo_bar(foo: Foo) -> Bar { +/// // this could be an inner comment with //! +/// foo.into_bar() +/// } +/// +/// trait T { +/// // The T struct could also be documented from within +/// } +/// +/// mod mymod { +/// // Modules only normally get inner documentation when they are defined as a separate file. +/// } +/// ``` +fn can_be_doc_comment(comment: &ast::Comment) -> Option { + use syntax::SyntaxKind::*; + + // if the comment is not on its own line, then we do not propose anything. + match comment.syntax().prev_token() { + Some(prev) => { + // There was a previous token, now check if it was a newline + Whitespace::cast(prev).filter(|w| w.text().contains('\n'))?; + } + // There is no previous token, this is the start of the file. + None => return Some(CommentPlacement::Inner), + } + + // check if comment is followed by: `struct`, `trait`, `mod`, `fn`, `type`, `extern crate`, + // `use` or `const`. + let parent = comment.syntax().parent(); + let par_kind = parent.as_ref().map(|parent| parent.kind()); + matches!(par_kind, Some(STRUCT | TRAIT | MODULE | FN | TYPE_ALIAS | EXTERN_CRATE | USE | CONST)) + .then_some(CommentPlacement::Outer) +} + +/// The line -> block assist can be invoked from anywhere within a sequence of line comments. +/// relevant_line_comments crawls backwards and forwards finding the complete sequence of comments that will +/// be joined. +pub(crate) fn relevant_line_comments(comment: &ast::Comment) -> Vec { + // The prefix identifies the kind of comment we're dealing with + let prefix = comment.prefix(); + let same_prefix = |c: &ast::Comment| c.prefix() == prefix; + + // These tokens are allowed to exist between comments + let skippable = |not: &SyntaxElement| { + not.clone() + .into_token() + .and_then(Whitespace::cast) + .map(|w| !w.spans_multiple_lines()) + .unwrap_or(false) + }; + + // Find all preceding comments (in reverse order) that have the same prefix + let prev_comments = comment + .syntax() + .siblings_with_tokens(Direction::Prev) + .filter(|s| !skippable(s)) + .map(|not| not.into_token().and_then(Comment::cast).filter(same_prefix)) + .take_while(|opt_com| opt_com.is_some()) + .flatten() + .skip(1); // skip the first element so we don't duplicate it in next_comments + + let next_comments = comment + .syntax() + .siblings_with_tokens(Direction::Next) + .filter(|s| !skippable(s)) + .map(|not| not.into_token().and_then(Comment::cast).filter(same_prefix)) + .take_while(|opt_com| opt_com.is_some()) + .flatten(); + + let mut comments: Vec<_> = prev_comments.collect(); + comments.reverse(); + comments.extend(next_comments); + comments +} + +fn line_comments_text_range(comment: &ast::Comment) -> Option { + let comments = relevant_line_comments(comment); + let first = comments.first()?; + let indentation = IndentLevel::from_token(first.syntax()); + let start = + first.syntax().text_range().start().checked_sub((indentation.0 as u32 * 4).into())?; + let end = comments.last()?.syntax().text_range().end(); + Some(TextRange::new(start, end)) +} + +#[cfg(test)] +mod tests { + use crate::tests::{check_assist, check_assist_not_applicable}; + + use super::*; + + #[test] + fn module_comment_to_doc() { + check_assist( + convert_comment_from_or_to_doc, + r#" + // such a nice module$0 + fn main() { + foo(); + } + "#, + r#" + //! such a nice module + fn main() { + foo(); + } + "#, + ); + } + + #[test] + fn single_line_comment_to_doc() { + check_assist( + convert_comment_from_or_to_doc, + r#" + + // unseen$0 docs + fn main() { + foo(); + } + "#, + r#" + + /// unseen docs + fn main() { + foo(); + } + "#, + ); + } + + #[test] + fn multi_line_comment_to_doc() { + check_assist( + convert_comment_from_or_to_doc, + r#" + + // unseen$0 docs + // make me seen! + fn main() { + foo(); + } + "#, + r#" + + /// unseen docs + /// make me seen! + fn main() { + foo(); + } + "#, + ); + } + + #[test] + fn single_line_doc_to_comment() { + check_assist( + convert_comment_from_or_to_doc, + r#" + + /// visible$0 docs + fn main() { + foo(); + } + "#, + r#" + + // visible docs + fn main() { + foo(); + } + "#, + ); + } + + #[test] + fn multi_line_doc_to_comment() { + check_assist( + convert_comment_from_or_to_doc, + r#" + + /// visible$0 docs + /// Hide me! + fn main() { + foo(); + } + "#, + r#" + + // visible docs + // Hide me! + fn main() { + foo(); + } + "#, + ); + } + + #[test] + fn single_line_block_comment_to_doc() { + check_assist( + convert_comment_from_or_to_doc, + r#" + + /* unseen$0 docs */ + fn main() { + foo(); + } + "#, + r#" + + /** unseen docs */ + fn main() { + foo(); + } + "#, + ); + } + + #[test] + fn multi_line_block_comment_to_doc() { + check_assist( + convert_comment_from_or_to_doc, + r#" + + /* unseen$0 docs + * make me seen! + */ + fn main() { + foo(); + } + "#, + r#" + + /** unseen docs + * make me seen! + */ + fn main() { + foo(); + } + "#, + ); + } + + #[test] + fn single_line_block_doc_to_comment() { + check_assist( + convert_comment_from_or_to_doc, + r#" + + /** visible$0 docs */ + fn main() { + foo(); + } + "#, + r#" + + /* visible docs */ + fn main() { + foo(); + } + "#, + ); + } + + #[test] + fn multi_line_block_doc_to_comment() { + check_assist( + convert_comment_from_or_to_doc, + r#" + + /** visible$0 docs + * Hide me! + */ + fn main() { + foo(); + } + "#, + r#" + + /* visible docs + * Hide me! + */ + fn main() { + foo(); + } + "#, + ); + } + + #[test] + fn single_inner_line_comment_to_doc() { + check_assist_not_applicable( + convert_comment_from_or_to_doc, + r#" + mod mymod { + // unseen$0 docs + foo(); + } + "#, + ); + } + + #[test] + fn single_inner_line_doc_to_comment() { + check_assist( + convert_comment_from_or_to_doc, + r#" + mod mymod { + //! visible$0 docs + foo(); + } + "#, + r#" + mod mymod { + // visible docs + foo(); + } + "#, + ); + } + + #[test] + fn multi_inner_line_doc_to_comment() { + check_assist( + convert_comment_from_or_to_doc, + r#" + mod mymod { + //! visible$0 docs + //! Hide me! + foo(); + } + "#, + r#" + mod mymod { + // visible docs + // Hide me! + foo(); + } + "#, + ); + check_assist( + convert_comment_from_or_to_doc, + r#" + mod mymod { + /// visible$0 docs + /// Hide me! + foo(); + } + "#, + r#" + mod mymod { + // visible docs + // Hide me! + foo(); + } + "#, + ); + } + + #[test] + fn single_inner_line_block_doc_to_comment() { + check_assist( + convert_comment_from_or_to_doc, + r#" + mod mymod { + /*! visible$0 docs */ + type Int = i32; + } + "#, + r#" + mod mymod { + /* visible docs */ + type Int = i32; + } + "#, + ); + } + + #[test] + fn multi_inner_line_block_doc_to_comment() { + check_assist( + convert_comment_from_or_to_doc, + r#" + mod mymod { + /*! visible$0 docs + * Hide me! + */ + type Int = i32; + } + "#, + r#" + mod mymod { + /* visible docs + * Hide me! + */ + type Int = i32; + } + "#, + ); + } + + #[test] + fn not_overeager() { + check_assist_not_applicable( + convert_comment_from_or_to_doc, + r#" + fn main() { + foo(); + // $0well that settles main + } + // $1 nicely done + "#, + ); + } + + #[test] + fn all_possible_items() { + check_assist( + convert_comment_from_or_to_doc, + r#"mod m { + /* Nice struct$0 */ + struct S {} + }"#, + r#"mod m { + /** Nice struct */ + struct S {} + }"#, + ); + check_assist( + convert_comment_from_or_to_doc, + r#"mod m { + /* Nice trait$0 */ + trait T {} + }"#, + r#"mod m { + /** Nice trait */ + trait T {} + }"#, + ); + check_assist( + convert_comment_from_or_to_doc, + r#"mod m { + /* Nice module$0 */ + mod module {} + }"#, + r#"mod m { + /** Nice module */ + mod module {} + }"#, + ); + check_assist( + convert_comment_from_or_to_doc, + r#"mod m { + /* Nice function$0 */ + fn function() {} + }"#, + r#"mod m { + /** Nice function */ + fn function() {} + }"#, + ); + check_assist( + convert_comment_from_or_to_doc, + r#"mod m { + /* Nice type$0 */ + type Type Int = i32; + }"#, + r#"mod m { + /** Nice type */ + type Type Int = i32; + }"#, + ); + check_assist( + convert_comment_from_or_to_doc, + r#"mod m { + /* Nice crate$0 */ + extern crate rust_analyzer; + }"#, + r#"mod m { + /** Nice crate */ + extern crate rust_analyzer; + }"#, + ); + check_assist( + convert_comment_from_or_to_doc, + r#"mod m { + /* Nice import$0 */ + use ide_assists::convert_comment_from_or_to_doc::tests + }"#, + r#"mod m { + /** Nice import */ + use ide_assists::convert_comment_from_or_to_doc::tests + }"#, + ); + check_assist( + convert_comment_from_or_to_doc, + r#"mod m { + /* Nice constant$0 */ + const CONST: &str = "very const"; + }"#, + r#"mod m { + /** Nice constant */ + const CONST: &str = "very const"; + }"#, + ); + } + + #[test] + fn no_inner_comments() { + check_assist_not_applicable( + convert_comment_from_or_to_doc, + r#" + mod mymod { + // aaa$0aa + } + "#, + ); + } +} diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs index ffd1508ccbdc..94e0519cba0b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs @@ -278,4 +278,16 @@ fn f() { let a = 1; let b = 0.0; let c: (i32, (i32, f64)) = todo$0!(); }"#, r#"fn f() { let a = 1; let b = 0.0; let c: (i32, (i32, f64)) = (a, (a, b)); }"#, ) } + + #[test] + fn test_tuple_struct_with_generics() { + check_assist( + term_search, + r#"//- minicore: todo, unimplemented +struct Foo(T); +fn f() { let a = 1; let b: Foo = todo$0!(); }"#, + r#"struct Foo(T); +fn f() { let a = 1; let b: Foo = Foo(a); }"#, + ) + } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs new file mode 100644 index 000000000000..30e09648ea12 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs @@ -0,0 +1,601 @@ +use hir::{ImportPathConfig, ModuleDef}; +use ide_db::{ + assists::{AssistId, AssistKind}, + famous_defs::FamousDefs, +}; +use syntax::{ + ast::{self, HasVisibility}, + AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, +}; + +use crate::{AssistContext, Assists}; + +// Assist: sugar_impl_future_into_async +// +// Rewrites asynchronous function from `-> impl Future` into `async fn`. +// This action does not touch the function body and therefore `async { 0 }` +// block does not transform to just `0`. +// +// ``` +// # //- minicore: future +// pub fn foo() -> impl core::future::F$0uture { +// async { 0 } +// } +// ``` +// -> +// ``` +// pub async fn foo() -> usize { +// async { 0 } +// } +// ``` +pub(crate) fn sugar_impl_future_into_async( + acc: &mut Assists, + ctx: &AssistContext<'_>, +) -> Option<()> { + let ret_type: ast::RetType = ctx.find_node_at_offset()?; + let function = ret_type.syntax().parent().and_then(ast::Fn::cast)?; + + if function.async_token().is_some() || function.const_token().is_some() { + return None; + } + + let ast::Type::ImplTraitType(return_impl_trait) = ret_type.ty()? else { + return None; + }; + + let main_trait_path = return_impl_trait + .type_bound_list()? + .bounds() + .filter_map(|bound| match bound.ty() { + Some(ast::Type::PathType(trait_path)) => trait_path.path(), + _ => None, + }) + .next()?; + + let trait_type = ctx.sema.resolve_trait(&main_trait_path)?; + let scope = ctx.sema.scope(main_trait_path.syntax())?; + if trait_type != FamousDefs(&ctx.sema, scope.krate()).core_future_Future()? { + return None; + } + let future_output = unwrap_future_output(main_trait_path)?; + + acc.add( + AssistId("sugar_impl_future_into_async", AssistKind::RefactorRewrite), + "Convert `impl Future` into async", + function.syntax().text_range(), + |builder| { + match future_output { + // Empty tuple + ast::Type::TupleType(t) if t.fields().next().is_none() => { + let mut ret_type_range = ret_type.syntax().text_range(); + + // find leftover whitespace + let whitespace_range = function + .param_list() + .as_ref() + .map(|params| NodeOrToken::Node(params.syntax())) + .and_then(following_whitespace); + + if let Some(whitespace_range) = whitespace_range { + ret_type_range = + TextRange::new(whitespace_range.start(), ret_type_range.end()); + } + + builder.delete(ret_type_range); + } + _ => { + builder.replace( + return_impl_trait.syntax().text_range(), + future_output.syntax().text(), + ); + } + } + + let (place_for_async, async_kw) = match function.visibility() { + Some(vis) => (vis.syntax().text_range().end(), " async"), + None => (function.syntax().text_range().start(), "async "), + }; + builder.insert(place_for_async, async_kw); + }, + ) +} + +// Assist: desugar_async_into_impl_future +// +// Rewrites asynchronous function from `async fn` into `-> impl Future`. +// This action does not touch the function body and therefore `0` +// block does not transform to `async { 0 }`. +// +// ``` +// # //- minicore: future +// pub as$0ync fn foo() -> usize { +// 0 +// } +// ``` +// -> +// ``` +// pub fn foo() -> impl core::future::Future { +// 0 +// } +// ``` +pub(crate) fn desugar_async_into_impl_future( + acc: &mut Assists, + ctx: &AssistContext<'_>, +) -> Option<()> { + let async_token = ctx.find_token_syntax_at_offset(SyntaxKind::ASYNC_KW)?; + let function = async_token.parent().and_then(ast::Fn::cast)?; + + let rparen = function.param_list()?.r_paren_token()?; + let return_type = match function.ret_type() { + // unable to get a `ty` makes the action unapplicable + Some(ret_type) => Some(ret_type.ty()?), + // No type means `-> ()` + None => None, + }; + + let scope = ctx.sema.scope(function.syntax())?; + let module = scope.module(); + let future_trait = FamousDefs(&ctx.sema, scope.krate()).core_future_Future()?; + let trait_path = module.find_path( + ctx.db(), + ModuleDef::Trait(future_trait), + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, + )?; + let trait_path = trait_path.display(ctx.db()); + + acc.add( + AssistId("desugar_async_into_impl_future", AssistKind::RefactorRewrite), + "Convert async into `impl Future`", + function.syntax().text_range(), + |builder| { + let mut async_range = async_token.text_range(); + + if let Some(whitespace_range) = following_whitespace(NodeOrToken::Token(async_token)) { + async_range = TextRange::new(async_range.start(), whitespace_range.end()); + } + builder.delete(async_range); + + match return_type { + Some(ret_type) => builder.replace( + ret_type.syntax().text_range(), + format!("impl {trait_path}"), + ), + None => builder.insert( + rparen.text_range().end(), + format!(" -> impl {trait_path}"), + ), + } + }, + ) +} + +fn unwrap_future_output(path: ast::Path) -> Option { + let future_trait = path.segments().last()?; + let assoc_list = future_trait.generic_arg_list()?; + let future_assoc = assoc_list.generic_args().next()?; + match future_assoc { + ast::GenericArg::AssocTypeArg(output_type) => output_type.ty(), + _ => None, + } +} + +fn following_whitespace(nt: NodeOrToken<&SyntaxNode, SyntaxToken>) -> Option { + let next_token = match nt { + NodeOrToken::Node(node) => node.next_sibling_or_token(), + NodeOrToken::Token(token) => token.next_sibling_or_token(), + }?; + (next_token.kind() == SyntaxKind::WHITESPACE).then_some(next_token.text_range()) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{check_assist, check_assist_not_applicable}; + + #[test] + fn sugar_with_use() { + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + use core::future::Future; + fn foo() -> impl F$0uture { + todo!() + } + "#, + r#" + use core::future::Future; + async fn foo() { + todo!() + } + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + use core::future::Future; + fn foo() -> impl F$0uture { + todo!() + } + "#, + r#" + use core::future::Future; + async fn foo() -> usize { + todo!() + } + "#, + ); + } + + #[test] + fn desugar_with_use() { + check_assist( + desugar_async_into_impl_future, + r#" + //- minicore: future + use core::future::Future; + as$0ync fn foo() { + todo!() + } + "#, + r#" + use core::future::Future; + fn foo() -> impl Future { + todo!() + } + "#, + ); + + check_assist( + desugar_async_into_impl_future, + r#" + //- minicore: future + use core::future; + as$0ync fn foo() { + todo!() + } + "#, + r#" + use core::future; + fn foo() -> impl future::Future { + todo!() + } + "#, + ); + + check_assist( + desugar_async_into_impl_future, + r#" + //- minicore: future + use core::future::Future; + as$0ync fn foo() -> usize { + todo!() + } + "#, + r#" + use core::future::Future; + fn foo() -> impl Future { + todo!() + } + "#, + ); + + check_assist( + desugar_async_into_impl_future, + r#" + //- minicore: future + use core::future::Future; + as$0ync fn foo() -> impl Future { + todo!() + } + "#, + r#" + use core::future::Future; + fn foo() -> impl Future> { + todo!() + } + "#, + ); + } + + #[test] + fn sugar_without_use() { + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::F$0uture { + todo!() + } + "#, + r#" + async fn foo() { + todo!() + } + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::F$0uture { + todo!() + } + "#, + r#" + async fn foo() -> usize { + todo!() + } + "#, + ); + } + + #[test] + fn desugar_without_use() { + check_assist( + desugar_async_into_impl_future, + r#" + //- minicore: future + as$0ync fn foo() { + todo!() + } + "#, + r#" + fn foo() -> impl core::future::Future { + todo!() + } + "#, + ); + + check_assist( + desugar_async_into_impl_future, + r#" + //- minicore: future + as$0ync fn foo() -> usize { + todo!() + } + "#, + r#" + fn foo() -> impl core::future::Future { + todo!() + } + "#, + ); + } + + #[test] + fn not_applicable() { + check_assist_not_applicable( + sugar_impl_future_into_async, + r#" + //- minicore: future + trait Future { + type Output; + } + fn foo() -> impl F$0uture { + todo!() + } + "#, + ); + + check_assist_not_applicable( + sugar_impl_future_into_async, + r#" + //- minicore: future + trait Future { + type Output; + } + fn foo() -> impl F$0uture { + todo!() + } + "#, + ); + + check_assist_not_applicable( + sugar_impl_future_into_async, + r#" + //- minicore: future + f$0n foo() -> impl core::future::Future { + todo!() + } + "#, + ); + + check_assist_not_applicable( + desugar_async_into_impl_future, + r#" + async f$0n foo() { + todo!() + } + "#, + ); + } + + #[test] + fn sugar_definition_with_use() { + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + use core::future::Future; + fn foo() -> impl F$0uture; + "#, + r#" + use core::future::Future; + async fn foo(); + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + use core::future::Future; + fn foo() -> impl F$0uture; + "#, + r#" + use core::future::Future; + async fn foo() -> usize; + "#, + ); + } + + #[test] + fn sugar_definition_without_use() { + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::F$0uture; + "#, + r#" + async fn foo(); + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::F$0uture; + "#, + r#" + async fn foo() -> usize; + "#, + ); + } + + #[test] + fn sugar_more_types() { + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::F$0uture + Send + Sync; + "#, + r#" + async fn foo(); + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::F$0uture + Debug; + "#, + r#" + async fn foo() -> usize; + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::F$0uture + Debug; + "#, + r#" + async fn foo() -> (usize); + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::F$0uture + Debug; + "#, + r#" + async fn foo() -> (usize, usize); + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::Future + Send>; + "#, + r#" + async fn foo() -> impl core::future::Future + Send; + "#, + ); + } + + #[test] + fn sugar_with_modifiers() { + check_assist_not_applicable( + sugar_impl_future_into_async, + r#" + //- minicore: future + const fn foo() -> impl core::future::F$0uture; + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + pub(crate) unsafe fn foo() -> impl core::future::F$0uture; + "#, + r#" + pub(crate) async unsafe fn foo() -> usize; + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + unsafe fn foo() -> impl core::future::F$0uture; + "#, + r#" + async unsafe fn foo(); + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + unsafe extern "C" fn foo() -> impl core::future::F$0uture; + "#, + r#" + async unsafe extern "C" fn foo(); + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::F$0uture; + "#, + r#" + async fn foo() -> T; + "#, + ); + + check_assist( + sugar_impl_future_into_async, + r#" + //- minicore: future + fn foo() -> impl core::future::F$0uture + where + T: Sized; + "#, + r#" + async fn foo() -> T + where + T: Sized; + "#, + ); + } +} diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs index 0df5e913a573..abebdec1d18c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs @@ -116,6 +116,7 @@ mod handlers { mod change_visibility; mod convert_bool_then; mod convert_comment_block; + mod convert_comment_from_or_to_doc; mod convert_from_to_tryfrom; mod convert_integer_literal; mod convert_into_to_from; @@ -209,6 +210,7 @@ mod handlers { mod sort_items; mod split_import; mod term_search; + mod toggle_async_sugar; mod toggle_ignore; mod unmerge_match_arm; mod unmerge_use; @@ -238,7 +240,10 @@ mod handlers { change_visibility::change_visibility, convert_bool_then::convert_bool_then_to_if, convert_bool_then::convert_if_to_bool_then, + toggle_async_sugar::desugar_async_into_impl_future, + toggle_async_sugar::sugar_impl_future_into_async, convert_comment_block::convert_comment_block, + convert_comment_from_or_to_doc::convert_comment_from_or_to_doc, convert_from_to_tryfrom::convert_from_to_tryfrom, convert_integer_literal::convert_integer_literal, convert_into_to_from::convert_into_to_from, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 937e78f8d7d2..eec1087e2df1 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -345,6 +345,21 @@ pub(crate) fn frobnicate() {} ) } +#[test] +fn doctest_comment_to_doc() { + check_doc_test( + "comment_to_doc", + r#####" +// Wow what $0a nice module +// I sure hope this shows up when I hover over it +"#####, + r#####" +//! Wow what a nice module +//! I sure hope this shows up when I hover over it +"#####, + ) +} + #[test] fn doctest_convert_bool_then_to_if() { check_doc_test( @@ -800,6 +815,24 @@ fn main() { ) } +#[test] +fn doctest_desugar_async_into_impl_future() { + check_doc_test( + "desugar_async_into_impl_future", + r#####" +//- minicore: future +pub as$0ync fn foo() -> usize { + 0 +} +"#####, + r#####" +pub fn foo() -> impl core::future::Future { + 0 +} +"#####, + ) +} + #[test] fn doctest_desugar_doc_comment() { check_doc_test( @@ -3020,6 +3053,24 @@ use std::{collections::HashMap}; ) } +#[test] +fn doctest_sugar_impl_future_into_async() { + check_doc_test( + "sugar_impl_future_into_async", + r#####" +//- minicore: future +pub fn foo() -> impl core::future::F$0uture { + async { 0 } +} +"#####, + r#####" +pub async fn foo() -> usize { + async { 0 } +} +"#####, + ) +} + #[test] fn doctest_toggle_ignore() { check_doc_test( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index 79c503e0a10d..f0c6e7a63b00 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -3,8 +3,9 @@ use std::iter; use hir::{Semantics, Type, TypeInfo, Variant}; use ide_db::{active_parameter::ActiveParameter, RootDatabase}; +use itertools::Either; use syntax::{ - algo::{find_node_at_offset, non_trivia_sibling}, + algo::{ancestors_at_offset, find_node_at_offset, non_trivia_sibling}, ast::{self, AttrKind, HasArgList, HasGenericParams, HasLoopBody, HasName, NameOrNameRef}, match_ast, AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize, T, @@ -119,20 +120,45 @@ fn expand( } // No attributes have been expanded, so look for macro_call! token trees or derive token trees - let orig_tt = match find_node_at_offset::(&original_file, offset) { + let orig_tt = match ancestors_at_offset(&original_file, offset) + .map_while(Either::::cast) + .last() + { Some(it) => it, None => break 'expansion, }; - let spec_tt = match find_node_at_offset::(&speculative_file, offset) { + let spec_tt = match ancestors_at_offset(&speculative_file, offset) + .map_while(Either::::cast) + .last() + { Some(it) => it, None => break 'expansion, }; - // Expand pseudo-derive expansion - if let (Some(orig_attr), Some(spec_attr)) = ( - orig_tt.syntax().parent().and_then(ast::Meta::cast).and_then(|it| it.parent_attr()), - spec_tt.syntax().parent().and_then(ast::Meta::cast).and_then(|it| it.parent_attr()), - ) { + let (tts, attrs) = match (orig_tt, spec_tt) { + (Either::Left(orig_tt), Either::Left(spec_tt)) => { + let attrs = orig_tt + .syntax() + .parent() + .and_then(ast::Meta::cast) + .and_then(|it| it.parent_attr()) + .zip( + spec_tt + .syntax() + .parent() + .and_then(ast::Meta::cast) + .and_then(|it| it.parent_attr()), + ); + (Some((orig_tt, spec_tt)), attrs) + } + (Either::Right(orig_path), Either::Right(spec_path)) => { + (None, orig_path.parent_attr().zip(spec_path.parent_attr())) + } + _ => break 'expansion, + }; + + // Expand pseudo-derive expansion aka `derive(Debug$0)` + if let Some((orig_attr, spec_attr)) = attrs { if let (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) = ( sema.expand_derive_as_pseudo_attr_macro(&orig_attr), sema.speculative_expand_derive_as_pseudo_attr_macro( @@ -147,15 +173,54 @@ fn expand( fake_mapped_token.text_range().start(), orig_attr, )); + break 'expansion; + } + + if let Some(spec_adt) = + spec_attr.syntax().ancestors().find_map(ast::Item::cast).and_then(|it| match it { + ast::Item::Struct(it) => Some(ast::Adt::Struct(it)), + ast::Item::Enum(it) => Some(ast::Adt::Enum(it)), + ast::Item::Union(it) => Some(ast::Adt::Union(it)), + _ => None, + }) + { + // might be the path of derive helper or a token tree inside of one + if let Some(helpers) = sema.derive_helper(&orig_attr) { + for (_mac, file) in helpers { + if let Some((fake_expansion, fake_mapped_token)) = sema + .speculative_expand_raw( + file, + spec_adt.syntax(), + fake_ident_token.clone(), + ) + { + // we are inside a derive helper token tree, treat this as being inside + // the derive expansion + let actual_expansion = sema.parse_or_expand(file.into()); + let new_offset = fake_mapped_token.text_range().start(); + if new_offset + relative_offset > actual_expansion.text_range().end() { + // offset outside of bounds from the original expansion, + // stop here to prevent problems from happening + break 'expansion; + } + original_file = actual_expansion; + speculative_file = fake_expansion; + fake_ident_token = fake_mapped_token; + offset = new_offset; + continue 'expansion; + } + } + } } // at this point we won't have any more successful expansions, so stop break 'expansion; } // Expand fn-like macro calls + let Some((orig_tt, spec_tt)) = tts else { break 'expansion }; if let (Some(actual_macro_call), Some(macro_call_with_fake_ident)) = ( - orig_tt.syntax().ancestors().find_map(ast::MacroCall::cast), - spec_tt.syntax().ancestors().find_map(ast::MacroCall::cast), + orig_tt.syntax().parent().and_then(ast::MacroCall::cast), + spec_tt.syntax().parent().and_then(ast::MacroCall::cast), ) { let mac_call_path0 = actual_macro_call.path().as_ref().map(|s| s.syntax().text()); let mac_call_path1 = @@ -201,6 +266,7 @@ fn expand( // none of our states have changed so stop the loop break 'expansion; } + ExpansionResult { original_file, speculative_file, offset, fake_ident_token, derive_ctx } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs index 3106772e63b1..e445e9fb68d6 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs @@ -106,6 +106,10 @@ impl FamousDefs<'_, '_> { self.find_trait("core:marker:Copy") } + pub fn core_future_Future(&self) -> Option { + self.find_trait("core:future:Future") + } + pub fn core_macros_builtin_derive(&self) -> Option { self.find_macro("core:macros:builtin:derive") } diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs b/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs index fab62e95d19a..c19f19803f17 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs @@ -16,7 +16,7 @@ use crate::{ // // This is the same as `Go to Definition` with the following exceptions: // - outline modules will navigate to the `mod name;` item declaration -// - trait assoc items will navigate to the assoc item of the trait declaration opposed to the trait impl +// - trait assoc items will navigate to the assoc item of the trait declaration as opposed to the trait impl // - fields in patterns will navigate to the field declaration of the struct, union or variant pub(crate) fn goto_declaration( db: &RootDatabase, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 79b87ecd58ff..f64e66183d1b 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -87,7 +87,6 @@ pub(crate) struct GlobalState { pub(crate) flycheck_sender: Sender, pub(crate) flycheck_receiver: Receiver, pub(crate) last_flycheck_error: Option, - pub(crate) diagnostics_received: bool, // Test explorer pub(crate) test_run_session: Option>, @@ -225,7 +224,6 @@ impl GlobalState { flycheck_sender, flycheck_receiver, last_flycheck_error: None, - diagnostics_received: false, test_run_session: None, test_run_sender, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index 7acd302867c3..193b3fdd4a8e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -804,10 +804,6 @@ impl GlobalState { fn handle_flycheck_msg(&mut self, message: flycheck::Message) { match message { flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => { - if !self.diagnostics_received { - self.diagnostics.clear_check(id); - self.diagnostics_received = true; - } let snap = self.snapshot(); let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( &self.config.diagnostics_map(), @@ -833,12 +829,11 @@ impl GlobalState { } } + flycheck::Message::ClearDiagnostics { id } => self.diagnostics.clear_check(id), + flycheck::Message::Progress { id, progress } => { let (state, message) = match progress { - flycheck::Progress::DidStart => { - self.diagnostics_received = false; - (Progress::Begin, None) - } + flycheck::Progress::DidStart => (Progress::Begin, None), flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)), flycheck::Progress::DidCancel => { self.last_flycheck_error = None; @@ -852,9 +847,6 @@ impl GlobalState { flycheck::Progress::DidFinish(result) => { self.last_flycheck_error = result.err().map(|err| format!("cargo check failed to start: {err}")); - if !self.diagnostics_received { - self.diagnostics.clear_check(id); - } (Progress::End, None) } }; diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 2ef9004c476e..2b0dd0062b90 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -7,6 +7,8 @@ edition = "2021" [dependencies] clap = "4.0.32" env_logger = "0.11" +mdbook-trpl-listing = { path = "../../doc/book/packages/mdbook-trpl-listing" } +mdbook-trpl-note = { path = "../../doc/book/packages/mdbook-trpl-note" } [dependencies.mdbook] version = "0.4.37" diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index 1368ec653de1..9a06754e4a66 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -8,6 +8,9 @@ use clap::{arg, ArgMatches, Command}; use mdbook::errors::Result as Result3; use mdbook::MDBook; +use mdbook_trpl_listing::TrplListing; +use mdbook_trpl_note::TrplNote; + fn main() { let crate_version = concat!("v", crate_version!()); env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init(); @@ -67,6 +70,14 @@ pub fn build(args: &ArgMatches) -> Result3<()> { book.config.build.build_dir = dest_dir.into(); } + if book.config.get_preprocessor("trpl-note").is_some() { + book.with_preprocessor(TrplNote); + } + + if book.config.get_preprocessor("trpl-listing").is_some() { + book.with_preprocessor(TrplListing); + } + book.build()?; Ok(()) diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 75dea90d994c..7d14d9e727ab 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -140,7 +140,7 @@ pub(crate) enum SegmentParam<'a> { Const(&'a ast::AnonConst), LifeTime(&'a ast::Lifetime), Type(&'a ast::Ty), - Binding(&'a ast::AssocConstraint), + Binding(&'a ast::AssocItemConstraint), } impl<'a> SegmentParam<'a> { @@ -175,9 +175,9 @@ impl<'a> Rewrite for SegmentParam<'a> { } } -impl Rewrite for ast::AssocConstraint { +impl Rewrite for ast::AssocItemConstraint { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - use ast::AssocConstraintKind::{Bound, Equality}; + use ast::AssocItemConstraintKind::{Bound, Equality}; let mut result = String::with_capacity(128); result.push_str(rewrite_ident(context, self.ident)); @@ -205,14 +205,14 @@ impl Rewrite for ast::AssocConstraint { } } -impl Rewrite for ast::AssocConstraintKind { +impl Rewrite for ast::AssocItemConstraintKind { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { match self { - ast::AssocConstraintKind::Equality { term } => match term { + ast::AssocItemConstraintKind::Equality { term } => match term { Term::Ty(ty) => ty.rewrite(context, shape), Term::Const(c) => c.rewrite(context, shape), }, - ast::AssocConstraintKind::Bound { bounds } => bounds.rewrite(context, shape), + ast::AssocItemConstraintKind::Bound { bounds } => bounds.rewrite(context, shape), } } } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 009200aca15d..600ca06fcdf3 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -2,11 +2,9 @@ run-make/allocator-shim-circular-deps/Makefile run-make/allow-non-lint-warnings-cmdline/Makefile run-make/archive-duplicate-names/Makefile run-make/atomic-lock-free/Makefile -run-make/bare-outfile/Makefile run-make/branch-protection-check-IBT/Makefile run-make/c-dynamic-dylib/Makefile run-make/c-dynamic-rlib/Makefile -run-make/c-link-to-rust-dylib/Makefile run-make/c-static-dylib/Makefile run-make/c-static-rlib/Makefile run-make/c-unwind-abi-catch-lib-panic/Makefile @@ -14,7 +12,6 @@ run-make/c-unwind-abi-catch-panic/Makefile run-make/cat-and-grep-sanity-check/Makefile run-make/cdylib-dylib-linkage/Makefile run-make/cdylib-fewer-symbols/Makefile -run-make/cdylib/Makefile run-make/codegen-options-parsing/Makefile run-make/comment-section/Makefile run-make/compiler-lookup-paths-2/Makefile @@ -38,12 +35,10 @@ run-make/dump-ice-to-disk/Makefile run-make/dump-mono-stats/Makefile run-make/duplicate-output-flavors/Makefile run-make/dylib-chain/Makefile -run-make/emit-named-files/Makefile run-make/emit-path-unhashed/Makefile run-make/emit-shared-files/Makefile run-make/emit-stack-sizes/Makefile run-make/emit-to-stdout/Makefile -run-make/emit/Makefile run-make/env-dep-info/Makefile run-make/error-found-staticlib-instead-crate/Makefile run-make/error-writing-dependencies/Makefile @@ -150,7 +145,6 @@ run-make/min-global-align/Makefile run-make/mingw-export-call-convention/Makefile run-make/mismatching-target-triples/Makefile run-make/missing-crate-dependency/Makefile -run-make/mixing-formats/Makefile run-make/mixing-libs/Makefile run-make/msvc-opt-minsize/Makefile run-make/multiple-emits/Makefile diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs index 6fd2148ef678..f3a64b38e8c6 100644 --- a/src/tools/tidy/src/target_specific_tests.rs +++ b/src/tools/tidy/src/target_specific_tests.rs @@ -90,6 +90,9 @@ pub fn check(path: &Path, bad: &mut bool) { } if let Some(llvm_components) = llvm_components { for component in llvm_components { + // Ensure the given component even exists. + // This is somewhat redundant with COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS, + // but helps detect such problems earlier (PR CI rather than bors CI). if !KNOWN_LLVM_COMPONENTS.contains(component) { eprintln!( "{}: revision {} specifies unknown LLVM component `{}`", diff --git a/tests/assembly/align_offset.rs b/tests/assembly/align_offset.rs index dbf599a741fd..d9902ce336b0 100644 --- a/tests/assembly/align_offset.rs +++ b/tests/assembly/align_offset.rs @@ -1,7 +1,7 @@ //@ assembly-output: emit-asm //@ compile-flags: -Copt-level=1 //@ only-x86_64 -#![crate_type="rlib"] +#![crate_type = "rlib"] // CHECK-LABEL: align_offset_byte_ptr // CHECK: leaq 31 diff --git a/tests/assembly/asm/inline-asm-avx.rs b/tests/assembly/asm/inline-asm-avx.rs index 7e52a798dedb..630acbb971a8 100644 --- a/tests/assembly/asm/inline-asm-avx.rs +++ b/tests/assembly/asm/inline-asm-avx.rs @@ -5,8 +5,8 @@ #![feature(portable_simd)] -use std::simd::Simd; use std::arch::asm; +use std::simd::Simd; #[target_feature(enable = "avx")] #[no_mangle] diff --git a/tests/assembly/closure-inherit-target-feature.rs b/tests/assembly/closure-inherit-target-feature.rs index cafe9e7ca6fa..4692653d91fc 100644 --- a/tests/assembly/closure-inherit-target-feature.rs +++ b/tests/assembly/closure-inherit-target-feature.rs @@ -18,7 +18,8 @@ pub unsafe fn sse41_blend_nofeature(x: __m128, y: __m128) -> __m128 { // CHECK: {{call .*_mm_blend_ps.*}} // CHECK-NOT: blendps // CHECK: ret - #[inline(never)] |x, y| _mm_blend_ps(x, y, 0b0101) + #[inline(never)] + |x, y| _mm_blend_ps(x, y, 0b0101) }; f(x, y) } @@ -33,9 +34,8 @@ pub fn sse41_blend_noinline(x: __m128, y: __m128) -> __m128 { // CHECK: blendps // CHECK-NOT: _mm_blend_ps // CHECK: ret - #[inline(never)] |x, y| unsafe { - _mm_blend_ps(x, y, 0b0101) - } + #[inline(never)] + |x, y| unsafe { _mm_blend_ps(x, y, 0b0101) } }; f(x, y) } @@ -52,9 +52,8 @@ pub fn sse41_blend_doinline(x: __m128, y: __m128) -> __m128 { // CHECK-NOT: _mm_blend_ps // CHECK: ret let f = { - #[inline] |x, y| unsafe { - _mm_blend_ps(x, y, 0b0101) - } + #[inline] + |x, y| unsafe { _mm_blend_ps(x, y, 0b0101) } }; f(x, y) } diff --git a/tests/assembly/is_aligned.rs b/tests/assembly/is_aligned.rs index 14423a52064a..ab8f7dea808d 100644 --- a/tests/assembly/is_aligned.rs +++ b/tests/assembly/is_aligned.rs @@ -4,8 +4,7 @@ //@ revisions: opt-speed opt-size //@ [opt-speed] compile-flags: -Copt-level=2 -Cdebug-assertions=no //@ [opt-size] compile-flags: -Copt-level=s -Cdebug-assertions=no -#![crate_type="rlib"] - +#![crate_type = "rlib"] #![feature(core_intrinsics)] #![feature(pointer_is_aligned_to)] @@ -16,9 +15,7 @@ // CHECK: retq #[no_mangle] pub unsafe fn is_aligned_to_unchecked(ptr: *const u8, align: usize) -> bool { - unsafe { - std::intrinsics::assume(align.is_power_of_two()) - } + unsafe { std::intrinsics::assume(align.is_power_of_two()) } ptr.is_aligned_to(align) } diff --git a/tests/assembly/pic-relocation-model.rs b/tests/assembly/pic-relocation-model.rs index 453fd6a70476..73db94791ec6 100644 --- a/tests/assembly/pic-relocation-model.rs +++ b/tests/assembly/pic-relocation-model.rs @@ -3,10 +3,9 @@ //@ [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=pic //@ [x64] needs-llvm-components: x86 - #![feature(no_core, lang_items)] #![no_core] -#![crate_type="rlib"] +#![crate_type = "rlib"] #[lang = "sized"] trait Sized {} @@ -17,9 +16,7 @@ trait Copy {} // CHECK: {{(jmpq|callq)}} *other_fn@GOTPCREL(%rip) #[no_mangle] pub fn call_other_fn() -> u8 { - unsafe { - other_fn() - } + unsafe { other_fn() } } // CHECK-LABEL: other_fn: @@ -27,9 +24,9 @@ pub fn call_other_fn() -> u8 { #[no_mangle] #[inline(never)] pub fn other_fn() -> u8 { - unsafe { - foreign_fn() - } + unsafe { foreign_fn() } } -extern "C" {fn foreign_fn() -> u8;} +extern "C" { + fn foreign_fn() -> u8; +} diff --git a/tests/assembly/pie-relocation-model.rs b/tests/assembly/pie-relocation-model.rs index 6ff6b7708bbf..e632b4dd5823 100644 --- a/tests/assembly/pie-relocation-model.rs +++ b/tests/assembly/pie-relocation-model.rs @@ -3,10 +3,9 @@ //@ [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=pie //@ [x64] needs-llvm-components: x86 - #![feature(no_core, lang_items)] #![no_core] -#![crate_type="rlib"] +#![crate_type = "rlib"] #[lang = "sized"] trait Sized {} @@ -18,9 +17,7 @@ trait Copy {} // CHECK: {{(jmp|callq)}} other_fn #[no_mangle] pub fn call_other_fn() -> u8 { - unsafe { - other_fn() - } + unsafe { other_fn() } } // CHECK-LABEL: other_fn: @@ -30,9 +27,9 @@ pub fn call_other_fn() -> u8 { #[no_mangle] #[inline(never)] pub fn other_fn() -> u8 { - unsafe { - foreign_fn() - } + unsafe { foreign_fn() } } -extern "C" {fn foreign_fn() -> u8;} +extern "C" { + fn foreign_fn() -> u8; +} diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs index 51b4dc4e1699..2a8251785e77 100644 --- a/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs +++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs @@ -10,12 +10,9 @@ //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled #![crate_type = "lib"] - #![allow(incomplete_features)] - #![feature(unsized_locals, unsized_fn_params)] - // CHECK-LABEL: emptyfn: #[no_mangle] pub fn emptyfn() { @@ -139,7 +136,6 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // missing-NOT: __security_check_cookie } - // CHECK-LABEL: local_string_addr_taken #[no_mangle] pub fn local_string_addr_taken(f: fn(&String)) { @@ -205,7 +201,7 @@ pub struct Gigastruct { not: u64, have: u64, array: u64, - members: u64 + members: u64, } // CHECK-LABEL: local_large_var_moved @@ -259,7 +255,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // EOF // ``` - // all: __security_check_cookie // strong: __security_check_cookie // basic: __security_check_cookie @@ -267,7 +262,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // missing-NOT: __security_check_cookie } - extern "C" { // A call to an external `alloca` function is *not* recognized as an // `alloca(3)` operation. This function is a compiler built-in, as the @@ -320,7 +314,6 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // missing-NOT: __security_check_cookie } - // CHECK-LABEL: alloca_dynamic_arg #[no_mangle] pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { @@ -340,7 +333,6 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // this is support for the "unsized locals" unstable feature: // https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html. - // CHECK-LABEL: unsized_fn_param #[no_mangle] pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { @@ -354,7 +346,6 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // alloca, and is therefore not protected by the `strong` or `basic` // heuristics. - // We should have a __security_check_cookie call in `all` and `strong` modes but // LLVM does not support generating stack protectors in functions with funclet // based EH personalities. diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs index c5915262c093..9729da4e5d25 100644 --- a/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs +++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs @@ -10,12 +10,9 @@ //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled #![crate_type = "lib"] - #![allow(incomplete_features)] - #![feature(unsized_locals, unsized_fn_params)] - // CHECK-LABEL: emptyfn: #[no_mangle] pub fn emptyfn() { @@ -139,7 +136,6 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // missing-NOT: __security_check_cookie } - // CHECK-LABEL: local_string_addr_taken #[no_mangle] pub fn local_string_addr_taken(f: fn(&String)) { @@ -213,7 +209,7 @@ pub struct Gigastruct { not: u64, have: u64, array: u64, - members: u64 + members: u64, } // CHECK-LABEL: local_large_var_moved @@ -267,7 +263,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // EOF // ``` - // all: __security_check_cookie // strong: __security_check_cookie // basic: __security_check_cookie @@ -275,7 +270,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // missing-NOT: __security_check_cookie } - extern "C" { // A call to an external `alloca` function is *not* recognized as an // `alloca(3)` operation. This function is a compiler built-in, as the @@ -328,7 +322,6 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // missing-NOT: __security_check_cookie } - // CHECK-LABEL: alloca_dynamic_arg #[no_mangle] pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { @@ -348,7 +341,6 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // this is support for the "unsized locals" unstable feature: // https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html. - // CHECK-LABEL: unsized_fn_param #[no_mangle] pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { @@ -362,7 +354,6 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // alloca, and is therefore not protected by the `strong` or `basic` // heuristics. - // We should have a __security_check_cookie call in `all` and `strong` modes but // LLVM does not support generating stack protectors in functions with funclet // based EH personalities. diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs index 1f15f1a318a6..5ed0b6c50a73 100644 --- a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs +++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs @@ -143,7 +143,6 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // missing-NOT: __stack_chk_fail } - // CHECK-LABEL: local_string_addr_taken #[no_mangle] pub fn local_string_addr_taken(f: fn(&String)) { @@ -194,7 +193,7 @@ pub struct Gigastruct { not: u64, have: u64, array: u64, - members: u64 + members: u64, } // CHECK-LABEL: local_large_var_moved @@ -255,7 +254,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // missing-NOT: __stack_chk_fail } - extern "C" { // A call to an external `alloca` function is *not* recognized as an // `alloca(3)` operation. This function is a compiler built-in, as the @@ -308,7 +306,6 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // missing-NOT: __stack_chk_fail } - // CHECK-LABEL: alloca_dynamic_arg #[no_mangle] pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { @@ -328,7 +325,6 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // this is support for the "unsized locals" unstable feature: // https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html. - // CHECK-LABEL: unsized_fn_param #[no_mangle] pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { @@ -342,7 +338,6 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // alloca, and is therefore not protected by the `strong` or `basic` // heuristics. - // all: __stack_chk_fail // strong-NOT: __stack_chk_fail // basic-NOT: __stack_chk_fail diff --git a/tests/assembly/static-relocation-model.rs b/tests/assembly/static-relocation-model.rs index 50527b853451..eafdfd485baa 100644 --- a/tests/assembly/static-relocation-model.rs +++ b/tests/assembly/static-relocation-model.rs @@ -9,15 +9,15 @@ #![feature(no_core, lang_items)] #![no_core] -#![crate_type="rlib"] +#![crate_type = "rlib"] -#[lang="sized"] +#[lang = "sized"] trait Sized {} -#[lang="copy"] +#[lang = "copy"] trait Copy {} -#[lang="sync"] +#[lang = "sync"] trait Sync {} #[lang = "drop_in_place"] @@ -42,9 +42,7 @@ extern "C" { // A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG]], :lo12:chaenomeles] #[no_mangle] pub fn banana() -> u8 { - unsafe { - *(chaenomeles as *mut u8) - } + unsafe { *(chaenomeles as *mut u8) } } // CHECK-LABEL: peach: @@ -53,9 +51,7 @@ pub fn banana() -> u8 { // A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG2]], :lo12:banana] #[no_mangle] pub fn peach() -> u8 { - unsafe { - *(banana as *mut u8) - } + unsafe { *(banana as *mut u8) } } // CHECK-LABEL: mango: @@ -65,9 +61,7 @@ pub fn peach() -> u8 { // A64-NEXT: ldr {{[a-z0-9]+}}, {{\[}}[[REG2]], :lo12:EXOCHORDA] #[no_mangle] pub fn mango() -> u8 { - unsafe { - *EXOCHORDA - } + unsafe { *EXOCHORDA } } // CHECK-LABEL: orange: diff --git a/tests/assembly/thin-lto.rs b/tests/assembly/thin-lto.rs index 182115662bfd..7b67b2de1e63 100644 --- a/tests/assembly/thin-lto.rs +++ b/tests/assembly/thin-lto.rs @@ -4,5 +4,4 @@ // CHECK: main -pub fn main() { -} +pub fn main() {} diff --git a/tests/assembly/wasm_exceptions.rs b/tests/assembly/wasm_exceptions.rs index 3d3b13ff32b7..7bdf7f1287c2 100644 --- a/tests/assembly/wasm_exceptions.rs +++ b/tests/assembly/wasm_exceptions.rs @@ -8,7 +8,7 @@ #![feature(core_intrinsics)] #![feature(rustc_attrs)] -extern { +extern "C" { fn may_panic(); #[rustc_nounwind] @@ -19,7 +19,9 @@ struct LogOnDrop; impl Drop for LogOnDrop { fn drop(&mut self) { - unsafe { log_number(0); } + unsafe { + log_number(0); + } } } @@ -27,7 +29,9 @@ impl Drop for LogOnDrop { #[no_mangle] pub fn test_cleanup() { let _log_on_drop = LogOnDrop; - unsafe { may_panic(); } + unsafe { + may_panic(); + } // CHECK-NOT: call // CHECK: try @@ -41,12 +45,16 @@ pub fn test_cleanup() { #[no_mangle] pub fn test_rtry() { unsafe { - core::intrinsics::catch_unwind(|_| { - may_panic(); - }, core::ptr::null_mut(), |data, exception| { - log_number(data as usize); - log_number(exception as usize); - }); + core::intrinsics::catch_unwind( + |_| { + may_panic(); + }, + core::ptr::null_mut(), + |data, exception| { + log_number(data as usize); + log_number(exception as usize); + }, + ); } // CHECK-NOT: call diff --git a/tests/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs b/tests/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs index 7215e354d0dc..f5e2f18e68e4 100644 --- a/tests/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs +++ b/tests/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-load.rs @@ -5,7 +5,7 @@ //@ only-x86_64-fortanix-unknown-sgx #[no_mangle] -pub extern fn plus_one(r: &mut u64) { +pub extern "C" fn plus_one(r: &mut u64) { *r = *r + 1; } diff --git a/tests/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs b/tests/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs index 5ae9dd11859e..f16d68fa2554 100644 --- a/tests/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs +++ b/tests/assembly/x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs @@ -5,7 +5,7 @@ //@ only-x86_64-fortanix-unknown-sgx #[no_mangle] -pub extern fn myret() {} +pub extern "C" fn myret() {} // CHECK: myret: // CHECK: popq [[REGISTER:%[a-z]+]] // CHECK-NEXT: lfence diff --git a/tests/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs b/tests/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs index 5566bb4e4b28..1992baf8c765 100644 --- a/tests/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs +++ b/tests/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs @@ -2,25 +2,43 @@ #![crate_type = "lib"] -pub trait Trait : Sized { +pub trait Trait: Sized { fn without_self() -> u32; - fn without_self_default() -> u32 { 0 } + fn without_self_default() -> u32 { + 0 + } - fn with_default_impl(self) -> Self { self } - fn with_default_impl_generic(self, x: T) -> (Self, T) { (self, x) } + fn with_default_impl(self) -> Self { + self + } + fn with_default_impl_generic(self, x: T) -> (Self, T) { + (self, x) + } fn without_default_impl(x: u32) -> (Self, u32); fn without_default_impl_generic(x: T) -> (Self, T); } impl Trait for char { - fn without_self() -> u32 { 2 } - fn without_default_impl(x: u32) -> (Self, u32) { ('c', x) } - fn without_default_impl_generic(x: T) -> (Self, T) { ('c', x) } + fn without_self() -> u32 { + 2 + } + fn without_default_impl(x: u32) -> (Self, u32) { + ('c', x) + } + fn without_default_impl_generic(x: T) -> (Self, T) { + ('c', x) + } } impl Trait for u32 { - fn without_self() -> u32 { 1 } - fn without_default_impl(x: u32) -> (Self, u32) { (0, x) } - fn without_default_impl_generic(x: T) -> (Self, T) { (0, x) } + fn without_self() -> u32 { + 1 + } + fn without_default_impl(x: u32) -> (Self, u32) { + (0, x) + } + fn without_default_impl_generic(x: T) -> (Self, T) { + (0, x) + } } diff --git a/tests/codegen-units/item-collection/auxiliary/cgu_extern_closures.rs b/tests/codegen-units/item-collection/auxiliary/cgu_extern_closures.rs index 05ea0a89ff29..0192a3d4188c 100644 --- a/tests/codegen-units/item-collection/auxiliary/cgu_extern_closures.rs +++ b/tests/codegen-units/item-collection/auxiliary/cgu_extern_closures.rs @@ -2,22 +2,19 @@ #[inline] pub fn inlined_fn(x: i32, y: i32) -> i32 { - - let closure = |a, b| { a + b }; + let closure = |a, b| a + b; closure(x, y) } pub fn inlined_fn_generic(x: i32, y: i32, z: T) -> (i32, T) { - - let closure = |a, b| { a + b }; + let closure = |a, b| a + b; (closure(x, y), z) } pub fn non_inlined_fn(x: i32, y: i32) -> i32 { - - let closure = |a, b| { a + b }; + let closure = |a, b| a + b; closure(x, y) } diff --git a/tests/codegen-units/item-collection/cross-crate-closures.rs b/tests/codegen-units/item-collection/cross-crate-closures.rs index 4ec7f17d5847..2dab19401ed7 100644 --- a/tests/codegen-units/item-collection/cross-crate-closures.rs +++ b/tests/codegen-units/item-collection/cross-crate-closures.rs @@ -14,7 +14,6 @@ extern crate cgu_extern_closures; //~ MONO_ITEM fn cross_crate_closures::start[0] #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn cgu_extern_closures::inlined_fn[0] //~ MONO_ITEM fn cgu_extern_closures::inlined_fn[0]::{{closure}}[0] let _ = cgu_extern_closures::inlined_fn(1, 2); diff --git a/tests/codegen-units/item-collection/cross-crate-trait-method.rs b/tests/codegen-units/item-collection/cross-crate-trait-method.rs index 84977328e490..997777603155 100644 --- a/tests/codegen-units/item-collection/cross-crate-trait-method.rs +++ b/tests/codegen-units/item-collection/cross-crate-trait-method.rs @@ -24,8 +24,6 @@ fn start(_: isize, _: *const *const u8) -> isize { //~ MONO_ITEM fn ::with_default_impl let _ = Trait::with_default_impl('c'); - - //~ MONO_ITEM fn ::with_default_impl_generic::<&str> let _ = Trait::with_default_impl_generic(0u32, "abc"); //~ MONO_ITEM fn ::with_default_impl_generic:: diff --git a/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs b/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs index 66dcda260660..947faa165a9c 100644 --- a/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs +++ b/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs @@ -15,7 +15,6 @@ impl Drop for StructWithDtor { //~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn std::ptr::drop_in_place::<[StructWithDtor; 2]> - shim(Some([StructWithDtor; 2])) @@ drop_in_place_intrinsic-cgu.0[Internal] let x = [StructWithDtor(0), StructWithDtor(1)]; diff --git a/tests/codegen-units/item-collection/function-as-argument.rs b/tests/codegen-units/item-collection/function-as-argument.rs index 4e6fd99d29ed..4be713dc3673 100644 --- a/tests/codegen-units/item-collection/function-as-argument.rs +++ b/tests/codegen-units/item-collection/function-as-argument.rs @@ -16,7 +16,6 @@ fn take_fn_pointer(f: fn(T1, T2), x: T1, y: T2) { //~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn take_fn_once::}> //~ MONO_ITEM fn function:: //~ MONO_ITEM fn } as std::ops::FnOnce<(u32, &str)>>::call_once - shim(fn(u32, &str) {function::}) diff --git a/tests/codegen-units/item-collection/generic-drop-glue.rs b/tests/codegen-units/item-collection/generic-drop-glue.rs index 99250dc7dc67..d861d269fae4 100644 --- a/tests/codegen-units/item-collection/generic-drop-glue.rs +++ b/tests/codegen-units/item-collection/generic-drop-glue.rs @@ -21,7 +21,7 @@ struct StructNoDrop { enum EnumWithDrop { A(T1), - B(T2) + B(T2), } impl Drop for EnumWithDrop { @@ -30,10 +30,9 @@ impl Drop for EnumWithDrop { enum EnumNoDrop { A(T1), - B(T2) + B(T2), } - struct NonGenericNoDrop(#[allow(dead_code)] i32); struct NonGenericWithDrop(#[allow(dead_code)] i32); @@ -67,24 +66,24 @@ fn start(_: isize, _: *const *const u8) -> isize { //~ MONO_ITEM fn as std::ops::Drop>::drop let _ = match EnumWithDrop::A::(0) { EnumWithDrop::A(x) => x, - EnumWithDrop::B(x) => x as i32 + EnumWithDrop::B(x) => x as i32, }; //~ MONO_ITEM fn std::ptr::drop_in_place::> - shim(Some(EnumWithDrop)) @@ generic_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn as std::ops::Drop>::drop let _ = match EnumWithDrop::B::(1.0) { EnumWithDrop::A(x) => x, - EnumWithDrop::B(x) => x as f64 + EnumWithDrop::B(x) => x as f64, }; let _ = match EnumNoDrop::A::(0) { EnumNoDrop::A(x) => x, - EnumNoDrop::B(x) => x as i32 + EnumNoDrop::B(x) => x as i32, }; let _ = match EnumNoDrop::B::(1.0) { EnumNoDrop::A(x) => x, - EnumNoDrop::B(x) => x as f64 + EnumNoDrop::B(x) => x as f64, }; 0 diff --git a/tests/codegen-units/item-collection/generic-impl.rs b/tests/codegen-units/item-collection/generic-impl.rs index 6e60907c1857..23d09e0d8af3 100644 --- a/tests/codegen-units/item-collection/generic-impl.rs +++ b/tests/codegen-units/item-collection/generic-impl.rs @@ -8,15 +8,13 @@ struct Struct { f: fn(x: T) -> T, } -fn id(x: T) -> T { x } +fn id(x: T) -> T { + x +} impl Struct { - fn new(x: T) -> Struct { - Struct { - x: x, - f: id - } + Struct { x: x, f: id } } fn get(self, x: T2) -> (T, T2) { @@ -25,11 +23,10 @@ impl Struct { } pub struct LifeTimeOnly<'a> { - _a: &'a u32 + _a: &'a u32, } impl<'a> LifeTimeOnly<'a> { - //~ MONO_ITEM fn LifeTimeOnly::<'_>::foo pub fn foo(&self) {} //~ MONO_ITEM fn LifeTimeOnly::<'_>::bar diff --git a/tests/codegen-units/item-collection/instantiation-through-vtable.rs b/tests/codegen-units/item-collection/instantiation-through-vtable.rs index 08e8c03a7328..59dd4311a03b 100644 --- a/tests/codegen-units/item-collection/instantiation-through-vtable.rs +++ b/tests/codegen-units/item-collection/instantiation-through-vtable.rs @@ -10,11 +10,13 @@ trait Trait { } struct Struct { - _a: T + _a: T, } impl Trait for Struct { - fn foo(&self) -> u32 { 0 } + fn foo(&self) -> u32 { + 0 + } fn bar(&self) {} } diff --git a/tests/codegen-units/item-collection/non-generic-drop-glue.rs b/tests/codegen-units/item-collection/non-generic-drop-glue.rs index d74b17463bf1..f7bb2f3f2f4d 100644 --- a/tests/codegen-units/item-collection/non-generic-drop-glue.rs +++ b/tests/codegen-units/item-collection/non-generic-drop-glue.rs @@ -7,7 +7,7 @@ //~ MONO_ITEM fn std::ptr::drop_in_place:: - shim(Some(StructWithDrop)) @@ non_generic_drop_glue-cgu.0[Internal] struct StructWithDrop { - x: i32 + x: i32, } impl Drop for StructWithDrop { @@ -16,12 +16,12 @@ impl Drop for StructWithDrop { } struct StructNoDrop { - x: i32 + x: i32, } //~ MONO_ITEM fn std::ptr::drop_in_place:: - shim(Some(EnumWithDrop)) @@ non_generic_drop_glue-cgu.0[Internal] enum EnumWithDrop { - A(i32) + A(i32), } impl Drop for EnumWithDrop { @@ -30,7 +30,7 @@ impl Drop for EnumWithDrop { } enum EnumNoDrop { - A(i32) + A(i32), } //~ MONO_ITEM fn start @@ -39,10 +39,10 @@ fn start(_: isize, _: *const *const u8) -> isize { let _ = StructWithDrop { x: 0 }.x; let _ = StructNoDrop { x: 0 }.x; let _ = match EnumWithDrop::A(0) { - EnumWithDrop::A(x) => x + EnumWithDrop::A(x) => x, }; let _ = match EnumNoDrop::A(0) { - EnumNoDrop::A(x) => x + EnumNoDrop::A(x) => x, }; 0 diff --git a/tests/codegen-units/item-collection/non-generic-functions.rs b/tests/codegen-units/item-collection/non-generic-functions.rs index 49a999a0d7c8..d4d7d221827d 100644 --- a/tests/codegen-units/item-collection/non-generic-functions.rs +++ b/tests/codegen-units/item-collection/non-generic-functions.rs @@ -25,7 +25,9 @@ fn bar() { baz(); } -struct Struct { _x: i32 } +struct Struct { + _x: i32, +} impl Struct { //~ MONO_ITEM fn Struct::foo diff --git a/tests/codegen-units/item-collection/overloaded-operators.rs b/tests/codegen-units/item-collection/overloaded-operators.rs index 23141c27de6e..69b55695d3d3 100644 --- a/tests/codegen-units/item-collection/overloaded-operators.rs +++ b/tests/codegen-units/item-collection/overloaded-operators.rs @@ -1,12 +1,12 @@ //@ compile-flags:-Zprint-mono-items=eager #![deny(dead_code)] -#![crate_type="lib"] +#![crate_type = "lib"] -use std::ops::{Index, IndexMut, Add, Deref}; +use std::ops::{Add, Deref, Index, IndexMut}; pub struct Indexable { - data: [u8; 3] + data: [u8; 3], } impl Index for Indexable { @@ -14,32 +14,22 @@ impl Index for Indexable { //~ MONO_ITEM fn >::index fn index(&self, index: usize) -> &Self::Output { - if index >= 3 { - &self.data[0] - } else { - &self.data[index] - } + if index >= 3 { &self.data[0] } else { &self.data[index] } } } impl IndexMut for Indexable { //~ MONO_ITEM fn >::index_mut fn index_mut(&mut self, index: usize) -> &mut Self::Output { - if index >= 3 { - &mut self.data[0] - } else { - &mut self.data[index] - } + if index >= 3 { &mut self.data[0] } else { &mut self.data[index] } } } - //~ MONO_ITEM fn ::eq //~ MONO_ITEM fn ::ne #[derive(PartialEq)] pub struct Equatable(u32); - impl Add for Equatable { type Output = u32; diff --git a/tests/codegen-units/item-collection/static-init.rs b/tests/codegen-units/item-collection/static-init.rs index b357f5cd66b2..1406fba2b984 100644 --- a/tests/codegen-units/item-collection/static-init.rs +++ b/tests/codegen-units/item-collection/static-init.rs @@ -2,9 +2,9 @@ #![feature(start)] -pub static FN : fn() = foo::; +pub static FN: fn() = foo::; -pub fn foo() { } +pub fn foo() {} //~ MONO_ITEM fn foo:: //~ MONO_ITEM static FN diff --git a/tests/codegen-units/item-collection/trait-implementations.rs b/tests/codegen-units/item-collection/trait-implementations.rs index b364cc5b3336..e4c444499e05 100644 --- a/tests/codegen-units/item-collection/trait-implementations.rs +++ b/tests/codegen-units/item-collection/trait-implementations.rs @@ -9,7 +9,6 @@ pub trait SomeTrait { } impl SomeTrait for i64 { - //~ MONO_ITEM fn ::foo fn foo(&self) {} @@ -17,7 +16,6 @@ impl SomeTrait for i64 { } impl SomeTrait for i32 { - //~ MONO_ITEM fn ::foo fn foo(&self) {} @@ -31,7 +29,6 @@ pub trait SomeGenericTrait { // Concrete impl of generic trait impl SomeGenericTrait for f64 { - //~ MONO_ITEM fn >::foo fn foo(&self, _: u32) {} @@ -40,7 +37,6 @@ impl SomeGenericTrait for f64 { // Generic impl of generic trait impl SomeGenericTrait for f32 { - fn foo(&self, _: T) {} fn bar(&self, _: T, _: T2) {} } @@ -48,26 +44,26 @@ impl SomeGenericTrait for f32 { //~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn ::bar:: - 0i32.bar('x'); + //~ MONO_ITEM fn ::bar:: + 0i32.bar('x'); - //~ MONO_ITEM fn >::bar::<&str> - 0f64.bar(0u32, "&str"); + //~ MONO_ITEM fn >::bar::<&str> + 0f64.bar(0u32, "&str"); - //~ MONO_ITEM fn >::bar::<()> - 0f64.bar(0u32, ()); + //~ MONO_ITEM fn >::bar::<()> + 0f64.bar(0u32, ()); - //~ MONO_ITEM fn >::foo - 0f32.foo('x'); + //~ MONO_ITEM fn >::foo + 0f32.foo('x'); - //~ MONO_ITEM fn >::foo - 0f32.foo(-1i64); + //~ MONO_ITEM fn >::foo + 0f32.foo(-1i64); - //~ MONO_ITEM fn >::bar::<()> - 0f32.bar(0u32, ()); + //~ MONO_ITEM fn >::bar::<()> + 0f32.bar(0u32, ()); - //~ MONO_ITEM fn >::bar::<&str> - 0f32.bar("&str", "&str"); + //~ MONO_ITEM fn >::bar::<&str> + 0f32.bar("&str", "&str"); - 0 + 0 } diff --git a/tests/codegen-units/item-collection/trait-method-as-argument.rs b/tests/codegen-units/item-collection/trait-method-as-argument.rs index c25e3ea45ecc..10cf2a0e967e 100644 --- a/tests/codegen-units/item-collection/trait-method-as-argument.rs +++ b/tests/codegen-units/item-collection/trait-method-as-argument.rs @@ -3,16 +3,19 @@ #![deny(dead_code)] #![feature(start)] -trait Trait : Sized { - fn foo(self) -> Self { self } +trait Trait: Sized { + fn foo(self) -> Self { + self + } } impl Trait for u32 { - fn foo(self) -> u32 { self } + fn foo(self) -> u32 { + self + } } -impl Trait for char { -} +impl Trait for char {} fn take_foo_once T>(f: F, arg: T) -> T { (f)(arg) diff --git a/tests/codegen-units/item-collection/trait-method-default-impl.rs b/tests/codegen-units/item-collection/trait-method-default-impl.rs index 89fec350f09c..b0a43d28e40b 100644 --- a/tests/codegen-units/item-collection/trait-method-default-impl.rs +++ b/tests/codegen-units/item-collection/trait-method-default-impl.rs @@ -4,8 +4,10 @@ #![feature(start)] trait SomeTrait { - fn foo(&self) { } - fn bar(&self, x: T) -> T { x } + fn foo(&self) {} + fn bar(&self, x: T) -> T { + x + } } impl SomeTrait for i8 { @@ -17,7 +19,7 @@ impl SomeTrait for i8 { } trait SomeGenericTrait { - fn foo(&self) { } + fn foo(&self) {} fn bar(&self, x: T1, y: T2) {} } diff --git a/tests/codegen-units/item-collection/unsizing.rs b/tests/codegen-units/item-collection/unsizing.rs index 1e2d7f174845..5ea8b47962a8 100644 --- a/tests/codegen-units/item-collection/unsizing.rs +++ b/tests/codegen-units/item-collection/unsizing.rs @@ -27,7 +27,7 @@ impl Trait for char { struct Struct { _a: u32, _b: i32, - _c: T + _c: T, } impl Trait for f64 { @@ -60,11 +60,7 @@ fn start(_: isize, _: *const *const u8) -> isize { let _char_unsized = char_sized as &Trait; // struct field - let struct_sized = &Struct { - _a: 1, - _b: 2, - _c: 3.0f64 - }; + let struct_sized = &Struct { _a: 1, _b: 2, _c: 3.0f64 }; //~ MONO_ITEM fn std::ptr::drop_in_place:: - shim(None) @@ unsizing-cgu.0[Internal] //~ MONO_ITEM fn ::foo let _struct_unsized = struct_sized as &Struct; diff --git a/tests/codegen-units/item-collection/unused-traits-and-generics.rs b/tests/codegen-units/item-collection/unused-traits-and-generics.rs index 27cdae2c0962..d5088d3f8937 100644 --- a/tests/codegen-units/item-collection/unused-traits-and-generics.rs +++ b/tests/codegen-units/item-collection/unused-traits-and-generics.rs @@ -1,6 +1,6 @@ //@ compile-flags:-Zprint-mono-items=eager -#![crate_type="lib"] +#![crate_type = "lib"] #![deny(dead_code)] // This test asserts that no codegen items are generated for generic items that @@ -16,7 +16,7 @@ pub fn foo(x: T) -> (T, T) { } pub struct Struct { - x: T + x: T, } impl Struct { @@ -29,7 +29,7 @@ impl Struct { pub enum Enum { A(T), - B { x: T } + B { x: T }, } impl Enum { @@ -56,7 +56,7 @@ impl TupleStruct { pub type Pair = (T, T); pub struct NonGeneric { - x: i32 + x: i32, } impl NonGeneric { diff --git a/tests/codegen-units/partitioning/auxiliary/shared_generics_aux.rs b/tests/codegen-units/partitioning/auxiliary/shared_generics_aux.rs index 158932d165df..b6c568ed387a 100644 --- a/tests/codegen-units/partitioning/auxiliary/shared_generics_aux.rs +++ b/tests/codegen-units/partitioning/auxiliary/shared_generics_aux.rs @@ -3,7 +3,7 @@ //@ compile-flags:-Zshare-generics=yes -Copt-level=0 //@ no-prefer-dynamic -#![crate_type="rlib"] +#![crate_type = "rlib"] pub fn generic_fn(x: T, y: T) -> (T, T) { (x, y) diff --git a/tests/codegen-units/partitioning/extern-generic.rs b/tests/codegen-units/partitioning/extern-generic.rs index 0e4b6a37f712..602a5240283b 100644 --- a/tests/codegen-units/partitioning/extern-generic.rs +++ b/tests/codegen-units/partitioning/extern-generic.rs @@ -3,7 +3,7 @@ //@ compile-flags:-Zprint-mono-items=eager -Zshare-generics=y #![allow(dead_code)] -#![crate_type="lib"] +#![crate_type = "lib"] //@ aux-build:cgu_generic_function.rs extern crate cgu_generic_function; diff --git a/tests/codegen-units/partitioning/inlining-from-extern-crate.rs b/tests/codegen-units/partitioning/inlining-from-extern-crate.rs index d021f467f1f9..b007ffe1cb51 100644 --- a/tests/codegen-units/partitioning/inlining-from-extern-crate.rs +++ b/tests/codegen-units/partitioning/inlining-from-extern-crate.rs @@ -3,7 +3,7 @@ //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus -#![crate_type="lib"] +#![crate_type = "lib"] //@ aux-build:cgu_explicit_inlining.rs extern crate cgu_explicit_inlining; @@ -15,8 +15,7 @@ extern crate cgu_explicit_inlining; //~ MONO_ITEM fn cgu_explicit_inlining::always_inlined @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod2[Internal] //~ MONO_ITEM fn user @@ inlining_from_extern_crate[External] -pub fn user() -{ +pub fn user() { cgu_explicit_inlining::inlined(); cgu_explicit_inlining::always_inlined(); @@ -28,8 +27,7 @@ pub mod mod1 { use cgu_explicit_inlining; //~ MONO_ITEM fn mod1::user @@ inlining_from_extern_crate-mod1[External] - pub fn user() - { + pub fn user() { cgu_explicit_inlining::inlined(); // does not generate a monomorphization in this crate @@ -41,8 +39,7 @@ pub mod mod2 { use cgu_explicit_inlining; //~ MONO_ITEM fn mod2::user @@ inlining_from_extern_crate-mod2[External] - pub fn user() - { + pub fn user() { cgu_explicit_inlining::always_inlined(); // does not generate a monomorphization in this crate diff --git a/tests/codegen-units/partitioning/local-generic.rs b/tests/codegen-units/partitioning/local-generic.rs index 06f46b23db6a..0cfc572650c1 100644 --- a/tests/codegen-units/partitioning/local-generic.rs +++ b/tests/codegen-units/partitioning/local-generic.rs @@ -3,13 +3,15 @@ //@ compile-flags:-Zprint-mono-items=eager #![allow(dead_code)] -#![crate_type="lib"] +#![crate_type = "lib"] //~ MONO_ITEM fn generic:: @@ local_generic.volatile[External] //~ MONO_ITEM fn generic:: @@ local_generic.volatile[External] //~ MONO_ITEM fn generic:: @@ local_generic.volatile[External] //~ MONO_ITEM fn generic::<&str> @@ local_generic.volatile[External] -pub fn generic(x: T) -> T { x } +pub fn generic(x: T) -> T { + x +} //~ MONO_ITEM fn user @@ local_generic[Internal] fn user() { diff --git a/tests/codegen-units/partitioning/local-inlining-but-not-all.rs b/tests/codegen-units/partitioning/local-inlining-but-not-all.rs index 2f9cbe83f1d5..454de255254a 100644 --- a/tests/codegen-units/partitioning/local-inlining-but-not-all.rs +++ b/tests/codegen-units/partitioning/local-inlining-but-not-all.rs @@ -4,16 +4,13 @@ //@ compile-flags:-Zinline-in-all-cgus=no #![allow(dead_code)] -#![crate_type="lib"] +#![crate_type = "lib"] mod inline { //~ MONO_ITEM fn inline::inlined_function @@ local_inlining_but_not_all-inline[External] #[inline] - pub fn inlined_function() - { - - } + pub fn inlined_function() {} } pub mod user1 { @@ -37,7 +34,5 @@ pub mod user2 { pub mod non_user { //~ MONO_ITEM fn non_user::baz @@ local_inlining_but_not_all-non_user[External] - pub fn baz() { - - } + pub fn baz() {} } diff --git a/tests/codegen-units/partitioning/local-inlining.rs b/tests/codegen-units/partitioning/local-inlining.rs index 2329a876c960..42c68b5c6218 100644 --- a/tests/codegen-units/partitioning/local-inlining.rs +++ b/tests/codegen-units/partitioning/local-inlining.rs @@ -4,17 +4,14 @@ //@ compile-flags:-Zinline-in-all-cgus #![allow(dead_code)] -#![crate_type="lib"] +#![crate_type = "lib"] mod inline { // Important: This function should show up in all codegen units where it is inlined //~ MONO_ITEM fn inline::inlined_function @@ local_inlining-user1[Internal] local_inlining-user2[Internal] #[inline(always)] - pub fn inlined_function() - { - - } + pub fn inlined_function() {} } pub mod user1 { @@ -38,7 +35,5 @@ pub mod user2 { pub mod non_user { //~ MONO_ITEM fn non_user::baz @@ local_inlining-non_user[External] - pub fn baz() { - - } + pub fn baz() {} } diff --git a/tests/codegen-units/partitioning/local-transitive-inlining.rs b/tests/codegen-units/partitioning/local-transitive-inlining.rs index 4ccc53aea1d1..0d279ebe7404 100644 --- a/tests/codegen-units/partitioning/local-transitive-inlining.rs +++ b/tests/codegen-units/partitioning/local-transitive-inlining.rs @@ -4,16 +4,13 @@ //@ compile-flags:-Zinline-in-all-cgus #![allow(dead_code)] -#![crate_type="rlib"] +#![crate_type = "rlib"] mod inline { //~ MONO_ITEM fn inline::inlined_function @@ local_transitive_inlining-indirect_user[Internal] #[inline(always)] - pub fn inlined_function() - { - - } + pub fn inlined_function() {} } mod direct_user { @@ -38,7 +35,5 @@ pub mod indirect_user { pub mod non_user { //~ MONO_ITEM fn non_user::baz @@ local_transitive_inlining-non_user[External] - pub fn baz() { - - } + pub fn baz() {} } diff --git a/tests/codegen-units/partitioning/methods-are-with-self-type.rs b/tests/codegen-units/partitioning/methods-are-with-self-type.rs index 3ba53334cc90..901e7507d738 100644 --- a/tests/codegen-units/partitioning/methods-are-with-self-type.rs +++ b/tests/codegen-units/partitioning/methods-are-with-self-type.rs @@ -15,7 +15,7 @@ struct SomeType; struct SomeGenericType(T1, T2); mod mod1 { - use super::{SomeType, SomeGenericType}; + use super::{SomeGenericType, SomeType}; // Even though the impl is in `mod1`, the methods should end up in the // parent module, since that is where their self-type is. @@ -40,8 +40,7 @@ trait Trait { // We provide an implementation of `Trait` for all types. The corresponding // monomorphizations should end up in whichever module the concrete `T` is. -impl Trait for T -{ +impl Trait for T { fn foo(&self) {} } diff --git a/tests/codegen-units/partitioning/regular-modules.rs b/tests/codegen-units/partitioning/regular-modules.rs index 68601975d062..294971464155 100644 --- a/tests/codegen-units/partitioning/regular-modules.rs +++ b/tests/codegen-units/partitioning/regular-modules.rs @@ -3,7 +3,7 @@ //@ compile-flags:-Zprint-mono-items=eager #![allow(dead_code)] -#![crate_type="lib"] +#![crate_type = "lib"] //~ MONO_ITEM fn foo @@ regular_modules[Internal] fn foo() {} diff --git a/tests/codegen-units/partitioning/shared-generics.rs b/tests/codegen-units/partitioning/shared-generics.rs index 5b78794316c6..ea312719ac91 100644 --- a/tests/codegen-units/partitioning/shared-generics.rs +++ b/tests/codegen-units/partitioning/shared-generics.rs @@ -4,14 +4,13 @@ //@ incremental //@ compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Copt-level=0 -#![crate_type="rlib"] +#![crate_type = "rlib"] //@ aux-build:shared_generics_aux.rs extern crate shared_generics_aux; //~ MONO_ITEM fn foo pub fn foo() { - //~ MONO_ITEM fn shared_generics_aux::generic_fn:: @@ shared_generics_aux-in-shared_generics.volatile[External] let _ = shared_generics_aux::generic_fn(0u16, 1u16); diff --git a/tests/codegen-units/partitioning/statics.rs b/tests/codegen-units/partitioning/statics.rs index c7eef1f3789d..00dd6d877e1e 100644 --- a/tests/codegen-units/partitioning/statics.rs +++ b/tests/codegen-units/partitioning/statics.rs @@ -2,7 +2,7 @@ //@ incremental //@ compile-flags:-Zprint-mono-items=lazy -#![crate_type="rlib"] +#![crate_type = "rlib"] //~ MONO_ITEM static FOO @@ statics[Internal] static FOO: u32 = 0; diff --git a/tests/codegen-units/partitioning/vtable-through-const.rs b/tests/codegen-units/partitioning/vtable-through-const.rs index f91c0c0bfdbf..a9186cea9c89 100644 --- a/tests/codegen-units/partitioning/vtable-through-const.rs +++ b/tests/codegen-units/partitioning/vtable-through-const.rs @@ -28,20 +28,24 @@ mod mod1 { } impl Trait1Gen for NeedsDrop { - fn do_something(&self, x: T) -> T { x } - fn do_something_else(&self, x: T) -> T { x } + fn do_something(&self, x: T) -> T { + x + } + fn do_something_else(&self, x: T) -> T { + x + } } //~ MONO_ITEM fn mod1::id:: @@ vtable_through_const-mod1.volatile[Internal] - fn id(x: T) -> T { x } + fn id(x: T) -> T { + x + } // These are referenced, so they produce mono-items (see start()) pub const TRAIT1_REF: &'static Trait1 = &NeedsDrop as &Trait1; pub const TRAIT1_GEN_REF: &'static Trait1Gen = &NeedsDrop as &Trait1Gen; pub const ID_CHAR: fn(char) -> char = id::; - - pub trait Trait2 { fn do_something(&self) {} fn do_something_else(&self) {} @@ -57,8 +61,12 @@ mod mod1 { } impl Trait2Gen for NeedsDrop { - fn do_something(&self, x: T) -> T { x } - fn do_something_else(&self, x: T) -> T { x } + fn do_something(&self, x: T) -> T { + x + } + fn do_something_else(&self, x: T) -> T { + x + } } // These are not referenced, so they do not produce mono-items diff --git a/tests/codegen-units/polymorphization/unused_type_parameters.rs b/tests/codegen-units/polymorphization/unused_type_parameters.rs index cf5f7c320985..438305f112f3 100644 --- a/tests/codegen-units/polymorphization/unused_type_parameters.rs +++ b/tests/codegen-units/polymorphization/unused_type_parameters.rs @@ -9,54 +9,51 @@ mod functions { // Function doesn't have any type parameters to be unused. pub fn no_parameters() {} -//~ MONO_ITEM fn functions::no_parameters + //~ MONO_ITEM fn functions::no_parameters // Function has an unused type parameter. - pub fn unused() { - } + pub fn unused() {} -//~ MONO_ITEM fn functions::unused:: + //~ MONO_ITEM fn functions::unused:: // Function uses type parameter in value of a binding. pub fn used_binding_value() { let _: T = Default::default(); } -//~ MONO_ITEM fn functions::used_binding_value:: -//~ MONO_ITEM fn functions::used_binding_value:: + //~ MONO_ITEM fn functions::used_binding_value:: + //~ MONO_ITEM fn functions::used_binding_value:: // Function uses type parameter in type of a binding. pub fn used_binding_type() { let _: Option = None; } -//~ MONO_ITEM fn functions::used_binding_type:: -//~ MONO_ITEM fn functions::used_binding_type:: + //~ MONO_ITEM fn functions::used_binding_type:: + //~ MONO_ITEM fn functions::used_binding_type:: // Function uses type parameter in argument. - pub fn used_argument(_: T) { - } + pub fn used_argument(_: T) {} -//~ MONO_ITEM fn functions::used_argument:: -//~ MONO_ITEM fn functions::used_argument:: -// + //~ MONO_ITEM fn functions::used_argument:: + //~ MONO_ITEM fn functions::used_argument:: + // // Function uses type parameter in substitutions to another function. pub fn used_substs() { unused::() } -//~ MONO_ITEM fn functions::used_substs:: -//~ MONO_ITEM fn functions::used_substs:: + //~ MONO_ITEM fn functions::used_substs:: + //~ MONO_ITEM fn functions::used_substs:: } - mod closures { // Function doesn't have any type parameters to be unused. pub fn no_parameters() { let _ = || {}; } -//~ MONO_ITEM fn closures::no_parameters + //~ MONO_ITEM fn closures::no_parameters // Function has an unused type parameter in parent and closure. pub fn unused() -> u32 { @@ -64,8 +61,8 @@ mod closures { add_one(3) } -//~ MONO_ITEM fn closures::unused::::{closure#0} -//~ MONO_ITEM fn closures::unused:: + //~ MONO_ITEM fn closures::unused::::{closure#0} + //~ MONO_ITEM fn closures::unused:: // Function has an unused type parameter in closure, but not in parent. pub fn used_parent() -> u32 { @@ -74,9 +71,9 @@ mod closures { add_one(3) } -//~ MONO_ITEM fn closures::used_parent::::{closure#0} -//~ MONO_ITEM fn closures::used_parent:: -//~ MONO_ITEM fn closures::used_parent:: + //~ MONO_ITEM fn closures::used_parent::::{closure#0} + //~ MONO_ITEM fn closures::used_parent:: + //~ MONO_ITEM fn closures::used_parent:: // Function uses type parameter in value of a binding in closure. pub fn used_binding_value() -> T { @@ -88,10 +85,10 @@ mod closures { x() } -//~ MONO_ITEM fn closures::used_binding_value::::{closure#0} -//~ MONO_ITEM fn closures::used_binding_value::::{closure#0} -//~ MONO_ITEM fn closures::used_binding_value:: -//~ MONO_ITEM fn closures::used_binding_value:: + //~ MONO_ITEM fn closures::used_binding_value::::{closure#0} + //~ MONO_ITEM fn closures::used_binding_value::::{closure#0} + //~ MONO_ITEM fn closures::used_binding_value:: + //~ MONO_ITEM fn closures::used_binding_value:: // Function uses type parameter in type of a binding in closure. pub fn used_binding_type() -> Option { @@ -103,10 +100,10 @@ mod closures { x() } -//~ MONO_ITEM fn closures::used_binding_type::::{closure#0} -//~ MONO_ITEM fn closures::used_binding_type::::{closure#0} -//~ MONO_ITEM fn closures::used_binding_type:: -//~ MONO_ITEM fn closures::used_binding_type:: + //~ MONO_ITEM fn closures::used_binding_type::::{closure#0} + //~ MONO_ITEM fn closures::used_binding_type::::{closure#0} + //~ MONO_ITEM fn closures::used_binding_type:: + //~ MONO_ITEM fn closures::used_binding_type:: // Function and closure uses type parameter in argument. pub fn used_argument(t: T) -> u32 { @@ -114,10 +111,10 @@ mod closures { x(t) } -//~ MONO_ITEM fn closures::used_argument::::{closure#0} -//~ MONO_ITEM fn closures::used_argument::::{closure#0} -//~ MONO_ITEM fn closures::used_argument:: -//~ MONO_ITEM fn closures::used_argument:: + //~ MONO_ITEM fn closures::used_argument::::{closure#0} + //~ MONO_ITEM fn closures::used_argument::::{closure#0} + //~ MONO_ITEM fn closures::used_argument:: + //~ MONO_ITEM fn closures::used_argument:: // Closure uses type parameter in argument. pub fn used_argument_closure() -> u32 { @@ -126,10 +123,10 @@ mod closures { x(t) } -//~ MONO_ITEM fn closures::used_argument_closure::::{closure#0} -//~ MONO_ITEM fn closures::used_argument_closure::::{closure#0} -//~ MONO_ITEM fn closures::used_argument_closure:: -//~ MONO_ITEM fn closures::used_argument_closure:: + //~ MONO_ITEM fn closures::used_argument_closure::::{closure#0} + //~ MONO_ITEM fn closures::used_argument_closure::::{closure#0} + //~ MONO_ITEM fn closures::used_argument_closure:: + //~ MONO_ITEM fn closures::used_argument_closure:: // Closure uses type parameter as upvar. pub fn used_upvar() -> T { @@ -138,10 +135,10 @@ mod closures { y() } -//~ MONO_ITEM fn closures::used_upvar::::{closure#0} -//~ MONO_ITEM fn closures::used_upvar::::{closure#0} -//~ MONO_ITEM fn closures::used_upvar:: -//~ MONO_ITEM fn closures::used_upvar:: + //~ MONO_ITEM fn closures::used_upvar::::{closure#0} + //~ MONO_ITEM fn closures::used_upvar::::{closure#0} + //~ MONO_ITEM fn closures::used_upvar:: + //~ MONO_ITEM fn closures::used_upvar:: // Closure uses type parameter in substitutions to another function. pub fn used_substs() { @@ -149,10 +146,10 @@ mod closures { x() } -//~ MONO_ITEM fn closures::used_substs::::{closure#0} -//~ MONO_ITEM fn closures::used_substs::::{closure#0} -//~ MONO_ITEM fn closures::used_substs:: -//~ MONO_ITEM fn closures::used_substs:: + //~ MONO_ITEM fn closures::used_substs::::{closure#0} + //~ MONO_ITEM fn closures::used_substs::::{closure#0} + //~ MONO_ITEM fn closures::used_substs:: + //~ MONO_ITEM fn closures::used_substs:: } mod methods { @@ -160,32 +157,30 @@ mod methods { impl Foo { // Function has an unused type parameter from impl. - pub fn unused_impl() { - } + pub fn unused_impl() {} -//~ MONO_ITEM fn methods::Foo::::unused_impl + //~ MONO_ITEM fn methods::Foo::::unused_impl // Function has an unused type parameter from impl and fn. - pub fn unused_both() { - } + pub fn unused_both() {} -//~ MONO_ITEM fn methods::Foo::::unused_both:: + //~ MONO_ITEM fn methods::Foo::::unused_both:: // Function uses type parameter from impl. pub fn used_impl() { let _: F = Default::default(); } -//~ MONO_ITEM fn methods::Foo::::used_impl -//~ MONO_ITEM fn methods::Foo::::used_impl + //~ MONO_ITEM fn methods::Foo::::used_impl + //~ MONO_ITEM fn methods::Foo::::used_impl // Function uses type parameter from impl. pub fn used_fn() { let _: G = Default::default(); } -//~ MONO_ITEM fn methods::Foo::::used_fn:: -//~ MONO_ITEM fn methods::Foo::::used_fn:: + //~ MONO_ITEM fn methods::Foo::::used_fn:: + //~ MONO_ITEM fn methods::Foo::::used_fn:: // Function uses type parameter from impl. pub fn used_both() { @@ -193,16 +188,16 @@ mod methods { let _: G = Default::default(); } -//~ MONO_ITEM fn methods::Foo::::used_both:: -//~ MONO_ITEM fn methods::Foo::::used_both:: + //~ MONO_ITEM fn methods::Foo::::used_both:: + //~ MONO_ITEM fn methods::Foo::::used_both:: // Function uses type parameter in substitutions to another function. pub fn used_substs() { super::functions::unused::() } -//~ MONO_ITEM fn methods::Foo::::used_substs -//~ MONO_ITEM fn methods::Foo::::used_substs + //~ MONO_ITEM fn methods::Foo::::used_substs + //~ MONO_ITEM fn methods::Foo::::used_substs // Function has an unused type parameter from impl and fn. pub fn closure_unused_all() -> u32 { @@ -210,8 +205,8 @@ mod methods { add_one(3) } -//~ MONO_ITEM fn methods::Foo::::closure_unused_all::::{closure#0} -//~ MONO_ITEM fn methods::Foo::::closure_unused_all:: + //~ MONO_ITEM fn methods::Foo::::closure_unused_all::::{closure#0} + //~ MONO_ITEM fn methods::Foo::::closure_unused_all:: // Function uses type parameter from impl and fn in closure. pub fn closure_used_both() -> u32 { @@ -224,10 +219,10 @@ mod methods { add_one(3) } -//~ MONO_ITEM fn methods::Foo::::closure_used_both::::{closure#0} -//~ MONO_ITEM fn methods::Foo::::closure_used_both::::{closure#0} -//~ MONO_ITEM fn methods::Foo::::closure_used_both:: -//~ MONO_ITEM fn methods::Foo::::closure_used_both:: + //~ MONO_ITEM fn methods::Foo::::closure_used_both::::{closure#0} + //~ MONO_ITEM fn methods::Foo::::closure_used_both::::{closure#0} + //~ MONO_ITEM fn methods::Foo::::closure_used_both:: + //~ MONO_ITEM fn methods::Foo::::closure_used_both:: // Function uses type parameter from fn in closure. pub fn closure_used_fn() -> u32 { @@ -239,10 +234,10 @@ mod methods { add_one(3) } -//~ MONO_ITEM fn methods::Foo::::closure_used_fn::::{closure#0} -//~ MONO_ITEM fn methods::Foo::::closure_used_fn::::{closure#0} -//~ MONO_ITEM fn methods::Foo::::closure_used_fn:: -//~ MONO_ITEM fn methods::Foo::::closure_used_fn:: + //~ MONO_ITEM fn methods::Foo::::closure_used_fn::::{closure#0} + //~ MONO_ITEM fn methods::Foo::::closure_used_fn::::{closure#0} + //~ MONO_ITEM fn methods::Foo::::closure_used_fn:: + //~ MONO_ITEM fn methods::Foo::::closure_used_fn:: // Function uses type parameter from impl in closure. pub fn closure_used_impl() -> u32 { @@ -254,10 +249,10 @@ mod methods { add_one(3) } -//~ MONO_ITEM fn methods::Foo::::closure_used_impl::::{closure#0} -//~ MONO_ITEM fn methods::Foo::::closure_used_impl::::{closure#0} -//~ MONO_ITEM fn methods::Foo::::closure_used_impl:: -//~ MONO_ITEM fn methods::Foo::::closure_used_impl:: + //~ MONO_ITEM fn methods::Foo::::closure_used_impl::::{closure#0} + //~ MONO_ITEM fn methods::Foo::::closure_used_impl::::{closure#0} + //~ MONO_ITEM fn methods::Foo::::closure_used_impl:: + //~ MONO_ITEM fn methods::Foo::::closure_used_impl:: // Closure uses type parameter in substitutions to another function. pub fn closure_used_substs() { @@ -265,15 +260,13 @@ mod methods { x() } -//~ MONO_ITEM fn methods::Foo::::closure_used_substs::{closure#0} -//~ MONO_ITEM fn methods::Foo::::closure_used_substs::{closure#0} -//~ MONO_ITEM fn methods::Foo::::closure_used_substs -//~ MONO_ITEM fn methods::Foo::::closure_used_substs + //~ MONO_ITEM fn methods::Foo::::closure_used_substs::{closure#0} + //~ MONO_ITEM fn methods::Foo::::closure_used_substs::{closure#0} + //~ MONO_ITEM fn methods::Foo::::closure_used_substs + //~ MONO_ITEM fn methods::Foo::::closure_used_substs } } - - fn dispatch() { functions::no_parameters(); functions::unused::(); diff --git a/tests/codegen/aarch64-struct-align-128.rs b/tests/codegen/aarch64-struct-align-128.rs index 0a30a2527da6..d1b4132d501f 100644 --- a/tests/codegen/aarch64-struct-align-128.rs +++ b/tests/codegen/aarch64-struct-align-128.rs @@ -12,14 +12,12 @@ #![crate_type = "lib"] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="freeze"] -trait Freeze { } -#[lang="copy"] -trait Copy { } - - +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} // Passed as `[i64 x 2]`, since it's an aggregate with size <= 128 bits, align < 128 bits. #[repr(C)] @@ -31,7 +29,7 @@ pub struct Align8 { // repr(transparent), so same as above. #[repr(transparent)] pub struct Transparent8 { - a: Align8 + a: Align8, } // Passed as `[i64 x 2]`, since it's an aggregate with size <= 128 bits, align < 128 bits. @@ -47,8 +45,6 @@ extern "C" { fn test_8(a: Align8, b: Transparent8, c: Wrapped8); } - - // Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits. // EXCEPT on Linux, where there's a special case to use its unadjusted alignment, // making it the same as `Align8`, so it's be passed as `[i64 x 2]`. @@ -62,7 +58,7 @@ pub struct Align16 { // repr(transparent), so same as above. #[repr(transparent)] pub struct Transparent16 { - a: Align16 + a: Align16, } // Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits. @@ -79,8 +75,6 @@ extern "C" { fn test_16(a: Align16, b: Transparent16, c: Wrapped16); } - - // Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits. #[repr(C)] pub struct I128 { @@ -90,13 +84,13 @@ pub struct I128 { // repr(transparent), so same as above. #[repr(transparent)] pub struct TransparentI128 { - a: I128 + a: I128, } // Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits. #[repr(C)] pub struct WrappedI128 { - pub a: I128 + pub a: I128, } extern "C" { @@ -106,8 +100,6 @@ extern "C" { fn test_i128(a: I128, b: TransparentI128, c: WrappedI128); } - - // Passed as `[2 x i64]`, since it's an aggregate with size <= 128 bits, align < 128 bits. // Note that the Linux special case does not apply, because packing is not considered "adjustment". #[repr(C)] @@ -119,13 +111,13 @@ pub struct Packed { // repr(transparent), so same as above. #[repr(transparent)] pub struct TransparentPacked { - a: Packed + a: Packed, } // Passed as `[2 x i64]`, since it's an aggregate with size <= 128 bits, align < 128 bits. #[repr(C)] pub struct WrappedPacked { - pub a: Packed + pub a: Packed, } extern "C" { @@ -135,13 +127,19 @@ extern "C" { fn test_packed(a: Packed, b: TransparentPacked, c: WrappedPacked); } - - pub unsafe fn main( - a1: Align8, a2: Transparent8, a3: Wrapped8, - b1: Align16, b2: Transparent16, b3: Wrapped16, - c1: I128, c2: TransparentI128, c3: WrappedI128, - d1: Packed, d2: TransparentPacked, d3: WrappedPacked, + a1: Align8, + a2: Transparent8, + a3: Wrapped8, + b1: Align16, + b2: Transparent16, + b3: Wrapped16, + c1: I128, + c2: TransparentI128, + c3: WrappedI128, + d1: Packed, + d2: TransparentPacked, + d3: WrappedPacked, ) { test_8(a1, a2, a3); test_16(b1, b2, b3); diff --git a/tests/codegen/abi-efiapi.rs b/tests/codegen/abi-efiapi.rs index fa73f649ed87..986d042268aa 100644 --- a/tests/codegen/abi-efiapi.rs +++ b/tests/codegen/abi-efiapi.rs @@ -17,12 +17,12 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="freeze"] -trait Freeze { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} //x86_64: define win64cc void @has_efiapi //i686: define void @has_efiapi diff --git a/tests/codegen/abi-main-signature-16bit-c-int.rs b/tests/codegen/abi-main-signature-16bit-c-int.rs index 9832088ab338..d44b80475e47 100644 --- a/tests/codegen/abi-main-signature-16bit-c-int.rs +++ b/tests/codegen/abi-main-signature-16bit-c-int.rs @@ -6,8 +6,6 @@ //@[avr] only-avr //@[msp] only-msp430 - -fn main() { -} +fn main() {} // CHECK: define i16 @main(i16, i8**) diff --git a/tests/codegen/abi-main-signature-32bit-c-int.rs b/tests/codegen/abi-main-signature-32bit-c-int.rs index 7684024a2e38..ce475adde44c 100644 --- a/tests/codegen/abi-main-signature-32bit-c-int.rs +++ b/tests/codegen/abi-main-signature-32bit-c-int.rs @@ -6,7 +6,6 @@ //@ ignore-avr //@ ignore-wasi wasi codegens the main symbol differently -fn main() { -} +fn main() {} // CHECK: define{{( hidden| noundef)*}} i32 @main(i32{{( %0)?}}, ptr{{( %1)?}}) diff --git a/tests/codegen/abi-repr-ext.rs b/tests/codegen/abi-repr-ext.rs index 2e100a372355..a42f73566961 100644 --- a/tests/codegen/abi-repr-ext.rs +++ b/tests/codegen/abi-repr-ext.rs @@ -24,14 +24,17 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} #[repr(i8)] pub enum Type { Type1 = 0, - Type2 = 1 + Type2 = 1, } // To accommodate rust#97800, one might consider writing the below as: @@ -50,7 +53,6 @@ pub enum Type { // riscv-SAME: signext // CHECK-SAME: i8 @test() - #[no_mangle] pub extern "C" fn test() -> Type { Type::Type1 diff --git a/tests/codegen/abi-x86_64_sysv.rs b/tests/codegen/abi-x86_64_sysv.rs index 659c1d93e208..09909f994d65 100644 --- a/tests/codegen/abi-x86_64_sysv.rs +++ b/tests/codegen/abi-x86_64_sysv.rs @@ -5,25 +5,25 @@ #![crate_type = "lib"] pub struct S24 { - a: i8, - b: i8, - c: i8, + a: i8, + b: i8, + c: i8, } pub struct S48 { - a: i16, - b: i16, - c: i8, + a: i16, + b: i16, + c: i8, } // CHECK: i24 @struct_24_bits(i24 #[no_mangle] pub extern "sysv64" fn struct_24_bits(a: S24) -> S24 { - a + a } // CHECK: i48 @struct_48_bits(i48 #[no_mangle] pub extern "sysv64" fn struct_48_bits(a: S48) -> S48 { - a + a } diff --git a/tests/codegen/adjustments.rs b/tests/codegen/adjustments.rs index 549a9737eb15..7f7831def083 100644 --- a/tests/codegen/adjustments.rs +++ b/tests/codegen/adjustments.rs @@ -5,17 +5,16 @@ // Hack to get the correct size for the length part in slices // CHECK: @helper([[USIZE:i[0-9]+]] %_1) #[no_mangle] -pub fn helper(_: usize) { -} +pub fn helper(_: usize) {} // CHECK-LABEL: @no_op_slice_adjustment #[no_mangle] pub fn no_op_slice_adjustment(x: &[u8]) -> &[u8] { // We used to generate an extra alloca and memcpy for the block's trailing expression value, so // check that we copy directly to the return value slot -// CHECK: %0 = insertvalue { ptr, [[USIZE]] } poison, ptr %x.0, 0 -// CHECK: %1 = insertvalue { ptr, [[USIZE]] } %0, [[USIZE]] %x.1, 1 -// CHECK: ret { ptr, [[USIZE]] } %1 + // CHECK: %0 = insertvalue { ptr, [[USIZE]] } poison, ptr %x.0, 0 + // CHECK: %1 = insertvalue { ptr, [[USIZE]] } %0, [[USIZE]] %x.1, 1 + // CHECK: ret { ptr, [[USIZE]] } %1 { x } } @@ -24,6 +23,6 @@ pub fn no_op_slice_adjustment(x: &[u8]) -> &[u8] { pub fn no_op_slice_adjustment2(x: &[u8]) -> &[u8] { // We used to generate an extra alloca and memcpy for the function's return value, so check // that there's no memcpy (the slice is written to sret_slot element-wise) -// CHECK-NOT: call void @llvm.memcpy. + // CHECK-NOT: call void @llvm.memcpy. no_op_slice_adjustment(x) } diff --git a/tests/codegen/align-byval.rs b/tests/codegen/align-byval.rs index 3a2be2b2b9c3..223696229cb1 100644 --- a/tests/codegen/align-byval.rs +++ b/tests/codegen/align-byval.rs @@ -23,9 +23,12 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} impl Copy for i32 {} impl Copy for i64 {} @@ -58,7 +61,7 @@ pub struct ForceAlign4 { pub struct NaturalAlign8 { a: i64, b: i64, - c: i64 + c: i64, } // On i686-windows, this is passed by reference (because alignment is >4 and requested/forced), @@ -68,7 +71,7 @@ pub struct NaturalAlign8 { pub struct ForceAlign8 { a: i64, b: i64, - c: i64 + c: i64, } // On i686-windows, this is passed on stack, because requested alignment is <=4. @@ -77,28 +80,28 @@ pub struct ForceAlign8 { pub struct LowerFA8 { a: i64, b: i64, - c: i64 + c: i64, } // On i686-windows, this is passed by reference, because it contains a field with // requested/forced alignment. #[repr(C)] pub struct WrappedFA8 { - a: ForceAlign8 + a: ForceAlign8, } // On i686-windows, this has the same ABI as ForceAlign8, i.e. passed by reference. #[repr(transparent)] pub struct TransparentFA8 { _0: (), - a: ForceAlign8 + a: ForceAlign8, } #[repr(C)] #[repr(align(16))] pub struct ForceAlign16 { a: [i32; 16], - b: i8 + b: i8, } // CHECK-LABEL: @call_na1 diff --git a/tests/codegen/align-enum.rs b/tests/codegen/align-enum.rs index 93d5a87fb309..e8dd95d3afb0 100644 --- a/tests/codegen/align-enum.rs +++ b/tests/codegen/align-enum.rs @@ -18,8 +18,8 @@ pub struct Nested64 { // CHECK-LABEL: @align64 #[no_mangle] pub fn align64(a: u32) -> Align64 { -// CHECK: %a64 = alloca [64 x i8], align 64 -// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 64 %{{.*}}, ptr align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) + // CHECK: %a64 = alloca [64 x i8], align 64 + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 64 %{{.*}}, ptr align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) let a64 = Align64::A(a); a64 } @@ -27,7 +27,7 @@ pub fn align64(a: u32) -> Align64 { // CHECK-LABEL: @nested64 #[no_mangle] pub fn nested64(a: u8, b: u32, c: u16) -> Nested64 { -// CHECK: %n64 = alloca [128 x i8], align 64 + // CHECK: %n64 = alloca [128 x i8], align 64 let n64 = Nested64 { a, b: Align64::B(b), c }; n64 } diff --git a/tests/codegen/align-offset.rs b/tests/codegen/align-offset.rs index 15b11f413cb5..aeac230f718f 100644 --- a/tests/codegen/align-offset.rs +++ b/tests/codegen/align-offset.rs @@ -53,7 +53,6 @@ pub fn align_offset_word_slice(slice: &[Align4]) -> usize { slice.as_ptr().align_offset(32) } - // CHECK-LABEL: @align_offset_word_ptr(ptr{{.+}}%ptr #[no_mangle] pub fn align_offset_word_ptr(ptr: *const Align4) -> usize { diff --git a/tests/codegen/align-struct.rs b/tests/codegen/align-struct.rs index e70b42b47db8..cc65b08a9223 100644 --- a/tests/codegen/align-struct.rs +++ b/tests/codegen/align-struct.rs @@ -25,9 +25,9 @@ pub enum Enum64 { // CHECK-LABEL: @align64 #[no_mangle] -pub fn align64(i : i32) -> Align64 { -// CHECK: %a64 = alloca [64 x i8], align 64 -// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 64 %{{.*}}, ptr align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) +pub fn align64(i: i32) -> Align64 { + // CHECK: %a64 = alloca [64 x i8], align 64 + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 64 %{{.*}}, ptr align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) let a64 = Align64(i); a64 } @@ -37,14 +37,14 @@ pub fn align64(i : i32) -> Align64 { // CHECK-LABEL: @align64_load #[no_mangle] pub fn align64_load(a: Align64) -> i32 { -// CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 64 + // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 64 a.0 } // CHECK-LABEL: @nested64 #[no_mangle] pub fn nested64(a: Align64, b: i32, c: i32, d: i8) -> Nested64 { -// CHECK: %n64 = alloca [128 x i8], align 64 + // CHECK: %n64 = alloca [128 x i8], align 64 let n64 = Nested64 { a, b, c, d }; n64 } @@ -52,7 +52,7 @@ pub fn nested64(a: Align64, b: i32, c: i32, d: i8) -> Nested64 { // CHECK-LABEL: @enum4 #[no_mangle] pub fn enum4(a: i32) -> Enum4 { -// CHECK: %e4 = alloca [8 x i8], align 4 + // CHECK: %e4 = alloca [8 x i8], align 4 let e4 = Enum4::A(a); e4 } @@ -60,7 +60,7 @@ pub fn enum4(a: i32) -> Enum4 { // CHECK-LABEL: @enum64 #[no_mangle] pub fn enum64(a: Align64) -> Enum64 { -// CHECK: %e64 = alloca [128 x i8], align 64 + // CHECK: %e64 = alloca [128 x i8], align 64 let e64 = Enum64::A(a); e64 } diff --git a/tests/codegen/array-cmp.rs b/tests/codegen/array-cmp.rs index 194c0adf1d2e..2565a385b61b 100644 --- a/tests/codegen/array-cmp.rs +++ b/tests/codegen/array-cmp.rs @@ -10,9 +10,10 @@ #[no_mangle] pub fn compare() -> bool { let bytes = 12.5f32.to_ne_bytes(); - bytes == if cfg!(target_endian = "big") { - [0x41, 0x48, 0x00, 0x00] - } else { - [0x00, 0x00, 0x48, 0x41] - } + bytes + == if cfg!(target_endian = "big") { + [0x41, 0x48, 0x00, 0x00] + } else { + [0x00, 0x00, 0x48, 0x41] + } } diff --git a/tests/codegen/asm-maybe-uninit.rs b/tests/codegen/asm-maybe-uninit.rs index f9bf280b3846..55813c35a468 100644 --- a/tests/codegen/asm-maybe-uninit.rs +++ b/tests/codegen/asm-maybe-uninit.rs @@ -4,8 +4,8 @@ #![crate_type = "rlib"] #![allow(asm_sub_register)] -use std::mem::MaybeUninit; use std::arch::asm; +use std::mem::MaybeUninit; // CHECK-LABEL: @int #[no_mangle] diff --git a/tests/codegen/asm-sanitize-llvm.rs b/tests/codegen/asm-sanitize-llvm.rs index 8638ed2236ac..fb332f9a0f3e 100644 --- a/tests/codegen/asm-sanitize-llvm.rs +++ b/tests/codegen/asm-sanitize-llvm.rs @@ -21,14 +21,10 @@ trait Copy {} pub unsafe fn we_escape_dollar_signs() { // CHECK: call void asm sideeffect alignstack inteldialect "banana$$:" - asm!( - r"banana$:", - ) + asm!(r"banana$:",) } pub unsafe fn we_escape_escapes_too() { // CHECK: call void asm sideeffect alignstack inteldialect "banana\{{(\\|5C)}}36:" - asm!( - r"banana\36:", - ) + asm!(r"banana\36:",) } diff --git a/tests/codegen/atomicptr.rs b/tests/codegen/atomicptr.rs index cbbd56155123..ea8b382c8fcc 100644 --- a/tests/codegen/atomicptr.rs +++ b/tests/codegen/atomicptr.rs @@ -6,13 +6,12 @@ //@ compile-flags: -O -Cno-prepopulate-passes #![crate_type = "lib"] - #![feature(strict_provenance)] #![feature(strict_provenance_atomic_ptr)] +use std::ptr::without_provenance_mut; use std::sync::atomic::AtomicPtr; use std::sync::atomic::Ordering::Relaxed; -use std::ptr::without_provenance_mut; // Portability hack so that we can say [[USIZE]] instead of i64/i32/i16 for usize. // CHECK: @helper([[USIZE:i[0-9]+]] noundef %_1) diff --git a/tests/codegen/autovectorize-f32x4.rs b/tests/codegen/autovectorize-f32x4.rs index 90c9f3691045..254362842f91 100644 --- a/tests/codegen/autovectorize-f32x4.rs +++ b/tests/codegen/autovectorize-f32x4.rs @@ -5,25 +5,20 @@ // CHECK-LABEL: @auto_vectorize_direct #[no_mangle] pub fn auto_vectorize_direct(a: [f32; 4], b: [f32; 4]) -> [f32; 4] { -// CHECK: load <4 x float> -// CHECK: load <4 x float> -// CHECK: fadd <4 x float> -// CHECK: store <4 x float> - [ - a[0] + b[0], - a[1] + b[1], - a[2] + b[2], - a[3] + b[3], - ] + // CHECK: load <4 x float> + // CHECK: load <4 x float> + // CHECK: fadd <4 x float> + // CHECK: store <4 x float> + [a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]] } // CHECK-LABEL: @auto_vectorize_loop #[no_mangle] pub fn auto_vectorize_loop(a: [f32; 4], b: [f32; 4]) -> [f32; 4] { -// CHECK: load <4 x float> -// CHECK: load <4 x float> -// CHECK: fadd <4 x float> -// CHECK: store <4 x float> + // CHECK: load <4 x float> + // CHECK: load <4 x float> + // CHECK: fadd <4 x float> + // CHECK: store <4 x float> let mut c = [0.0; 4]; for i in 0..4 { c[i] = a[i] + b[i]; @@ -34,9 +29,9 @@ pub fn auto_vectorize_loop(a: [f32; 4], b: [f32; 4]) -> [f32; 4] { // CHECK-LABEL: @auto_vectorize_array_from_fn #[no_mangle] pub fn auto_vectorize_array_from_fn(a: [f32; 4], b: [f32; 4]) -> [f32; 4] { -// CHECK: load <4 x float> -// CHECK: load <4 x float> -// CHECK: fadd <4 x float> -// CHECK: store <4 x float> + // CHECK: load <4 x float> + // CHECK: load <4 x float> + // CHECK: fadd <4 x float> + // CHECK: store <4 x float> std::array::from_fn(|i| a[i] + b[i]) } diff --git a/tests/codegen/auxiliary/extern_decl.rs b/tests/codegen/auxiliary/extern_decl.rs index edc48351869a..d17e77b14448 100644 --- a/tests/codegen/auxiliary/extern_decl.rs +++ b/tests/codegen/auxiliary/extern_decl.rs @@ -5,7 +5,9 @@ #![crate_type = "lib"] #[no_mangle] -pub fn extern_fn() -> u8 { unsafe { extern_static } } +pub fn extern_fn() -> u8 { + unsafe { extern_static } +} #[no_mangle] pub static mut extern_static: u8 = 71; diff --git a/tests/codegen/auxiliary/nounwind.rs b/tests/codegen/auxiliary/nounwind.rs index 73c5aee33878..40f66442c6ed 100644 --- a/tests/codegen/auxiliary/nounwind.rs +++ b/tests/codegen/auxiliary/nounwind.rs @@ -1,3 +1,2 @@ #[no_mangle] -pub fn bar() { -} +pub fn bar() {} diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs index fb53abecfdb2..2d9efb52c7cf 100644 --- a/tests/codegen/avr/avr-func-addrspace.rs +++ b/tests/codegen/avr/avr-func-addrspace.rs @@ -14,15 +14,18 @@ #![no_core] #[lang = "sized"] -pub trait Sized { } +pub trait Sized {} #[lang = "copy"] -pub trait Copy { } +pub trait Copy {} #[lang = "receiver"] -pub trait Receiver { } +pub trait Receiver {} #[lang = "tuple_trait"] -pub trait Tuple { } +pub trait Tuple {} -pub struct Result { _a: T, _b: E } +pub struct Result { + _a: T, + _b: E, +} impl Copy for usize {} impl Copy for &usize {} @@ -39,7 +42,7 @@ pub trait FnOnce { } #[lang = "fn_mut"] -pub trait FnMut : FnOnce { +pub trait FnMut: FnOnce { extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; } @@ -64,7 +67,7 @@ fn arbitrary_black_box(ptr: &usize, _: &mut u32) -> Result<(), ()> { #[inline(never)] #[no_mangle] -fn call_through_fn_trait(a: &mut impl Fn<(), Output=()>) { +fn call_through_fn_trait(a: &mut impl Fn<(), Output = ()>) { (*a)() } @@ -110,7 +113,10 @@ pub unsafe fn transmute_fn_ptr_to_data(x: fn()) -> *const () { transmute(x) } -pub enum Either { A(T), B(U) } +pub enum Either { + A(T), + B(U), +} // Previously, we would codegen this as passing/returning a scalar pair of `{ i8, ptr }`, // with the `ptr` field representing both `&i32` and `fn()` depending on the variant. diff --git a/tests/codegen/binary-search-index-no-bound-check.rs b/tests/codegen/binary-search-index-no-bound-check.rs index 96f6bb54b3fe..a213c015a40b 100644 --- a/tests/codegen/binary-search-index-no-bound-check.rs +++ b/tests/codegen/binary-search-index-no-bound-check.rs @@ -11,11 +11,7 @@ pub fn binary_search_index_no_bounds_check(s: &[u8]) -> u8 { // CHECK-NOT: slice_start_index_len_fail // CHECK-NOT: slice_end_index_len_fail // CHECK-NOT: panic_bounds_check - if let Ok(idx) = s.binary_search(&b'\\') { - s[idx] - } else { - 42 - } + if let Ok(idx) = s.binary_search(&b'\\') { s[idx] } else { 42 } } // Similarly, check that `partition_point` is known to return a valid fencepost. diff --git a/tests/codegen/bool-cmp.rs b/tests/codegen/bool-cmp.rs index 29ee3e0627bc..71d3411689f4 100644 --- a/tests/codegen/bool-cmp.rs +++ b/tests/codegen/bool-cmp.rs @@ -10,9 +10,9 @@ use std::cmp::Ordering; // CHECK-LABEL: @cmp_bool #[no_mangle] pub fn cmp_bool(a: bool, b: bool) -> Ordering { -// LLVM 10 produces (zext a) + (sext b), but the final lowering is (zext a) - (zext b). -// CHECK: zext i1 -// CHECK: {{z|s}}ext i1 -// CHECK: {{sub|add}} nsw + // LLVM 10 produces (zext a) + (sext b), but the final lowering is (zext a) - (zext b). + // CHECK: zext i1 + // CHECK: {{z|s}}ext i1 + // CHECK: {{sub|add}} nsw a.cmp(&b) } diff --git a/tests/codegen/branch-protection.rs b/tests/codegen/branch-protection.rs index 0961b1b9f522..a29ec67d578b 100644 --- a/tests/codegen/branch-protection.rs +++ b/tests/codegen/branch-protection.rs @@ -12,12 +12,11 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} // A basic test function. -pub fn test() { -} +pub fn test() {} // BTI: !"branch-target-enforcement", i32 1 // BTI: !"sign-return-address", i32 0 diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs index 9c31acc9bb7c..c6a8b7bbf378 100644 --- a/tests/codegen/cast-target-abi.rs +++ b/tests/codegen/cast-target-abi.rs @@ -18,9 +18,12 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} // This struct will be passed as a single `i64` or `i32`. // This may be (if `i64)) larger than the Rust layout, which is just `{ i16, i16 }`. @@ -104,7 +107,6 @@ pub unsafe fn return_twou16s() -> TwoU16s { // powerpc64: [[RETVAL:%.+]] = alloca [4 x i8], align 2 // powerpc64: call void @returns_twou16s(ptr {{.+}} [[RETVAL]]) - // The other targets copy the cast ABI type to an alloca. // aarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] @@ -151,7 +153,6 @@ pub unsafe fn return_fiveu16s() -> FiveU16s { // powerpc64: call void @returns_fiveu16s(ptr {{.+}} [[RET_PTR]]) - // The other targets copy the cast ABI type to the sret pointer. // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] @@ -199,7 +200,6 @@ pub unsafe fn return_doubledouble() -> DoubleDouble { // powerpc64: [[RETVAL:%.+]] = alloca [16 x i8], align 8 // powerpc64: call void @returns_doubledouble(ptr {{.+}} [[RETVAL]]) - // The other targets copy the cast ABI type to an alloca. // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] @@ -266,7 +266,6 @@ pub unsafe fn return_doublefloat() -> DoubleFloat { // powerpc64: [[RETVAL:%.+]] = alloca [16 x i8], align 8 // powerpc64: call void @returns_doublefloat(ptr {{.+}} [[RETVAL]]) - // The other targets copy the cast ABI type to an alloca. // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] diff --git a/tests/codegen/cf-protection.rs b/tests/codegen/cf-protection.rs index 5120bbf114d9..244d1eb25442 100644 --- a/tests/codegen/cf-protection.rs +++ b/tests/codegen/cf-protection.rs @@ -13,12 +13,11 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} // A basic test function. -pub fn test() { -} +pub fn test() {} // undefined-NOT: !"cf-protection-branch" // undefined-NOT: !"cf-protection-return" diff --git a/tests/codegen/cffi/ffi-const.rs b/tests/codegen/cffi/ffi-const.rs index 8044ad105d5d..564b8f7f8d8d 100644 --- a/tests/codegen/cffi/ffi-const.rs +++ b/tests/codegen/cffi/ffi-const.rs @@ -2,12 +2,15 @@ #![crate_type = "lib"] #![feature(ffi_const)] -pub fn bar() { unsafe { foo() } } +pub fn bar() { + unsafe { foo() } +} extern "C" { // CHECK-LABEL: declare{{.*}}void @foo() // CHECK-SAME: [[ATTRS:#[0-9]+]] // The attribute changed from `readnone` to `memory(none)` with LLVM 16.0. // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readnone|memory\(none\)}}{{.*}} } - #[ffi_const] pub fn foo(); + #[ffi_const] + pub fn foo(); } diff --git a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs index 35bf00f8f3c3..614d5d94f620 100644 --- a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs +++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs @@ -13,9 +13,12 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} #[repr(C)] struct S { diff --git a/tests/codegen/cffi/ffi-pure.rs b/tests/codegen/cffi/ffi-pure.rs index 51135fd37535..601509d5c90f 100644 --- a/tests/codegen/cffi/ffi-pure.rs +++ b/tests/codegen/cffi/ffi-pure.rs @@ -2,12 +2,15 @@ #![crate_type = "lib"] #![feature(ffi_pure)] -pub fn bar() { unsafe { foo() } } +pub fn bar() { + unsafe { foo() } +} extern "C" { // CHECK-LABEL: declare{{.*}}void @foo() // CHECK-SAME: [[ATTRS:#[0-9]+]] // The attribute changed from `readonly` to `memory(read)` with LLVM 16.0. // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readonly|memory\(read\)}}{{.*}} } - #[ffi_pure] pub fn foo(); + #[ffi_pure] + pub fn foo(); } diff --git a/tests/codegen/cfguard-checks.rs b/tests/codegen/cfguard-checks.rs index 2b09a5fe12c2..cdf6406ad61b 100644 --- a/tests/codegen/cfguard-checks.rs +++ b/tests/codegen/cfguard-checks.rs @@ -4,8 +4,7 @@ #![crate_type = "lib"] // A basic test function. -pub fn test() { -} +pub fn test() {} // Ensure the module flag cfguard=2 is present // CHECK: !"cfguard", i32 2 diff --git a/tests/codegen/cfguard-disabled.rs b/tests/codegen/cfguard-disabled.rs index 105e02072615..90915c0f0c6b 100644 --- a/tests/codegen/cfguard-disabled.rs +++ b/tests/codegen/cfguard-disabled.rs @@ -4,8 +4,7 @@ #![crate_type = "lib"] // A basic test function. -pub fn test() { -} +pub fn test() {} // Ensure the module flag cfguard is not present // CHECK-NOT: !"cfguard" diff --git a/tests/codegen/cfguard-nochecks.rs b/tests/codegen/cfguard-nochecks.rs index 0443880d72da..5f386533ec1a 100644 --- a/tests/codegen/cfguard-nochecks.rs +++ b/tests/codegen/cfguard-nochecks.rs @@ -4,8 +4,7 @@ #![crate_type = "lib"] // A basic test function. -pub fn test() { -} +pub fn test() {} // Ensure the module flag cfguard=1 is present // CHECK: !"cfguard", i32 1 diff --git a/tests/codegen/cfguard-non-msvc.rs b/tests/codegen/cfguard-non-msvc.rs index 5d266de8a94d..1e6559aaf5d2 100644 --- a/tests/codegen/cfguard-non-msvc.rs +++ b/tests/codegen/cfguard-non-msvc.rs @@ -4,8 +4,7 @@ #![crate_type = "lib"] // A basic test function. -pub fn test() { -} +pub fn test() {} // Ensure the cfguard module flag is not added for non-MSVC targets. // CHECK-NOT: !"cfguard" diff --git a/tests/codegen/checked_ilog.rs b/tests/codegen/checked_ilog.rs new file mode 100644 index 000000000000..8f3c07119fee --- /dev/null +++ b/tests/codegen/checked_ilog.rs @@ -0,0 +1,20 @@ +//@ compile-flags: -O + +#![crate_type = "lib"] + +// Ensure that when val < base, we do not divide or multiply. + +// CHECK-LABEL: @checked_ilog +// CHECK-SAME: (i16 noundef %val, i16 noundef %base) +#[no_mangle] +pub fn checked_ilog(val: u16, base: u16) -> Option { + // CHECK-NOT: udiv + // CHECK-NOT: mul + // CHECK: %[[IS_LESS:.+]] = icmp ult i16 %val, %base + // CHECK-NEXT: br i1 %[[IS_LESS]], label %[[TRUE:.+]], label %[[FALSE:.+]] + // CHECK: [[TRUE]]: + // CHECK-NOT: udiv + // CHECK-NOT: mul + // CHECK: ret { i32, i32 } + val.checked_ilog(base) +} diff --git a/tests/codegen/coercions.rs b/tests/codegen/coercions.rs index a205e541df10..63c1742c6399 100644 --- a/tests/codegen/coercions.rs +++ b/tests/codegen/coercions.rs @@ -7,7 +7,7 @@ static X: i32 = 5; // CHECK-LABEL: @raw_ptr_to_raw_ptr_noop // CHECK-NOT: alloca #[no_mangle] -pub fn raw_ptr_to_raw_ptr_noop() -> *const i32{ +pub fn raw_ptr_to_raw_ptr_noop() -> *const i32 { &X as *const i32 } diff --git a/tests/codegen/constant-branch.rs b/tests/codegen/constant-branch.rs index 3328b1eb4a88..a2710cc4b258 100644 --- a/tests/codegen/constant-branch.rs +++ b/tests/codegen/constant-branch.rs @@ -8,18 +8,10 @@ #[no_mangle] pub fn if_bool() { // CHECK: br label %{{.+}} - _ = if true { - 0 - } else { - 1 - }; + _ = if true { 0 } else { 1 }; // CHECK: br label %{{.+}} - _ = if false { - 0 - } else { - 1 - }; + _ = if false { 0 } else { 1 }; } // CHECK-LABEL: @if_constant_int_eq @@ -27,18 +19,10 @@ pub fn if_bool() { pub fn if_constant_int_eq() { let val = 0; // CHECK: br label %{{.+}} - _ = if val == 0 { - 0 - } else { - 1 - }; + _ = if val == 0 { 0 } else { 1 }; // CHECK: br label %{{.+}} - _ = if val == 1 { - 0 - } else { - 1 - }; + _ = if val == 1 { 0 } else { 1 }; } // CHECK-LABEL: @if_constant_match @@ -48,19 +32,19 @@ pub fn if_constant_match() { _ = match 1 { 1 => 2, 2 => 3, - _ => 4 + _ => 4, }; // CHECK: br label %{{.+}} _ = match 1 { 2 => 3, - _ => 4 + _ => 4, }; // CHECK: br label %[[MINUS1:.+]] _ = match -1 { - // CHECK: [[MINUS1]]: - // CHECK: store i32 1 + // CHECK: [[MINUS1]]: + // CHECK: store i32 1 -1 => 1, _ => 0, } diff --git a/tests/codegen/coroutine-debug-msvc.rs b/tests/codegen/coroutine-debug-msvc.rs index e2296db1d594..9e2ec3ea28ac 100644 --- a/tests/codegen/coroutine-debug-msvc.rs +++ b/tests/codegen/coroutine-debug-msvc.rs @@ -11,7 +11,8 @@ use std::ops::Coroutine; fn coroutine_test() -> impl Coroutine { - #[coroutine] || { + #[coroutine] + || { yield 0; let s = String::from("foo"); yield 1; @@ -23,23 +24,23 @@ fn coroutine_test() -> impl Coroutine { // CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$" // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]], // For brevity, we only check the struct name and members of the last variant. -// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14, +// CHECK-SAME: file: [[FILE:![0-9]*]], line: 15, // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant1", scope: [[GEN]], -// CHECK-SAME: file: [[FILE]], line: 18, +// CHECK-SAME: file: [[FILE]], line: 19, // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant2", scope: [[GEN]], -// CHECK-SAME: file: [[FILE]], line: 18, +// CHECK-SAME: file: [[FILE]], line: 19, // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant3", scope: [[GEN]], -// CHECK-SAME: file: [[FILE]], line: 15, +// CHECK-SAME: file: [[FILE]], line: 16, // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]], -// CHECK-SAME: file: [[FILE]], line: 17, +// CHECK-SAME: file: [[FILE]], line: 18, // CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]] // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) diff --git a/tests/codegen/coroutine-debug.rs b/tests/codegen/coroutine-debug.rs index 914515f58b85..d00667a37d5e 100644 --- a/tests/codegen/coroutine-debug.rs +++ b/tests/codegen/coroutine-debug.rs @@ -11,7 +11,8 @@ use std::ops::Coroutine; fn coroutine_test() -> impl Coroutine { - #[coroutine] || { + #[coroutine] + || { yield 0; let s = String::from("foo"); yield 1; @@ -26,26 +27,26 @@ fn coroutine_test() -> impl Coroutine { // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: discriminator: [[DISC:![0-9]*]] // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]], -// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14, +// CHECK-SAME: file: [[FILE:![0-9]*]], line: 15, // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "Unresumed", scope: [[GEN]], // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]], -// CHECK-SAME: file: [[FILE]], line: 18, +// CHECK-SAME: file: [[FILE]], line: 19, // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]], -// CHECK-SAME: file: [[FILE]], line: 18, +// CHECK-SAME: file: [[FILE]], line: 19, // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]], -// CHECK-SAME: file: [[FILE]], line: 15, +// CHECK-SAME: file: [[FILE]], line: 16, // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]], -// CHECK-SAME: file: [[FILE]], line: 17, +// CHECK-SAME: file: [[FILE]], line: 18, // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]], diff --git a/tests/codegen/dealloc-no-unwind.rs b/tests/codegen/dealloc-no-unwind.rs index 667f6fea1857..ead26da610e2 100644 --- a/tests/codegen/dealloc-no-unwind.rs +++ b/tests/codegen/dealloc-no-unwind.rs @@ -1,13 +1,17 @@ //@ compile-flags: -O -#![crate_type="lib"] +#![crate_type = "lib"] struct A; impl Drop for A { fn drop(&mut self) { - extern "C" { fn foo(); } - unsafe { foo(); } + extern "C" { + fn foo(); + } + unsafe { + foo(); + } } } diff --git a/tests/codegen/debug-column.rs b/tests/codegen/debug-column.rs index ff25fbe1b132..d14a5c29142e 100644 --- a/tests/codegen/debug-column.rs +++ b/tests/codegen/debug-column.rs @@ -3,6 +3,7 @@ //@ ignore-windows //@ compile-flags: -C debuginfo=2 +#[rustfmt::skip] fn main() { unsafe { // Column numbers are 1-based. Regression test for #65437. @@ -13,8 +14,8 @@ fn main() { // CHECK: call void @turtle(){{( #[0-9]+)?}}, !dbg [[B:!.*]] /* ż */ turtle(); - // CHECK: [[A]] = !DILocation(line: 10, column: 9, - // CHECK: [[B]] = !DILocation(line: 14, column: 10, + // CHECK: [[A]] = !DILocation(line: 11, column: 9, + // CHECK: [[B]] = !DILocation(line: 15, column: 10, } } diff --git a/tests/codegen/debug-compile-unit-path.rs b/tests/codegen/debug-compile-unit-path.rs index 4be418d66103..6131d9d7351a 100644 --- a/tests/codegen/debug-compile-unit-path.rs +++ b/tests/codegen/debug-compile-unit-path.rs @@ -3,7 +3,7 @@ // // Ensure that we remap the compile unit directory and that we set it to the compilers current // working directory and not something else. -#![crate_type="rlib"] +#![crate_type = "rlib"] // CHECK-DAG: [[FILE:![0-9]*]] = !DIFile(filename: "/base/debug-compile-unit-path.rs{{.*}}", directory: "/cwd/") // CHECK-DAG: {{![0-9]*}} = distinct !DICompileUnit({{.*}}file: [[FILE]] diff --git a/tests/codegen/debuginfo-generic-closure-env-names.rs b/tests/codegen/debuginfo-generic-closure-env-names.rs index 04ff7fff4399..6d56fbc40abe 100644 --- a/tests/codegen/debuginfo-generic-closure-env-names.rs +++ b/tests/codegen/debuginfo-generic-closure-env-names.rs @@ -46,7 +46,6 @@ // NONMSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: ![[function_containing_closure_NAMESPACE]] // MSVC-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "closure_env$0", scope: ![[function_containing_closure_NAMESPACE]] - #![crate_type = "lib"] use std::future::Future; @@ -70,11 +69,9 @@ async fn generic_async_function(x: T) -> T { x } -fn generic_async_block(x: T) -> impl Future { +fn generic_async_block(x: T) -> impl Future { static _X: u8 = 0; // Same as above - async move { - x - } + async move { x } } pub fn instantiate_generics() { diff --git a/tests/codegen/dllimports/auxiliary/wrapper.rs b/tests/codegen/dllimports/auxiliary/wrapper.rs index 7d1f6ab70d5f..00a29f7ee7e5 100644 --- a/tests/codegen/dllimports/auxiliary/wrapper.rs +++ b/tests/codegen/dllimports/auxiliary/wrapper.rs @@ -1,13 +1,13 @@ //@ no-prefer-dynamic #![crate_type = "rlib"] -#[link(name = "dummy", kind="dylib")] +#[link(name = "dummy", kind = "dylib")] extern "C" { pub fn dylib_func2(x: i32) -> i32; pub static dylib_global2: i32; } -#[link(name = "dummy", kind="static")] +#[link(name = "dummy", kind = "static")] extern "C" { pub fn static_func2(x: i32) -> i32; pub static static_global2: i32; diff --git a/tests/codegen/dllimports/main.rs b/tests/codegen/dllimports/main.rs index c1626853b16d..93d350a22380 100644 --- a/tests/codegen/dllimports/main.rs +++ b/tests/codegen/dllimports/main.rs @@ -1,4 +1,4 @@ - // This test is for *-windows-msvc only. +// This test is for *-windows-msvc only. //@ only-windows //@ ignore-gnu @@ -20,13 +20,13 @@ extern crate wrapper; // CHECK: declare noundef i32 @static_func1(i32 noundef) // CHECK: declare noundef i32 @static_func2(i32 noundef) -#[link(name = "dummy", kind="dylib")] +#[link(name = "dummy", kind = "dylib")] extern "C" { pub fn dylib_func1(x: i32) -> i32; pub static dylib_global1: i32; } -#[link(name = "dummy", kind="static")] +#[link(name = "dummy", kind = "static")] extern "C" { pub fn static_func1(x: i32) -> i32; pub static static_global1: i32; diff --git a/tests/codegen/drop-in-place-noalias.rs b/tests/codegen/drop-in-place-noalias.rs index 36532ea8f532..2dc769df1c92 100644 --- a/tests/codegen/drop-in-place-noalias.rs +++ b/tests/codegen/drop-in-place-noalias.rs @@ -3,7 +3,7 @@ // Tests that the compiler can apply `noalias` and other &mut attributes to `drop_in_place`. // Note that non-Unpin types should not get `noalias`, matching &mut behavior. -#![crate_type="lib"] +#![crate_type = "lib"] use std::marker::PhantomPinned; diff --git a/tests/codegen/drop.rs b/tests/codegen/drop.rs index 1e80247ba8aa..b22a8ef27d23 100644 --- a/tests/codegen/drop.rs +++ b/tests/codegen/drop.rs @@ -7,28 +7,26 @@ struct SomeUniqueName; impl Drop for SomeUniqueName { #[inline(never)] - fn drop(&mut self) { - } + fn drop(&mut self) {} } #[inline(never)] -pub fn possibly_unwinding() { -} +pub fn possibly_unwinding() {} // CHECK-LABEL: @droppy #[no_mangle] pub fn droppy() { -// Check that there are exactly 6 drop calls. The cleanups for the unwinding should be reused, so -// that's one new drop call per call to possibly_unwinding(), and finally 3 drop calls for the -// regular function exit. We used to have problems with quadratic growths of drop calls in such -// functions. -// FIXME(eddyb) the `void @` forces a match on the instruction, instead of the -// comment, that's `; call core::ptr::drop_in_place::` -// for the `v0` mangling, should switch to matching on that once `legacy` is gone. -// CHECK-COUNT-6: {{(call|invoke) void @.*}}drop_in_place{{.*}}SomeUniqueName -// CHECK-NOT: {{(call|invoke) void @.*}}drop_in_place{{.*}}SomeUniqueName -// The next line checks for the } that ends the function definition -// CHECK-LABEL: {{^[}]}} + // Check that there are exactly 6 drop calls. The cleanups for the unwinding should be reused, + // so that's one new drop call per call to possibly_unwinding(), and finally 3 drop calls for + // the regular function exit. We used to have problems with quadratic growths of drop calls in + // such functions. + // FIXME(eddyb) the `void @` forces a match on the instruction, instead of the + // comment, that's `; call core::ptr::drop_in_place::` + // for the `v0` mangling, should switch to matching on that once `legacy` is gone. + // CHECK-COUNT-6: {{(call|invoke) void @.*}}drop_in_place{{.*}}SomeUniqueName + // CHECK-NOT: {{(call|invoke) void @.*}}drop_in_place{{.*}}SomeUniqueName + // The next line checks for the } that ends the function definition + // CHECK-LABEL: {{^[}]}} let _s = SomeUniqueName; possibly_unwinding(); let _s = SomeUniqueName; diff --git a/tests/codegen/dst-offset.rs b/tests/codegen/dst-offset.rs index ce735baeb6a9..7177a960432a 100644 --- a/tests/codegen/dst-offset.rs +++ b/tests/codegen/dst-offset.rs @@ -3,7 +3,6 @@ //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 #![crate_type = "lib"] - #![feature(extern_types)] use std::ptr::addr_of; @@ -11,8 +10,7 @@ use std::ptr::addr_of; // Hack to get the correct type for usize // CHECK: @helper([[USIZE:i[0-9]+]] %_1) #[no_mangle] -pub fn helper(_: usize) { -} +pub fn helper(_: usize) {} struct Dst { x: u32, @@ -23,30 +21,31 @@ struct Dst { // CHECK: @dst_dyn_trait_offset(ptr align {{[0-9]+}} [[DATA_PTR:%.+]], ptr align {{[0-9]+}} [[VTABLE_PTR:%.+]]) #[no_mangle] pub fn dst_dyn_trait_offset(s: &Dst) -> &dyn Drop { -// The alignment of dyn trait is unknown, so we compute the offset based on align from the vtable. + // The alignment of dyn trait is unknown, so we compute the offset based on align from the + // vtable. -// CHECK: [[SIZE_PTR:%[0-9]+]] = getelementptr inbounds i8, ptr [[VTABLE_PTR]] -// CHECK: load [[USIZE]], ptr [[SIZE_PTR]] -// CHECK: [[ALIGN_PTR:%[0-9]+]] = getelementptr inbounds i8, ptr [[VTABLE_PTR]] -// CHECK: load [[USIZE]], ptr [[ALIGN_PTR]] + // CHECK: [[SIZE_PTR:%[0-9]+]] = getelementptr inbounds i8, ptr [[VTABLE_PTR]] + // CHECK: load [[USIZE]], ptr [[SIZE_PTR]] + // CHECK: [[ALIGN_PTR:%[0-9]+]] = getelementptr inbounds i8, ptr [[VTABLE_PTR]] + // CHECK: load [[USIZE]], ptr [[ALIGN_PTR]] -// CHECK: getelementptr inbounds i8, ptr [[DATA_PTR]] -// CHECK-NEXT: insertvalue -// CHECK-NEXT: insertvalue -// CHECK-NEXT: ret + // CHECK: getelementptr inbounds i8, ptr [[DATA_PTR]] + // CHECK-NEXT: insertvalue + // CHECK-NEXT: insertvalue + // CHECK-NEXT: ret &s.z } // CHECK-LABEL: @dst_slice_offset #[no_mangle] pub fn dst_slice_offset(s: &Dst<[u16]>) -> &[u16] { -// The alignment of [u16] is known, so we generate a GEP directly. + // The alignment of [u16] is known, so we generate a GEP directly. -// CHECK: start: -// CHECK-NEXT: getelementptr inbounds i8, {{.+}}, [[USIZE]] 6 -// CHECK-NEXT: insertvalue -// CHECK-NEXT: insertvalue -// CHECK-NEXT: ret + // CHECK: start: + // CHECK-NEXT: getelementptr inbounds i8, {{.+}}, [[USIZE]] 6 + // CHECK-NEXT: insertvalue + // CHECK-NEXT: insertvalue + // CHECK-NEXT: ret &s.z } @@ -60,25 +59,25 @@ struct PackedDstSlice { // CHECK-LABEL: @packed_dst_slice_offset #[no_mangle] pub fn packed_dst_slice_offset(s: &PackedDstSlice) -> *const [u16] { -// The alignment of [u16] is known, so we generate a GEP directly. + // The alignment of [u16] is known, so we generate a GEP directly. -// CHECK: start: -// CHECK-NEXT: getelementptr inbounds i8, {{.+}}, [[USIZE]] 5 -// CHECK-NEXT: insertvalue -// CHECK-NEXT: insertvalue -// CHECK-NEXT: ret + // CHECK: start: + // CHECK-NEXT: getelementptr inbounds i8, {{.+}}, [[USIZE]] 5 + // CHECK-NEXT: insertvalue + // CHECK-NEXT: insertvalue + // CHECK-NEXT: ret addr_of!(s.z) } -extern { +extern "C" { pub type Extern; } // CHECK-LABEL: @dst_extern #[no_mangle] pub fn dst_extern(s: &Dst) -> &Extern { -// Computing the alignment of an extern type is currently unsupported and just panics. + // Computing the alignment of an extern type is currently unsupported and just panics. -// CHECK: call void @{{.+}}panic + // CHECK: call void @{{.+}}panic &s.z } diff --git a/tests/codegen/dst-vtable-align-nonzero.rs b/tests/codegen/dst-vtable-align-nonzero.rs index b0507f4c217d..cb07e43238c1 100644 --- a/tests/codegen/dst-vtable-align-nonzero.rs +++ b/tests/codegen/dst-vtable-align-nonzero.rs @@ -10,9 +10,15 @@ pub trait Trait { fn f(&self); } -pub struct WrapperWithAlign1 { x: u8, y: T } +pub struct WrapperWithAlign1 { + x: u8, + y: T, +} -pub struct WrapperWithAlign2 { x: u16, y: T } +pub struct WrapperWithAlign2 { + x: u16, + y: T, +} pub struct Struct { _field: i8, @@ -22,7 +28,7 @@ pub struct Struct { // CHECK-LABEL: @eliminates_runtime_check_when_align_1 #[no_mangle] pub fn eliminates_runtime_check_when_align_1( - x: &Struct> + x: &Struct>, ) -> &WrapperWithAlign1 { // CHECK: load [[USIZE:i[0-9]+]], {{.+}} !range [[RANGE_META:![0-9]+]] // CHECK-NOT: llvm.umax @@ -35,7 +41,7 @@ pub fn eliminates_runtime_check_when_align_1( // CHECK-LABEL: @does_not_eliminate_runtime_check_when_align_2 #[no_mangle] pub fn does_not_eliminate_runtime_check_when_align_2( - x: &Struct> + x: &Struct>, ) -> &WrapperWithAlign2 { // CHECK: [[X0:%[0-9]+]] = load [[USIZE]], {{.+}} !range [[RANGE_META]] // CHECK: {{icmp|llvm.umax}} diff --git a/tests/codegen/ehcontguard_disabled.rs b/tests/codegen/ehcontguard_disabled.rs index dc4b5eb430bf..9efb2721b3e8 100644 --- a/tests/codegen/ehcontguard_disabled.rs +++ b/tests/codegen/ehcontguard_disabled.rs @@ -3,8 +3,7 @@ #![crate_type = "lib"] // A basic test function. -pub fn test() { -} +pub fn test() {} // Ensure the module flag ehcontguard is not present // CHECK-NOT: !"ehcontguard" diff --git a/tests/codegen/ehcontguard_enabled.rs b/tests/codegen/ehcontguard_enabled.rs index fde66f1c148e..ecc5512fd5de 100644 --- a/tests/codegen/ehcontguard_enabled.rs +++ b/tests/codegen/ehcontguard_enabled.rs @@ -3,8 +3,7 @@ #![crate_type = "lib"] // A basic test function. -pub fn test() { -} +pub fn test() {} // Ensure the module flag ehcontguard=1 is present // CHECK: !"ehcontguard", i32 1 diff --git a/tests/codegen/emcripten-catch-unwind.rs b/tests/codegen/emcripten-catch-unwind.rs index 7de7bd81b5c0..6cda8c6799f4 100644 --- a/tests/codegen/emcripten-catch-unwind.rs +++ b/tests/codegen/emcripten-catch-unwind.rs @@ -9,18 +9,23 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} #[rustc_intrinsic] -fn size_of() -> usize { loop {} } +fn size_of() -> usize { + loop {} +} extern "rust-intrinsic" { fn catch_unwind( try_fn: fn(_: *mut u8), data: *mut u8, - catch_fn: fn(_: *mut u8, _: *mut u8) + catch_fn: fn(_: *mut u8, _: *mut u8), ) -> i32; } @@ -36,7 +41,7 @@ pub fn ptr_size() -> usize { pub unsafe fn test_catch_unwind( try_fn: fn(_: *mut u8), data: *mut u8, - catch_fn: fn(_: *mut u8, _: *mut u8) + catch_fn: fn(_: *mut u8, _: *mut u8), ) -> i32 { // CHECK: start: // CHECK: [[ALLOCA:%.*]] = alloca diff --git a/tests/codegen/enable-lto-unit-splitting.rs b/tests/codegen/enable-lto-unit-splitting.rs index e46980944778..51c2671bc4eb 100644 --- a/tests/codegen/enable-lto-unit-splitting.rs +++ b/tests/codegen/enable-lto-unit-splitting.rs @@ -2,9 +2,8 @@ // //@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsplit-lto-unit -#![crate_type="lib"] +#![crate_type = "lib"] -pub fn foo() { -} +pub fn foo() {} // CHECK: !{{[0-9]+}} = !{i32 4, !"EnableSplitLTOUnit", i32 1} diff --git a/tests/codegen/enum/enum-bounds-check.rs b/tests/codegen/enum/enum-bounds-check.rs index a1b32ec9295b..c44c007ed6a9 100644 --- a/tests/codegen/enum/enum-bounds-check.rs +++ b/tests/codegen/enum/enum-bounds-check.rs @@ -3,7 +3,8 @@ #![crate_type = "lib"] pub enum Foo { - A, B + A, + B, } // CHECK-LABEL: @lookup @@ -15,7 +16,7 @@ pub fn lookup(buf: &[u8; 2], f: Foo) -> u8 { pub enum Bar { A = 2, - B = 3 + B = 3, } // CHECK-LABEL: @lookup_unmodified diff --git a/tests/codegen/enum/enum-debug-clike.rs b/tests/codegen/enum/enum-debug-clike.rs index 59ad58784439..89c803cce5e7 100644 --- a/tests/codegen/enum/enum-debug-clike.rs +++ b/tests/codegen/enum/enum-debug-clike.rs @@ -17,7 +17,11 @@ #![allow(unused_variables)] #![allow(unused_assignments)] -enum E { A, B, C } +enum E { + A, + B, + C, +} pub fn main() { let e = E::C; diff --git a/tests/codegen/enum/enum-debug-niche.rs b/tests/codegen/enum/enum-debug-niche.rs index 90de928bced6..59e8b8a78b43 100644 --- a/tests/codegen/enum/enum-debug-niche.rs +++ b/tests/codegen/enum/enum-debug-niche.rs @@ -23,7 +23,12 @@ #![allow(unused_variables)] #![allow(unused_assignments)] -enum E { A, B, C, D(bool) } +enum E { + A, + B, + C, + D(bool), +} pub fn main() { let e = E::D(true); diff --git a/tests/codegen/enum/enum-debug-tagged.rs b/tests/codegen/enum/enum-debug-tagged.rs index f13922ee33b8..e8f147665b08 100644 --- a/tests/codegen/enum/enum-debug-tagged.rs +++ b/tests/codegen/enum/enum-debug-tagged.rs @@ -21,7 +21,10 @@ #![allow(unused_variables)] #![allow(unused_assignments)] -enum E { A(u32), B(u32) } +enum E { + A(u32), + B(u32), +} pub fn main() { let e = E::A(23); diff --git a/tests/codegen/enum/enum-match.rs b/tests/codegen/enum/enum-match.rs index ced26c0a4340..8da5de63e67d 100644 --- a/tests/codegen/enum/enum-match.rs +++ b/tests/codegen/enum/enum-match.rs @@ -50,6 +50,7 @@ pub fn match1(e: Enum1) -> u8 { } // Case 2: Special cases don't apply. +#[rustfmt::skip] pub enum X { _2=2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, diff --git a/tests/codegen/enum/unreachable_enum_default_branch.rs b/tests/codegen/enum/unreachable_enum_default_branch.rs index dae01cfb055e..81a258f27220 100644 --- a/tests/codegen/enum/unreachable_enum_default_branch.rs +++ b/tests/codegen/enum/unreachable_enum_default_branch.rs @@ -22,8 +22,7 @@ const C: Int = Int(153); // CHECK-NEXT: ret i1 [[SPEC_SELECT]] #[no_mangle] pub fn implicit_match(x: Int) -> bool { - (x >= A && x <= B) - || x == C + (x >= A && x <= B) || x == C } // The code is from https://github.com/rust-lang/rust/issues/110097. @@ -35,9 +34,5 @@ pub fn implicit_match(x: Int) -> bool { // CHECK-NEXT: ret #[no_mangle] pub fn if_let(val: Result) -> Result { - if let Ok(x) = val { - Ok(x) - } else { - Err(()) - } + if let Ok(x) = val { Ok(x) } else { Err(()) } } diff --git a/tests/codegen/fatptr.rs b/tests/codegen/fatptr.rs index 0f13e66fbad0..041807202b84 100644 --- a/tests/codegen/fatptr.rs +++ b/tests/codegen/fatptr.rs @@ -7,6 +7,6 @@ pub trait T {} // CHECK-LABEL: @copy_fat_ptr #[no_mangle] pub fn copy_fat_ptr(x: &T) { -// CHECK-NOT: extractvalue + // CHECK-NOT: extractvalue let x2 = x; } diff --git a/tests/codegen/float_math.rs b/tests/codegen/float_math.rs index dcca51c2f5eb..31387ec82b92 100644 --- a/tests/codegen/float_math.rs +++ b/tests/codegen/float_math.rs @@ -3,48 +3,40 @@ #![crate_type = "lib"] #![feature(core_intrinsics)] -use std::intrinsics::{fadd_fast, fsub_fast, fmul_fast, fdiv_fast, frem_fast}; +use std::intrinsics::{fadd_fast, fdiv_fast, fmul_fast, frem_fast, fsub_fast}; // CHECK-LABEL: @add #[no_mangle] pub fn add(x: f32, y: f32) -> f32 { -// CHECK: fadd float -// CHECK-NOT: fast + // CHECK: fadd float + // CHECK-NOT: fast x + y } // CHECK-LABEL: @addition #[no_mangle] pub fn addition(x: f32, y: f32) -> f32 { -// CHECK: fadd fast float - unsafe { - fadd_fast(x, y) - } + // CHECK: fadd fast float + unsafe { fadd_fast(x, y) } } // CHECK-LABEL: @subtraction #[no_mangle] pub fn subtraction(x: f32, y: f32) -> f32 { -// CHECK: fsub fast float - unsafe { - fsub_fast(x, y) - } + // CHECK: fsub fast float + unsafe { fsub_fast(x, y) } } // CHECK-LABEL: @multiplication #[no_mangle] pub fn multiplication(x: f32, y: f32) -> f32 { -// CHECK: fmul fast float - unsafe { - fmul_fast(x, y) - } + // CHECK: fmul fast float + unsafe { fmul_fast(x, y) } } // CHECK-LABEL: @division #[no_mangle] pub fn division(x: f32, y: f32) -> f32 { -// CHECK: fdiv fast float - unsafe { - fdiv_fast(x, y) - } + // CHECK: fdiv fast float + unsafe { fdiv_fast(x, y) } } diff --git a/tests/codegen/force-frame-pointers.rs b/tests/codegen/force-frame-pointers.rs index c41824e024fd..84e0bcb39add 100644 --- a/tests/codegen/force-frame-pointers.rs +++ b/tests/codegen/force-frame-pointers.rs @@ -1,6 +1,6 @@ //@ compile-flags: -C no-prepopulate-passes -C force-frame-pointers=y -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] // CHECK: attributes #{{.*}} "frame-pointer"="all" pub fn foo() {} diff --git a/tests/codegen/force-no-unwind-tables.rs b/tests/codegen/force-no-unwind-tables.rs index 0189ae7c0a68..e823bedac0f6 100644 --- a/tests/codegen/force-no-unwind-tables.rs +++ b/tests/codegen/force-no-unwind-tables.rs @@ -1,7 +1,7 @@ //@ compile-flags: -C no-prepopulate-passes -C panic=abort -C force-unwind-tables=n //@ ignore-windows -#![crate_type="lib"] +#![crate_type = "lib"] // CHECK-LABEL: define{{.*}}void @foo // CHECK-NOT: attributes #{{.*}} uwtable diff --git a/tests/codegen/force-unwind-tables.rs b/tests/codegen/force-unwind-tables.rs index 33fdf7653f49..a2ef8a104543 100644 --- a/tests/codegen/force-unwind-tables.rs +++ b/tests/codegen/force-unwind-tables.rs @@ -1,6 +1,6 @@ //@ compile-flags: -C no-prepopulate-passes -C force-unwind-tables=y -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] // CHECK: attributes #{{.*}} uwtable pub fn foo() {} diff --git a/tests/codegen/frame-pointer.rs b/tests/codegen/frame-pointer.rs index 879535bcc368..da81c2e9cd9a 100644 --- a/tests/codegen/frame-pointer.rs +++ b/tests/codegen/frame-pointer.rs @@ -13,13 +13,12 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} impl Copy for u32 {} - // CHECK: define i32 @peach{{.*}}[[PEACH_ATTRS:\#[0-9]+]] { #[no_mangle] pub fn peach(x: u32) -> u32 { diff --git a/tests/codegen/function-arguments-noopt.rs b/tests/codegen/function-arguments-noopt.rs index 0d42915893bc..c80f119696df 100644 --- a/tests/codegen/function-arguments-noopt.rs +++ b/tests/codegen/function-arguments-noopt.rs @@ -7,63 +7,63 @@ #![feature(rustc_attrs)] pub struct S { - _field: [i32; 8], + _field: [i32; 8], } // CHECK: zeroext i1 @boolean(i1 zeroext %x) #[no_mangle] pub fn boolean(x: bool) -> bool { - x + x } // CHECK-LABEL: @boolean_call #[no_mangle] pub fn boolean_call(x: bool, f: fn(bool) -> bool) -> bool { -// CHECK: call zeroext i1 %f(i1 zeroext %x) - f(x) + // CHECK: call zeroext i1 %f(i1 zeroext %x) + f(x) } // CHECK: align 4 ptr @borrow(ptr align 4 %x) #[no_mangle] pub fn borrow(x: &i32) -> &i32 { - x + x } // CHECK: align 4 ptr @borrow_mut(ptr align 4 %x) #[no_mangle] pub fn borrow_mut(x: &mut i32) -> &mut i32 { - x + x } // CHECK-LABEL: @borrow_call #[no_mangle] pub fn borrow_call(x: &i32, f: fn(&i32) -> &i32) -> &i32 { - // CHECK: call align 4 ptr %f(ptr align 4 %x) - f(x) + // CHECK: call align 4 ptr %f(ptr align 4 %x) + f(x) } // CHECK: void @struct_(ptr sret([32 x i8]) align 4{{( %_0)?}}, ptr align 4 %x) #[no_mangle] pub fn struct_(x: S) -> S { - x + x } // CHECK-LABEL: @struct_call #[no_mangle] pub fn struct_call(x: S, f: fn(S) -> S) -> S { - // CHECK: call void %f(ptr sret([32 x i8]) align 4{{( %_0)?}}, ptr align 4 %{{.+}}) - f(x) + // CHECK: call void %f(ptr sret([32 x i8]) align 4{{( %_0)?}}, ptr align 4 %{{.+}}) + f(x) } // CHECK: { i1, i8 } @enum_(i1 zeroext %x.0, i8 %x.1) #[no_mangle] pub fn enum_(x: Option) -> Option { - x + x } // CHECK-LABEL: @enum_call #[no_mangle] pub fn enum_call(x: Option, f: fn(Option) -> Option) -> Option { - // CHECK: call { i1, i8 } %f(i1 zeroext %x.0, i8 %x.1) - f(x) + // CHECK: call { i1, i8 } %f(i1 zeroext %x.0, i8 %x.1) + f(x) } diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs index ebcbcae8563c..56504df40347 100644 --- a/tests/codegen/function-arguments.rs +++ b/tests/codegen/function-arguments.rs @@ -3,129 +3,123 @@ #![feature(dyn_star)] #![feature(allocator_api)] +use std::marker::PhantomPinned; use std::mem::MaybeUninit; use std::num::NonZero; -use std::marker::PhantomPinned; use std::ptr::NonNull; pub struct S { - _field: [i32; 8], + _field: [i32; 8], } pub struct UnsafeInner { - _field: std::cell::UnsafeCell, + _field: std::cell::UnsafeCell, } pub struct NotUnpin { - _field: i32, - _marker: PhantomPinned, + _field: i32, + _marker: PhantomPinned, } pub enum MyBool { - True, - False, + True, + False, } // CHECK: noundef zeroext i1 @boolean(i1 noundef zeroext %x) #[no_mangle] pub fn boolean(x: bool) -> bool { - x + x } // CHECK: i8 @maybeuninit_boolean(i8 %x) #[no_mangle] pub fn maybeuninit_boolean(x: MaybeUninit) -> MaybeUninit { - x + x } // CHECK: noundef zeroext i1 @enum_bool(i1 noundef zeroext %x) #[no_mangle] pub fn enum_bool(x: MyBool) -> MyBool { - x + x } // CHECK: i8 @maybeuninit_enum_bool(i8 %x) #[no_mangle] pub fn maybeuninit_enum_bool(x: MaybeUninit) -> MaybeUninit { - x + x } // CHECK: noundef i32 @char(i32 noundef %x) #[no_mangle] pub fn char(x: char) -> char { - x + x } // CHECK: i32 @maybeuninit_char(i32 %x) #[no_mangle] pub fn maybeuninit_char(x: MaybeUninit) -> MaybeUninit { - x + x } // CHECK: noundef i64 @int(i64 noundef %x) #[no_mangle] pub fn int(x: u64) -> u64 { - x + x } // CHECK: noundef i64 @nonzero_int(i64 noundef %x) #[no_mangle] pub fn nonzero_int(x: NonZero) -> NonZero { - x + x } // CHECK: noundef i64 @option_nonzero_int(i64 noundef %x) #[no_mangle] pub fn option_nonzero_int(x: Option>) -> Option> { - x + x } // CHECK: @readonly_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1) // FIXME #25759 This should also have `nocapture` #[no_mangle] -pub fn readonly_borrow(_: &i32) { -} +pub fn readonly_borrow(_: &i32) {} // CHECK: noundef align 4 dereferenceable(4) ptr @readonly_borrow_ret() #[no_mangle] pub fn readonly_borrow_ret() -> &'static i32 { - loop {} + loop {} } // CHECK: @static_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1) // static borrow may be captured #[no_mangle] -pub fn static_borrow(_: &'static i32) { -} +pub fn static_borrow(_: &'static i32) {} // CHECK: @named_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1) // borrow with named lifetime may be captured #[no_mangle] -pub fn named_borrow<'r>(_: &'r i32) { -} +pub fn named_borrow<'r>(_: &'r i32) {} // CHECK: @unsafe_borrow(ptr noundef nonnull align 2 %_1) // unsafe interior means this isn't actually readonly and there may be aliases ... #[no_mangle] -pub fn unsafe_borrow(_: &UnsafeInner) { -} +pub fn unsafe_borrow(_: &UnsafeInner) {} // CHECK: @mutable_unsafe_borrow(ptr noalias noundef align 2 dereferenceable(2) %_1) // ... unless this is a mutable borrow, those never alias #[no_mangle] -pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) { -} +pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {} // CHECK: @mutable_borrow(ptr noalias noundef align 4 dereferenceable(4) %_1) // FIXME #25759 This should also have `nocapture` #[no_mangle] -pub fn mutable_borrow(_: &mut i32) { -} +pub fn mutable_borrow(_: &mut i32) {} // CHECK: noundef align 4 dereferenceable(4) ptr @mutable_borrow_ret() #[no_mangle] pub fn mutable_borrow_ret() -> &'static mut i32 { - loop {} + loop {} } #[no_mangle] @@ -133,53 +127,44 @@ pub fn mutable_borrow_ret() -> &'static mut i32 { // This one is *not* `noalias` because it might be self-referential. // It is also not `dereferenceable` due to // . -pub fn mutable_notunpin_borrow(_: &mut NotUnpin) { -} +pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {} // CHECK: @notunpin_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1) // But `&NotUnpin` behaves perfectly normal. #[no_mangle] -pub fn notunpin_borrow(_: &NotUnpin) { -} +pub fn notunpin_borrow(_: &NotUnpin) {} // CHECK: @indirect_struct(ptr noalias nocapture noundef readonly align 4 dereferenceable(32) %_1) #[no_mangle] -pub fn indirect_struct(_: S) { -} +pub fn indirect_struct(_: S) {} // CHECK: @borrowed_struct(ptr noalias noundef readonly align 4 dereferenceable(32) %_1) // FIXME #25759 This should also have `nocapture` #[no_mangle] -pub fn borrowed_struct(_: &S) { -} +pub fn borrowed_struct(_: &S) {} // CHECK: @option_borrow(ptr noalias noundef readonly align 4 dereferenceable_or_null(4) %x) #[no_mangle] -pub fn option_borrow(x: Option<&i32>) { -} +pub fn option_borrow(x: Option<&i32>) {} // CHECK: @option_borrow_mut(ptr noalias noundef align 4 dereferenceable_or_null(4) %x) #[no_mangle] -pub fn option_borrow_mut(x: Option<&mut i32>) { -} +pub fn option_borrow_mut(x: Option<&mut i32>) {} // CHECK: @raw_struct(ptr noundef %_1) #[no_mangle] -pub fn raw_struct(_: *const S) { -} +pub fn raw_struct(_: *const S) {} // CHECK: @raw_option_nonnull_struct(ptr noundef %_1) #[no_mangle] -pub fn raw_option_nonnull_struct(_: Option>) { -} - +pub fn raw_option_nonnull_struct(_: Option>) {} // `Box` can get deallocated during execution of the function, so it should // not get `dereferenceable`. // CHECK: noundef nonnull align 4 ptr @_box(ptr noalias noundef nonnull align 4 %x) #[no_mangle] pub fn _box(x: Box) -> Box { - x + x } // With a custom allocator, it should *not* have `noalias`. (See @@ -188,106 +173,93 @@ pub fn _box(x: Box) -> Box { // CHECK: @_box_custom(ptr noundef nonnull align 4 %x.0, ptr noalias noundef nonnull readonly align 1 %x.1) #[no_mangle] pub fn _box_custom(x: Box) { - drop(x) + drop(x) } // CHECK: noundef nonnull align 4 ptr @notunpin_box(ptr noundef nonnull align 4 %x) #[no_mangle] pub fn notunpin_box(x: Box) -> Box { - x + x } // CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias nocapture noundef{{( writable)?}} sret([32 x i8]) align 4 dereferenceable(32){{( %_0)?}}) #[no_mangle] pub fn struct_return() -> S { - S { - _field: [0, 0, 0, 0, 0, 0, 0, 0] - } + S { _field: [0, 0, 0, 0, 0, 0, 0, 0] } } // Hack to get the correct size for the length part in slices // CHECK: @helper([[USIZE:i[0-9]+]] noundef %_1) #[no_mangle] -pub fn helper(_: usize) { -} +pub fn helper(_: usize) {} // CHECK: @slice(ptr noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] -pub fn slice(_: &[u8]) { -} +pub fn slice(_: &[u8]) {} // CHECK: @mutable_slice(ptr noalias noundef nonnull align 1 %_1.0, [[USIZE]] noundef %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] -pub fn mutable_slice(_: &mut [u8]) { -} +pub fn mutable_slice(_: &mut [u8]) {} // CHECK: @unsafe_slice(ptr noundef nonnull align 2 %_1.0, [[USIZE]] noundef %_1.1) // unsafe interior means this isn't actually readonly and there may be aliases ... #[no_mangle] -pub fn unsafe_slice(_: &[UnsafeInner]) { -} +pub fn unsafe_slice(_: &[UnsafeInner]) {} // CHECK: @raw_slice(ptr noundef %_1.0, [[USIZE]] noundef %_1.1) #[no_mangle] -pub fn raw_slice(_: *const [u8]) { -} +pub fn raw_slice(_: *const [u8]) {} // CHECK: @str(ptr noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] -pub fn str(_: &[u8]) { -} +pub fn str(_: &[u8]) {} // CHECK: @trait_borrow(ptr noundef nonnull align 1 %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] -pub fn trait_borrow(_: &dyn Drop) { -} +pub fn trait_borrow(_: &dyn Drop) {} // CHECK: @option_trait_borrow(ptr noundef align 1 %x.0, ptr %x.1) #[no_mangle] -pub fn option_trait_borrow(x: Option<&dyn Drop>) { -} +pub fn option_trait_borrow(x: Option<&dyn Drop>) {} // CHECK: @option_trait_borrow_mut(ptr noundef align 1 %x.0, ptr %x.1) #[no_mangle] -pub fn option_trait_borrow_mut(x: Option<&mut dyn Drop>) { -} +pub fn option_trait_borrow_mut(x: Option<&mut dyn Drop>) {} // CHECK: @trait_raw(ptr noundef %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1) #[no_mangle] -pub fn trait_raw(_: *const dyn Drop) { -} +pub fn trait_raw(_: *const dyn Drop) {} // CHECK: @trait_box(ptr noalias noundef nonnull align 1{{( %0)?}}, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}){{( %1)?}}) #[no_mangle] -pub fn trait_box(_: Box) { -} +pub fn trait_box(_: Box) {} // CHECK: { ptr, ptr } @trait_option(ptr noalias noundef align 1 %x.0, ptr %x.1) #[no_mangle] pub fn trait_option(x: Option>) -> Option> { - x + x } // CHECK: { ptr, [[USIZE]] } @return_slice(ptr noalias noundef nonnull readonly align 2 %x.0, [[USIZE]] noundef %x.1) #[no_mangle] pub fn return_slice(x: &[u16]) -> &[u16] { - x + x } // CHECK: { i16, i16 } @enum_id_1(i16 noundef %x.0, i16 %x.1) #[no_mangle] pub fn enum_id_1(x: Option>) -> Option> { - x + x } // CHECK: { i1, i8 } @enum_id_2(i1 noundef zeroext %x.0, i8 %x.1) #[no_mangle] pub fn enum_id_2(x: Option) -> Option { - x + x } // CHECK: { ptr, {{.+}} } @dyn_star(ptr noundef %x.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %x.1) @@ -295,5 +267,5 @@ pub fn enum_id_2(x: Option) -> Option { // so do like the `trait_box` test and just match on `{{.+}}` for the vtable. #[no_mangle] pub fn dyn_star(x: dyn* Drop) -> dyn* Drop { - x + x } diff --git a/tests/codegen/generic-debug.rs b/tests/codegen/generic-debug.rs index 0f289026396f..3423abe7187b 100644 --- a/tests/codegen/generic-debug.rs +++ b/tests/codegen/generic-debug.rs @@ -13,6 +13,6 @@ pub struct Generic(Type); -fn main () { +fn main() { let generic = Generic(10); } diff --git a/tests/codegen/inline-always-works-always.rs b/tests/codegen/inline-always-works-always.rs index e9ca05d17569..07200fd9e373 100644 --- a/tests/codegen/inline-always-works-always.rs +++ b/tests/codegen/inline-always-works-always.rs @@ -3,7 +3,7 @@ //@[SIZE-OPT] compile-flags: -Copt-level=s //@[SPEED-OPT] compile-flags: -Copt-level=3 -#![crate_type="rlib"] +#![crate_type = "rlib"] #[no_mangle] #[inline(always)] diff --git a/tests/codegen/inline-debuginfo.rs b/tests/codegen/inline-debuginfo.rs index f327180560de..1e1c9037f5c9 100644 --- a/tests/codegen/inline-debuginfo.rs +++ b/tests/codegen/inline-debuginfo.rs @@ -1,4 +1,4 @@ -#![crate_type="rlib"] +#![crate_type = "rlib"] //@ compile-flags: -Copt-level=3 -g // diff --git a/tests/codegen/instrument-coverage/instrument-coverage.rs b/tests/codegen/instrument-coverage/instrument-coverage.rs index d638a544d5a5..65fa437d2506 100644 --- a/tests/codegen/instrument-coverage/instrument-coverage.rs +++ b/tests/codegen/instrument-coverage/instrument-coverage.rs @@ -12,12 +12,10 @@ // CHECK: @__llvm_profile_filename = {{.*}}"default_%m_%p.profraw\00"{{.*}} // CHECK: @__llvm_coverage_mapping -#![crate_type="lib"] +#![crate_type = "lib"] #[inline(never)] -fn some_function() { - -} +fn some_function() {} pub fn some_other_function() { some_function(); diff --git a/tests/codegen/integer-cmp.rs b/tests/codegen/integer-cmp.rs index 46972878da50..bba112b246f3 100644 --- a/tests/codegen/integer-cmp.rs +++ b/tests/codegen/integer-cmp.rs @@ -10,19 +10,19 @@ use std::cmp::Ordering; // CHECK-LABEL: @cmp_signed #[no_mangle] pub fn cmp_signed(a: i64, b: i64) -> Ordering { -// CHECK: icmp slt -// CHECK: icmp ne -// CHECK: zext i1 -// CHECK: select i1 + // CHECK: icmp slt + // CHECK: icmp ne + // CHECK: zext i1 + // CHECK: select i1 a.cmp(&b) } // CHECK-LABEL: @cmp_unsigned #[no_mangle] pub fn cmp_unsigned(a: u32, b: u32) -> Ordering { -// CHECK: icmp ult -// CHECK: icmp ne -// CHECK: zext i1 -// CHECK: select i1 + // CHECK: icmp ult + // CHECK: icmp ne + // CHECK: zext i1 + // CHECK: select i1 a.cmp(&b) } diff --git a/tests/codegen/integer-overflow.rs b/tests/codegen/integer-overflow.rs index 00780251bbc1..a6407476fc20 100644 --- a/tests/codegen/integer-overflow.rs +++ b/tests/codegen/integer-overflow.rs @@ -2,7 +2,6 @@ #![crate_type = "lib"] - pub struct S1<'a> { data: &'a [u8], position: usize, @@ -12,7 +11,7 @@ pub struct S1<'a> { #[no_mangle] pub fn slice_no_index_order<'a>(s: &'a mut S1, n: usize) -> &'a [u8] { // CHECK-NOT: slice_index_order_fail - let d = &s.data[s.position..s.position+n]; + let d = &s.data[s.position..s.position + n]; s.position += n; return d; } diff --git a/tests/codegen/internalize-closures.rs b/tests/codegen/internalize-closures.rs index d37aa5fee8da..f226ea6faac8 100644 --- a/tests/codegen/internalize-closures.rs +++ b/tests/codegen/internalize-closures.rs @@ -1,7 +1,6 @@ //@ compile-flags: -C no-prepopulate-passes -Zmir-opt-level=0 pub fn main() { - // We want to make sure that closures get 'internal' linkage instead of // 'weak_odr' when they are not shared between codegen units // FIXME(eddyb) `legacy` mangling uses `{{closure}}`, while `v0` @@ -9,6 +8,6 @@ pub fn main() { // CHECK-LABEL: ; internalize_closures::main::{{.*}}closure // CHECK-NEXT: ; Function Attrs: // CHECK-NEXT: define internal - let c = |x:i32| { x + 1 }; + let c = |x: i32| x + 1; let _ = c(1); } diff --git a/tests/codegen/intrinsic-no-unnamed-attr.rs b/tests/codegen/intrinsic-no-unnamed-attr.rs index 45d06c70a6d7..fce0de80d7b6 100644 --- a/tests/codegen/intrinsic-no-unnamed-attr.rs +++ b/tests/codegen/intrinsic-no-unnamed-attr.rs @@ -8,5 +8,7 @@ extern "rust-intrinsic" { // CHECK: @llvm.sqrt.f32(float) #{{[0-9]*}} fn main() { - unsafe { sqrtf32(0.0f32); } + unsafe { + sqrtf32(0.0f32); + } } diff --git a/tests/codegen/intrinsics/const_eval_select.rs b/tests/codegen/intrinsics/const_eval_select.rs index c8debe8d7113..baa985b00cd0 100644 --- a/tests/codegen/intrinsics/const_eval_select.rs +++ b/tests/codegen/intrinsics/const_eval_select.rs @@ -6,10 +6,14 @@ use std::intrinsics::const_eval_select; -const fn foo(_: i32) -> i32 { 1 } +const fn foo(_: i32) -> i32 { + 1 +} #[no_mangle] -pub fn hi(n: i32) -> i32 { n } +pub fn hi(n: i32) -> i32 { + n +} #[no_mangle] pub unsafe fn hey() { diff --git a/tests/codegen/intrinsics/likely.rs b/tests/codegen/intrinsics/likely.rs index c5904085fc08..098fd9936ce1 100644 --- a/tests/codegen/intrinsics/likely.rs +++ b/tests/codegen/intrinsics/likely.rs @@ -3,17 +3,13 @@ #![crate_type = "lib"] #![feature(core_intrinsics)] -use std::intrinsics::{likely,unlikely}; +use std::intrinsics::{likely, unlikely}; #[no_mangle] pub fn check_likely(x: i32, y: i32) -> Option { unsafe { // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 true) - if likely(x == y) { - None - } else { - Some(x + y) - } + if likely(x == y) { None } else { Some(x + y) } } } @@ -21,10 +17,6 @@ pub fn check_likely(x: i32, y: i32) -> Option { pub fn check_unlikely(x: i32, y: i32) -> Option { unsafe { // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 false) - if unlikely(x == y) { - None - } else { - Some(x + y) - } + if unlikely(x == y) { None } else { Some(x + y) } } } diff --git a/tests/codegen/intrinsics/prefetch.rs b/tests/codegen/intrinsics/prefetch.rs index edd8c20b38f1..3f9f21c85cbf 100644 --- a/tests/codegen/intrinsics/prefetch.rs +++ b/tests/codegen/intrinsics/prefetch.rs @@ -3,8 +3,9 @@ #![crate_type = "lib"] #![feature(core_intrinsics)] -use std::intrinsics::{prefetch_read_data, prefetch_write_data, - prefetch_read_instruction, prefetch_write_instruction}; +use std::intrinsics::{ + prefetch_read_data, prefetch_read_instruction, prefetch_write_data, prefetch_write_instruction, +}; #[no_mangle] pub fn check_prefetch_read_data(data: &[i8]) { diff --git a/tests/codegen/is_val_statically_known.rs b/tests/codegen/is_val_statically_known.rs index 255d8950a974..6af4f353a481 100644 --- a/tests/codegen/is_val_statically_known.rs +++ b/tests/codegen/is_val_statically_known.rs @@ -75,7 +75,7 @@ pub fn _slice_ref(a: &[u8]) -> i32 { #[no_mangle] pub fn _slice_ref_borrow() -> i32 { // CHECK: ret i32 6 - _slice_ref(&[0;3]) + _slice_ref(&[0; 3]) } // CHECK-LABEL: @_slice_ref_arg( diff --git a/tests/codegen/issue-97217.rs b/tests/codegen/issue-97217.rs index a0dfff2ef2eb..ecf1fa1ddb3e 100644 --- a/tests/codegen/issue-97217.rs +++ b/tests/codegen/issue-97217.rs @@ -16,6 +16,6 @@ pub fn issue97217() -> i32 { let v1 = vec![5, 6, 7]; let v1_iter = v1.iter(); let total: i32 = v1_iter.sum(); - println!("{}",total); + println!("{}", total); total } diff --git a/tests/codegen/issues/issue-103327.rs b/tests/codegen/issues/issue-103327.rs index 398b1f376b78..f8cf273e4a6c 100644 --- a/tests/codegen/issues/issue-103327.rs +++ b/tests/codegen/issues/issue-103327.rs @@ -9,9 +9,5 @@ pub fn test(a: i32, b: i32) -> bool { let c1 = (a >= 0) && (a <= 10); let c2 = (b >= 0) && (b <= 20); - if c1 & c2 { - a + 100 != b - } else { - true - } + if c1 & c2 { a + 100 != b } else { true } } diff --git a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs index 56b4330b1a6c..db9eeda19a6c 100644 --- a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs +++ b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs @@ -6,7 +6,8 @@ pub struct S([usize; 8]); #[no_mangle] pub fn outer_function(x: S, y: S) -> usize { - (#[inline(always)]|| { + (#[inline(always)] + || { let _z = x; y.0[0] })() diff --git a/tests/codegen/issues/issue-119422.rs b/tests/codegen/issues/issue-119422.rs index aa56bfe79acb..682430a79f4a 100644 --- a/tests/codegen/issues/issue-119422.rs +++ b/tests/codegen/issues/issue-119422.rs @@ -5,8 +5,8 @@ //@ only-64bit (because the LLVM type of i64 for usize shows up) #![crate_type = "lib"] -use core::ptr::NonNull; use core::num::NonZero; +use core::ptr::NonNull; // CHECK-LABEL: @check_non_null #[no_mangle] @@ -73,7 +73,7 @@ pub fn isize_try_from_i32(x: NonZero) -> NonZero { // CHECK-LABEL: @u64_from_nonzero_is_not_zero #[no_mangle] -pub fn u64_from_nonzero_is_not_zero(x: NonZero)->bool { +pub fn u64_from_nonzero_is_not_zero(x: NonZero) -> bool { // CHECK-NOT: br // CHECK: ret i1 false // CHECK-NOT: br diff --git a/tests/codegen/issues/issue-13018.rs b/tests/codegen/issues/issue-13018.rs index d0a8ce159118..66282dc42749 100644 --- a/tests/codegen/issues/issue-13018.rs +++ b/tests/codegen/issues/issue-13018.rs @@ -6,6 +6,6 @@ use std::rc::Rc; pub fn foo(t: &Rc>) { -// CHECK-NOT: __rust_dealloc + // CHECK-NOT: __rust_dealloc drop(t.clone()); } diff --git a/tests/codegen/issues/issue-32364.rs b/tests/codegen/issues/issue-32364.rs index 50006e3f2181..016981d1947a 100644 --- a/tests/codegen/issues/issue-32364.rs +++ b/tests/codegen/issues/issue-32364.rs @@ -7,10 +7,9 @@ struct Foo; impl Foo { -// CHECK: define internal x86_stdcallcc void @{{.*}}foo{{.*}}() + // CHECK: define internal x86_stdcallcc void @{{.*}}foo{{.*}}() #[inline(never)] - pub extern "stdcall" fn foo() { - } + pub extern "stdcall" fn foo() {} } fn main() { diff --git a/tests/codegen/issues/issue-37945.rs b/tests/codegen/issues/issue-37945.rs index 756a75e2f0ed..01d1c694ec7c 100644 --- a/tests/codegen/issues/issue-37945.rs +++ b/tests/codegen/issues/issue-37945.rs @@ -9,26 +9,26 @@ use std::slice::Iter; #[no_mangle] pub fn is_empty_1(xs: Iter) -> bool { -// CHECK-LABEL: @is_empty_1( -// CHECK-NEXT: start: -// CHECK-NEXT: [[A:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null -// CHECK-NEXT: tail call void @llvm.assume(i1 [[A]]) -// The order between %xs.0 and %xs.1 on the next line doesn't matter -// and different LLVM versions produce different order. -// CHECK-NEXT: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}} -// CHECK-NEXT: ret i1 [[B:%.*]] - {xs}.next().is_none() + // CHECK-LABEL: @is_empty_1( + // CHECK-NEXT: start: + // CHECK-NEXT: [[A:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null + // CHECK-NEXT: tail call void @llvm.assume(i1 [[A]]) + // The order between %xs.0 and %xs.1 on the next line doesn't matter + // and different LLVM versions produce different order. + // CHECK-NEXT: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}} + // CHECK-NEXT: ret i1 [[B:%.*]] + { xs }.next().is_none() } #[no_mangle] pub fn is_empty_2(xs: Iter) -> bool { -// CHECK-LABEL: @is_empty_2 -// CHECK-NEXT: start: -// CHECK-NEXT: [[C:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null -// CHECK-NEXT: tail call void @llvm.assume(i1 [[C]]) -// The order between %xs.0 and %xs.1 on the next line doesn't matter -// and different LLVM versions produce different order. -// CHECK-NEXT: [[D:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}} -// CHECK-NEXT: ret i1 [[D:%.*]] + // CHECK-LABEL: @is_empty_2 + // CHECK-NEXT: start: + // CHECK-NEXT: [[C:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null + // CHECK-NEXT: tail call void @llvm.assume(i1 [[C]]) + // The order between %xs.0 and %xs.1 on the next line doesn't matter + // and different LLVM versions produce different order. + // CHECK-NEXT: [[D:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}} + // CHECK-NEXT: ret i1 [[D:%.*]] xs.map(|&x| x).next().is_none() } diff --git a/tests/codegen/issues/issue-45466.rs b/tests/codegen/issues/issue-45466.rs index fc714247dfb6..8a324fa555bb 100644 --- a/tests/codegen/issues/issue-45466.rs +++ b/tests/codegen/issues/issue-45466.rs @@ -1,6 +1,6 @@ //@ compile-flags: -O -#![crate_type="rlib"] +#![crate_type = "rlib"] // CHECK-LABEL: @memzero // CHECK-NOT: store diff --git a/tests/codegen/issues/issue-45964-bounds-check-slice-pos.rs b/tests/codegen/issues/issue-45964-bounds-check-slice-pos.rs index b7568bea4d0a..ea9288564e9d 100644 --- a/tests/codegen/issues/issue-45964-bounds-check-slice-pos.rs +++ b/tests/codegen/issues/issue-45964-bounds-check-slice-pos.rs @@ -3,7 +3,7 @@ //@ compile-flags: -O -#![crate_type="rlib"] +#![crate_type = "rlib"] // CHECK-LABEL: @test #[no_mangle] diff --git a/tests/codegen/issues/issue-47278.rs b/tests/codegen/issues/issue-47278.rs index 9076274f45e9..4f0a5bdf36f4 100644 --- a/tests/codegen/issues/issue-47278.rs +++ b/tests/codegen/issues/issue-47278.rs @@ -1,9 +1,11 @@ // -C no-prepopulate-passes -#![crate_type="staticlib"] +#![crate_type = "staticlib"] #[repr(C)] pub struct Foo(u64); // CHECK: define {{.*}} @foo( #[no_mangle] -pub extern "C" fn foo(_: Foo) -> Foo { loop {} } +pub extern "C" fn foo(_: Foo) -> Foo { + loop {} +} diff --git a/tests/codegen/issues/issue-47442.rs b/tests/codegen/issues/issue-47442.rs index 6944336d3356..445234e55add 100644 --- a/tests/codegen/issues/issue-47442.rs +++ b/tests/codegen/issues/issue-47442.rs @@ -4,7 +4,7 @@ // CHECK-NOT: Unwind #![feature(test)] -#![crate_type="rlib"] +#![crate_type = "rlib"] extern crate test; diff --git a/tests/codegen/issues/issue-56267-2.rs b/tests/codegen/issues/issue-56267-2.rs index ced0d2d63bb5..98e3732777e3 100644 --- a/tests/codegen/issues/issue-56267-2.rs +++ b/tests/codegen/issues/issue-56267-2.rs @@ -1,6 +1,6 @@ //@ compile-flags: -C no-prepopulate-passes -#![crate_type="rlib"] +#![crate_type = "rlib"] #[allow(dead_code)] pub struct Foo { diff --git a/tests/codegen/issues/issue-56267.rs b/tests/codegen/issues/issue-56267.rs index fc3754f2d990..cabcc298482d 100644 --- a/tests/codegen/issues/issue-56267.rs +++ b/tests/codegen/issues/issue-56267.rs @@ -1,6 +1,6 @@ //@ compile-flags: -C no-prepopulate-passes -#![crate_type="rlib"] +#![crate_type = "rlib"] #[allow(dead_code)] pub struct Foo { diff --git a/tests/codegen/issues/issue-56927.rs b/tests/codegen/issues/issue-56927.rs index e4a0a1791418..a40718689b3e 100644 --- a/tests/codegen/issues/issue-56927.rs +++ b/tests/codegen/issues/issue-56927.rs @@ -1,6 +1,6 @@ //@ compile-flags: -C no-prepopulate-passes -#![crate_type="rlib"] +#![crate_type = "rlib"] #[repr(align(16))] pub struct S { diff --git a/tests/codegen/issues/issue-73031.rs b/tests/codegen/issues/issue-73031.rs index 61a269999e90..db9c6d6db233 100644 --- a/tests/codegen/issues/issue-73031.rs +++ b/tests/codegen/issues/issue-73031.rs @@ -12,11 +12,7 @@ pub enum All { // CHECK-LABEL: @issue_73031 #[no_mangle] pub fn issue_73031(a: &mut All, q: i32) -> i32 { - *a = if q == 5 { - All::Foo - } else { - All::Bar - }; + *a = if q == 5 { All::Foo } else { All::Bar }; match *a { // CHECK-NOT: panic All::None => panic!(), diff --git a/tests/codegen/issues/issue-73258.rs b/tests/codegen/issues/issue-73258.rs index 48f14fe2dfe3..e5c622b5656b 100644 --- a/tests/codegen/issues/issue-73258.rs +++ b/tests/codegen/issues/issue-73258.rs @@ -7,7 +7,10 @@ #[derive(Clone, Copy)] #[repr(u8)] pub enum Foo { - A, B, C, D, + A, + B, + C, + D, } // CHECK-LABEL: @issue_73258( diff --git a/tests/codegen/issues/issue-73338-effecient-cmp.rs b/tests/codegen/issues/issue-73338-effecient-cmp.rs index a64eb56f9030..71641a5457b1 100644 --- a/tests/codegen/issues/issue-73338-effecient-cmp.rs +++ b/tests/codegen/issues/issue-73338-effecient-cmp.rs @@ -4,7 +4,7 @@ //@ compile-flags: -Copt-level=3 -#![crate_type="lib"] +#![crate_type = "lib"] #[repr(u32)] #[derive(Copy, Clone, Eq, PartialEq, PartialOrd)] @@ -15,25 +15,25 @@ pub enum Foo { } #[no_mangle] -pub fn compare_less(a: Foo, b: Foo)->bool{ +pub fn compare_less(a: Foo, b: Foo) -> bool { // CHECK-NOT: br {{.*}} a < b } #[no_mangle] -pub fn compare_le(a: Foo, b: Foo)->bool{ +pub fn compare_le(a: Foo, b: Foo) -> bool { // CHECK-NOT: br {{.*}} a <= b } #[no_mangle] -pub fn compare_ge(a: Foo, b: Foo)->bool{ +pub fn compare_ge(a: Foo, b: Foo) -> bool { // CHECK-NOT: br {{.*}} a >= b } #[no_mangle] -pub fn compare_greater(a: Foo, b: Foo)->bool{ +pub fn compare_greater(a: Foo, b: Foo) -> bool { // CHECK-NOT: br {{.*}} a > b } diff --git a/tests/codegen/issues/issue-73396-bounds-check-after-position.rs b/tests/codegen/issues/issue-73396-bounds-check-after-position.rs index ef4538ac84e1..9b3b1318ced1 100644 --- a/tests/codegen/issues/issue-73396-bounds-check-after-position.rs +++ b/tests/codegen/issues/issue-73396-bounds-check-after-position.rs @@ -12,11 +12,7 @@ pub fn position_slice_to_no_bounds_check(s: &[u8]) -> &[u8] { // CHECK-NOT: slice_end_index_len_fail // CHECK-NOT: panic_bounds_check // CHECK-NOT: unreachable - if let Some(idx) = s.iter().position(|b| *b == b'\\') { - &s[..idx] - } else { - s - } + if let Some(idx) = s.iter().position(|b| *b == b'\\') { &s[..idx] } else { s } } // CHECK-LABEL: @position_slice_from_no_bounds_check @@ -27,11 +23,7 @@ pub fn position_slice_from_no_bounds_check(s: &[u8]) -> &[u8] { // CHECK-NOT: slice_end_index_len_fail // CHECK-NOT: panic_bounds_check // CHECK-NOT: unreachable - if let Some(idx) = s.iter().position(|b| *b == b'\\') { - &s[idx..] - } else { - s - } + if let Some(idx) = s.iter().position(|b| *b == b'\\') { &s[idx..] } else { s } } // CHECK-LABEL: @position_index_no_bounds_check @@ -42,11 +34,7 @@ pub fn position_index_no_bounds_check(s: &[u8]) -> u8 { // CHECK-NOT: slice_end_index_len_fail // CHECK-NOT: panic_bounds_check // CHECK-NOT: unreachable - if let Some(idx) = s.iter().position(|b| *b == b'\\') { - s[idx] - } else { - 42 - } + if let Some(idx) = s.iter().position(|b| *b == b'\\') { s[idx] } else { 42 } } // CHECK-LABEL: @rposition_slice_to_no_bounds_check #[no_mangle] @@ -56,11 +44,7 @@ pub fn rposition_slice_to_no_bounds_check(s: &[u8]) -> &[u8] { // CHECK-NOT: slice_end_index_len_fail // CHECK-NOT: panic_bounds_check // CHECK-NOT: unreachable - if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { - &s[..idx] - } else { - s - } + if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { &s[..idx] } else { s } } // CHECK-LABEL: @rposition_slice_from_no_bounds_check @@ -71,11 +55,7 @@ pub fn rposition_slice_from_no_bounds_check(s: &[u8]) -> &[u8] { // CHECK-NOT: slice_end_index_len_fail // CHECK-NOT: panic_bounds_check // CHECK-NOT: unreachable - if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { - &s[idx..] - } else { - s - } + if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { &s[idx..] } else { s } } // CHECK-LABEL: @rposition_index_no_bounds_check @@ -86,9 +66,5 @@ pub fn rposition_index_no_bounds_check(s: &[u8]) -> u8 { // CHECK-NOT: slice_end_index_len_fail // CHECK-NOT: panic_bounds_check // CHECK-NOT: unreachable - if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { - s[idx] - } else { - 42 - } + if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { s[idx] } else { 42 } } diff --git a/tests/codegen/issues/issue-75546.rs b/tests/codegen/issues/issue-75546.rs index 992ef97d6242..1132c8ab5093 100644 --- a/tests/codegen/issues/issue-75546.rs +++ b/tests/codegen/issues/issue-75546.rs @@ -9,7 +9,9 @@ pub fn issue_75546() { let mut i = 1u32; while i < u32::MAX { // CHECK-NOT: panic - if i == 0 { panic!(); } + if i == 0 { + panic!(); + } i += 1; } } diff --git a/tests/codegen/issues/issue-77812.rs b/tests/codegen/issues/issue-77812.rs index b9ce0a4f7db2..bf84ac21b16d 100644 --- a/tests/codegen/issues/issue-77812.rs +++ b/tests/codegen/issues/issue-77812.rs @@ -10,7 +10,7 @@ pub enum Variant { Two, } -extern { +extern "C" { fn exf1(); fn exf2(); } diff --git a/tests/codegen/issues/issue-84268.rs b/tests/codegen/issues/issue-84268.rs index 1e3950609b33..5e852133ed3d 100644 --- a/tests/codegen/issues/issue-84268.rs +++ b/tests/codegen/issues/issue-84268.rs @@ -17,7 +17,5 @@ pub struct M([i32; 4]); pub fn is_infinite(v: V) -> M { // CHECK: fabs // CHECK: cmp oeq - unsafe { - simd_eq(simd_fabs(v), V([f32::INFINITY; 4])) - } + unsafe { simd_eq(simd_fabs(v), V([f32::INFINITY; 4])) } } diff --git a/tests/codegen/issues/issue-96497-slice-size-nowrap.rs b/tests/codegen/issues/issue-96497-slice-size-nowrap.rs index c2b262b3334c..f922462cc279 100644 --- a/tests/codegen/issues/issue-96497-slice-size-nowrap.rs +++ b/tests/codegen/issues/issue-96497-slice-size-nowrap.rs @@ -4,7 +4,7 @@ //@ compile-flags: -O -#![crate_type="lib"] +#![crate_type = "lib"] // CHECK-LABEL: @simple_size_of_nowrap #[no_mangle] diff --git a/tests/codegen/issues/issue-99960.rs b/tests/codegen/issues/issue-99960.rs index 075495061750..9029121d35f4 100644 --- a/tests/codegen/issues/issue-99960.rs +++ b/tests/codegen/issues/issue-99960.rs @@ -6,9 +6,5 @@ pub fn test(dividend: i64, divisor: i64) -> Option { // CHECK-LABEL: @test( // CHECK-NOT: panic - if dividend > i64::min_value() && divisor != 0 { - Some(dividend / divisor) - } else { - None - } + if dividend > i64::min_value() && divisor != 0 { Some(dividend / divisor) } else { None } } diff --git a/tests/codegen/lib-optimizations/iter-sum.rs b/tests/codegen/lib-optimizations/iter-sum.rs index b563a6debb52..ea8c916bfc1b 100644 --- a/tests/codegen/lib-optimizations/iter-sum.rs +++ b/tests/codegen/lib-optimizations/iter-sum.rs @@ -2,7 +2,6 @@ //@ only-x86_64 (vectorization varies between architectures) #![crate_type = "lib"] - // Ensure that slice + take + sum gets vectorized. // Currently this relies on the slice::Iter::try_fold implementation // CHECK-LABEL: @slice_take_sum diff --git a/tests/codegen/lifetime_start_end.rs b/tests/codegen/lifetime_start_end.rs index 38e878451588..99d37c25dcac 100644 --- a/tests/codegen/lifetime_start_end.rs +++ b/tests/codegen/lifetime_start_end.rs @@ -8,27 +8,27 @@ pub fn test() { let a = 0u8; &a; // keep variable in an alloca -// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, ptr %a) + // CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, ptr %a) { let b = &Some(a); &b; // keep variable in an alloca -// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, {{.*}}) + // CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, {{.*}}) -// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, {{.*}}) + // CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, {{.*}}) -// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, {{.*}}) + // CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, {{.*}}) -// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, {{.*}}) + // CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, {{.*}}) } let c = 1u8; &c; // keep variable in an alloca -// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, ptr %c) + // CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, ptr %c) -// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, ptr %c) + // CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, ptr %c) -// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, ptr %a) + // CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, ptr %a) } diff --git a/tests/codegen/link-dead-code.rs b/tests/codegen/link-dead-code.rs index 7769622233f6..93e1d84d9c70 100644 --- a/tests/codegen/link-dead-code.rs +++ b/tests/codegen/link-dead-code.rs @@ -8,15 +8,21 @@ // CHECK-LABEL: ; link_dead_code::const_fn // CHECK-NEXT: ; Function Attrs: // CHECK-NEXT: define hidden -const fn const_fn() -> i32 { 1 } +const fn const_fn() -> i32 { + 1 +} // CHECK-LABEL: ; link_dead_code::inline_fn // CHECK-NEXT: ; Function Attrs: // CHECK-NEXT: define hidden #[inline] -fn inline_fn() -> i32 { 2 } +fn inline_fn() -> i32 { + 2 +} // CHECK-LABEL: ; link_dead_code::private_fn // CHECK-NEXT: ; Function Attrs: // CHECK-NEXT: define hidden -fn private_fn() -> i32 { 3 } +fn private_fn() -> i32 { + 3 +} diff --git a/tests/codegen/link_section.rs b/tests/codegen/link_section.rs index 281d3fb99d46..196f5edb7d63 100644 --- a/tests/codegen/link_section.rs +++ b/tests/codegen/link_section.rs @@ -16,7 +16,7 @@ pub static VAR1: u32 = 0x01000000; pub enum E { A(u32), - B(f32) + B(f32), } // CHECK: @VAR2 = {{(dso_local )?}}constant {{.*}}, section ".test_two" diff --git a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs index d978f2d25254..cba1a980caa7 100644 --- a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs +++ b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs @@ -6,9 +6,12 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} // CHECK: define void @f_fpr_tracking(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, i8 noundef zeroext %i) #[no_mangle] diff --git a/tests/codegen/lto-removes-invokes.rs b/tests/codegen/lto-removes-invokes.rs index f0102c25d5bd..3217c239bf78 100644 --- a/tests/codegen/lto-removes-invokes.rs +++ b/tests/codegen/lto-removes-invokes.rs @@ -10,8 +10,8 @@ fn main() { fn foo() { let _a = Box::new(3); bar(); -// CHECK-LABEL: define dso_local void @foo -// CHECK: call void @bar + // CHECK-LABEL: define dso_local void @foo + // CHECK: call void @bar } #[inline(never)] diff --git a/tests/codegen/macos/i686-macosx-deployment-target.rs b/tests/codegen/macos/i686-macosx-deployment-target.rs index b854476de418..389434da1f67 100644 --- a/tests/codegen/macos/i686-macosx-deployment-target.rs +++ b/tests/codegen/macos/i686-macosx-deployment-target.rs @@ -8,12 +8,12 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="freeze"] -trait Freeze { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} #[repr(C)] pub struct Bool { diff --git a/tests/codegen/macos/i686-no-macosx-deployment-target.rs b/tests/codegen/macos/i686-no-macosx-deployment-target.rs index a49a3467e7a0..4c6b7656e593 100644 --- a/tests/codegen/macos/i686-no-macosx-deployment-target.rs +++ b/tests/codegen/macos/i686-no-macosx-deployment-target.rs @@ -8,12 +8,12 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="freeze"] -trait Freeze { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} #[repr(C)] pub struct Bool { diff --git a/tests/codegen/macos/x86_64-macosx-deployment-target.rs b/tests/codegen/macos/x86_64-macosx-deployment-target.rs index eac989c29541..a40deca24bbe 100644 --- a/tests/codegen/macos/x86_64-macosx-deployment-target.rs +++ b/tests/codegen/macos/x86_64-macosx-deployment-target.rs @@ -8,12 +8,12 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="freeze"] -trait Freeze { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} #[repr(C)] pub struct Bool { diff --git a/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs b/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs index ed294cf4e3dc..26d519ef1a6d 100644 --- a/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs +++ b/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs @@ -8,12 +8,12 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="freeze"] -trait Freeze { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} #[repr(C)] pub struct Bool { diff --git a/tests/codegen/match-optimized.rs b/tests/codegen/match-optimized.rs index 5cecafb9f29c..d6893be0b7be 100644 --- a/tests/codegen/match-optimized.rs +++ b/tests/codegen/match-optimized.rs @@ -11,23 +11,23 @@ pub enum E { // CHECK-LABEL: @exhaustive_match #[no_mangle] pub fn exhaustive_match(e: E) -> u8 { -// CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [ -// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]] -// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]] -// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[C:[a-zA-Z0-9_]+]] -// CHECK-NEXT: ] -// CHECK: [[OTHERWISE]]: -// CHECK-NEXT: unreachable -// -// CHECK: [[A]]: -// CHECK-NEXT: store i8 0, ptr %_0, align 1 -// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]] -// CHECK: [[B]]: -// CHECK-NEXT: store i8 1, ptr %_0, align 1 -// CHECK-NEXT: br label %[[EXIT]] -// CHECK: [[C]]: -// CHECK-NEXT: store i8 3, ptr %_0, align 1 -// CHECK-NEXT: br label %[[EXIT]] + // CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [ + // CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]] + // CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]] + // CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[C:[a-zA-Z0-9_]+]] + // CHECK-NEXT: ] + // CHECK: [[OTHERWISE]]: + // CHECK-NEXT: unreachable + // + // CHECK: [[A]]: + // CHECK-NEXT: store i8 0, ptr %_0, align 1 + // CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]] + // CHECK: [[B]]: + // CHECK-NEXT: store i8 1, ptr %_0, align 1 + // CHECK-NEXT: br label %[[EXIT]] + // CHECK: [[C]]: + // CHECK-NEXT: store i8 3, ptr %_0, align 1 + // CHECK-NEXT: br label %[[EXIT]] match e { E::A => 0, E::B => 1, diff --git a/tests/codegen/match-optimizes-away.rs b/tests/codegen/match-optimizes-away.rs index 55ece89cec21..82ab5718b375 100644 --- a/tests/codegen/match-optimizes-away.rs +++ b/tests/codegen/match-optimizes-away.rs @@ -1,11 +1,20 @@ // //@ compile-flags: -O -#![crate_type="lib"] +#![crate_type = "lib"] -pub enum Three { A, B, C } +pub enum Three { + A, + B, + C, +} #[repr(u16)] -pub enum Four { A, B, C, D } +pub enum Four { + A, + B, + C, + D, +} #[no_mangle] pub fn three_valued(x: Three) -> Three { diff --git a/tests/codegen/mir_zst_stores.rs b/tests/codegen/mir_zst_stores.rs index 667273c2f0f7..ff1d429cffdb 100644 --- a/tests/codegen/mir_zst_stores.rs +++ b/tests/codegen/mir_zst_stores.rs @@ -4,7 +4,9 @@ use std::marker::PhantomData; #[derive(Copy, Clone)] -struct Zst { phantom: PhantomData } +struct Zst { + phantom: PhantomData, +} // CHECK-LABEL: @mir // CHECK-NOT: store{{.*}}undef diff --git a/tests/codegen/naked-fn/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs index 3c426825537b..307745a921cf 100644 --- a/tests/codegen/naked-fn/naked-functions.rs +++ b/tests/codegen/naked-fn/naked-functions.rs @@ -14,8 +14,7 @@ pub unsafe extern "C" fn naked_empty() { // CHECK-NEXT: {{.+}}: // CHECK-NEXT: call void asm // CHECK-NEXT: unreachable - asm!("ret", - options(noreturn)); + asm!("ret", options(noreturn)); } // CHECK: Function Attrs: naked @@ -26,7 +25,5 @@ pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize // CHECK-NEXT: {{.+}}: // CHECK-NEXT: call void asm // CHECK-NEXT: unreachable - asm!("lea rax, [rdi + rsi]", - "ret", - options(noreturn)); + asm!("lea rax, [rdi + rsi]", "ret", options(noreturn)); } diff --git a/tests/codegen/no-assumes-on-casts.rs b/tests/codegen/no-assumes-on-casts.rs index b9c264daa2d1..9c00dc2c0155 100644 --- a/tests/codegen/no-assumes-on-casts.rs +++ b/tests/codegen/no-assumes-on-casts.rs @@ -6,14 +6,14 @@ #[no_mangle] pub fn fna(a: i16) -> i32 { a as i32 -// CHECK-NOT: assume -// CHECK: sext + // CHECK-NOT: assume + // CHECK: sext } // CHECK-LABEL: fnb #[no_mangle] pub fn fnb(a: u16) -> u32 { a as u32 -// CHECK-NOT: assume -// CHECK: zext + // CHECK-NOT: assume + // CHECK: zext } diff --git a/tests/codegen/noalias-freeze.rs b/tests/codegen/noalias-freeze.rs index 8086f3afbbc8..32c840140260 100644 --- a/tests/codegen/noalias-freeze.rs +++ b/tests/codegen/noalias-freeze.rs @@ -8,7 +8,9 @@ #![crate_type = "lib"] -fn project(x: &(T,)) -> &T { &x.0 } +fn project(x: &(T,)) -> &T { + &x.0 +} fn dummy() {} diff --git a/tests/codegen/noalias-unpin.rs b/tests/codegen/noalias-unpin.rs index 546b1edb7b61..630a62020c11 100644 --- a/tests/codegen/noalias-unpin.rs +++ b/tests/codegen/noalias-unpin.rs @@ -4,7 +4,7 @@ pub struct SelfRef { self_ref: *mut SelfRef, - _pin: std::marker::PhantomPinned + _pin: std::marker::PhantomPinned, } // CHECK-LABEL: @test_self_ref( diff --git a/tests/codegen/non-terminate/infinite-recursion.rs b/tests/codegen/non-terminate/infinite-recursion.rs index 804704c0292e..19123639896b 100644 --- a/tests/codegen/non-terminate/infinite-recursion.rs +++ b/tests/codegen/non-terminate/infinite-recursion.rs @@ -1,7 +1,6 @@ //@ compile-flags: -C opt-level=3 #![crate_type = "lib"] - #![allow(unconditional_recursion)] // CHECK-LABEL: @infinite_recursion diff --git a/tests/codegen/noreturnflag.rs b/tests/codegen/noreturnflag.rs index a8f08628986a..d9bb30b2703a 100644 --- a/tests/codegen/noreturnflag.rs +++ b/tests/codegen/noreturnflag.rs @@ -4,7 +4,7 @@ #[no_mangle] pub fn foo() -> ! { -// CHECK: @foo() unnamed_addr #0 + // CHECK: @foo() unnamed_addr #0 loop {} } @@ -12,7 +12,7 @@ pub enum EmptyEnum {} #[no_mangle] pub fn bar() -> EmptyEnum { -// CHECK: @bar() unnamed_addr #0 + // CHECK: @bar() unnamed_addr #0 loop {} } diff --git a/tests/codegen/nounwind.rs b/tests/codegen/nounwind.rs index 2b237ef01208..464bc2535c2b 100644 --- a/tests/codegen/nounwind.rs +++ b/tests/codegen/nounwind.rs @@ -10,7 +10,7 @@ extern crate nounwind; #[no_mangle] pub fn foo() { nounwind::bar(); -// CHECK: @foo() unnamed_addr #0 -// CHECK: @bar() unnamed_addr #0 -// CHECK: attributes #0 = { {{.*}}nounwind{{.*}} } + // CHECK: @foo() unnamed_addr #0 + // CHECK: @bar() unnamed_addr #0 + // CHECK: attributes #0 = { {{.*}}nounwind{{.*}} } } diff --git a/tests/codegen/optimize-attr-1.rs b/tests/codegen/optimize-attr-1.rs index c8e68779aae6..3aee44791e0e 100644 --- a/tests/codegen/optimize-attr-1.rs +++ b/tests/codegen/optimize-attr-1.rs @@ -4,7 +4,7 @@ //@[SPEED-OPT] compile-flags: -Copt-level=3 -Ccodegen-units=1 #![feature(optimize_attribute)] -#![crate_type="rlib"] +#![crate_type = "rlib"] // CHECK-LABEL: define{{.*}}i32 @nothing // CHECK-SAME: [[NOTHING_ATTRS:#[0-9]+]] diff --git a/tests/codegen/option-niche-eq.rs b/tests/codegen/option-niche-eq.rs index 25ea5dd595c3..4d3a7ce3764b 100644 --- a/tests/codegen/option-niche-eq.rs +++ b/tests/codegen/option-niche-eq.rs @@ -4,8 +4,8 @@ extern crate core; use core::cmp::Ordering; -use core::ptr::NonNull; use core::num::NonZero; +use core::ptr::NonNull; // CHECK-LABEL: @non_zero_eq #[no_mangle] diff --git a/tests/codegen/packed.rs b/tests/codegen/packed.rs index 5142df9c4881..790d618b2ead 100644 --- a/tests/codegen/packed.rs +++ b/tests/codegen/packed.rs @@ -6,20 +6,20 @@ #[repr(packed)] pub struct Packed1 { dealign: u8, - data: u32 + data: u32, } #[repr(packed(2))] pub struct Packed2 { dealign: u8, - data: u32 + data: u32, } // CHECK-LABEL: @write_pkd1 #[no_mangle] pub fn write_pkd1(pkd: &mut Packed1) -> u32 { -// CHECK: %{{.*}} = load i32, ptr %{{.*}}, align 1 -// CHECK: store i32 42, ptr %{{.*}}, align 1 + // CHECK: %{{.*}} = load i32, ptr %{{.*}}, align 1 + // CHECK: store i32 42, ptr %{{.*}}, align 1 let result = pkd.data; pkd.data = 42; result @@ -28,8 +28,8 @@ pub fn write_pkd1(pkd: &mut Packed1) -> u32 { // CHECK-LABEL: @write_pkd2 #[no_mangle] pub fn write_pkd2(pkd: &mut Packed2) -> u32 { -// CHECK: %{{.*}} = load i32, ptr %{{.*}}, align 2 -// CHECK: store i32 42, ptr %{{.*}}, align 2 + // CHECK: %{{.*}} = load i32, ptr %{{.*}}, align 2 + // CHECK: store i32 42, ptr %{{.*}}, align 2 let result = pkd.data; pkd.data = 42; result @@ -39,21 +39,21 @@ pub struct Array([i32; 8]); #[repr(packed)] pub struct BigPacked1 { dealign: u8, - data: Array + data: Array, } #[repr(packed(2))] pub struct BigPacked2 { dealign: u8, - data: Array + data: Array, } // CHECK-LABEL: @call_pkd1 #[no_mangle] pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 { -// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8] -// CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) -// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) + // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8] + // CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) // check that calls whose destination is a field of a packed struct // go through an alloca rather than calling the function with an // unaligned destination. @@ -63,9 +63,9 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 { // CHECK-LABEL: @call_pkd2 #[no_mangle] pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 { -// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8] -// CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) -// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) + // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8] + // CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) // check that calls whose destination is a field of a packed struct // go through an alloca rather than calling the function with an // unaligned destination. @@ -119,14 +119,14 @@ pub struct Packed2Pair(u8, u32); // CHECK-LABEL: @pkd1_pair #[no_mangle] pub fn pkd1_pair(pair1: &mut Packed1Pair, pair2: &mut Packed1Pair) { -// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, i{{[0-9]+}} 5, i1 false) + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, i{{[0-9]+}} 5, i1 false) *pair2 = *pair1; } // CHECK-LABEL: @pkd2_pair #[no_mangle] pub fn pkd2_pair(pair1: &mut Packed2Pair, pair2: &mut Packed2Pair) { -// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 2 %{{.*}}, i{{[0-9]+}} 6, i1 false) + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 2 %{{.*}}, i{{[0-9]+}} 6, i1 false) *pair2 = *pair1; } @@ -141,13 +141,13 @@ pub struct Packed2NestedPair((u32, u32)); // CHECK-LABEL: @pkd1_nested_pair #[no_mangle] pub fn pkd1_nested_pair(pair1: &mut Packed1NestedPair, pair2: &mut Packed1NestedPair) { -// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, i{{[0-9]+}} 8, i1 false) + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, i{{[0-9]+}} 8, i1 false) *pair2 = *pair1; } // CHECK-LABEL: @pkd2_nested_pair #[no_mangle] pub fn pkd2_nested_pair(pair1: &mut Packed2NestedPair, pair2: &mut Packed2NestedPair) { -// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 2 %{{.*}}, i{{[0-9]+}} 8, i1 false) + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 2 %{{.*}}, i{{[0-9]+}} 8, i1 false) *pair2 = *pair1; } diff --git a/tests/codegen/panic-abort-windows.rs b/tests/codegen/panic-abort-windows.rs index 71caa1b3d2af..eb61e649f04a 100644 --- a/tests/codegen/panic-abort-windows.rs +++ b/tests/codegen/panic-abort-windows.rs @@ -8,11 +8,9 @@ // CHECK: Function Attrs: nounwind uwtable // CHECK-NEXT: define void @normal_uwtable() #[no_mangle] -pub fn normal_uwtable() { -} +pub fn normal_uwtable() {} // CHECK: Function Attrs: nounwind uwtable // CHECK-NEXT: define void @extern_uwtable() #[no_mangle] -pub extern fn extern_uwtable() { -} +pub extern "C" fn extern_uwtable() {} diff --git a/tests/codegen/personality_lifetimes.rs b/tests/codegen/personality_lifetimes.rs index 0ef4aa424d83..828af05436b4 100644 --- a/tests/codegen/personality_lifetimes.rs +++ b/tests/codegen/personality_lifetimes.rs @@ -3,19 +3,17 @@ //@ compile-flags: -O -C no-prepopulate-passes -#![crate_type="lib"] +#![crate_type = "lib"] struct S; impl Drop for S { #[inline(never)] - fn drop(&mut self) { - } + fn drop(&mut self) {} } #[inline(never)] -fn might_unwind() { -} +fn might_unwind() {} // CHECK-LABEL: @test #[no_mangle] diff --git a/tests/codegen/pgo-instrumentation.rs b/tests/codegen/pgo-instrumentation.rs index e2c348edf822..b1906c145c6b 100644 --- a/tests/codegen/pgo-instrumentation.rs +++ b/tests/codegen/pgo-instrumentation.rs @@ -10,12 +10,10 @@ // CHECK-DAG: @__profd_{{.*}}pgo_instrumentation{{.*}}some_other_function{{.*}} = {{.*}}global // CHECK: @__llvm_profile_filename = {{.*}}"default_%m.profraw\00"{{.*}} -#![crate_type="lib"] +#![crate_type = "lib"] #[inline(never)] -fn some_function() { - -} +fn some_function() {} pub fn some_other_function() { some_function(); diff --git a/tests/codegen/pic-relocation-model.rs b/tests/codegen/pic-relocation-model.rs index 10ade847133a..a1d1678a6bda 100644 --- a/tests/codegen/pic-relocation-model.rs +++ b/tests/codegen/pic-relocation-model.rs @@ -5,15 +5,15 @@ // CHECK: define i8 @call_foreign_fn() #[no_mangle] pub fn call_foreign_fn() -> u8 { - unsafe { - foreign_fn() - } + unsafe { foreign_fn() } } // (Allow but do not require `zeroext` here, because it is not worth effort to // spell out which targets have it and which ones do not; see rust#97800.) // CHECK: declare{{( zeroext)?}} i8 @foreign_fn() -extern "C" {fn foreign_fn() -> u8;} +extern "C" { + fn foreign_fn() -> u8; +} // CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2} diff --git a/tests/codegen/pie-relocation-model.rs b/tests/codegen/pie-relocation-model.rs index 20bf8919ac10..b10af6934522 100644 --- a/tests/codegen/pie-relocation-model.rs +++ b/tests/codegen/pie-relocation-model.rs @@ -8,15 +8,15 @@ // CHECK: define dso_local i8 @call_foreign_fn() #[no_mangle] pub fn call_foreign_fn() -> u8 { - unsafe { - foreign_fn() - } + unsafe { foreign_fn() } } // External functions are still marked as non-dso_local, since we don't know if the symbol // is defined in the binary or in the shared library. // CHECK: declare zeroext i8 @foreign_fn() -extern "C" {fn foreign_fn() -> u8;} +extern "C" { + fn foreign_fn() -> u8; +} // CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2} // CHECK: !{i32 7, !"PIE Level", i32 2} diff --git a/tests/codegen/powerpc64le-struct-align-128.rs b/tests/codegen/powerpc64le-struct-align-128.rs index 0096c6d3138b..3981cd121296 100644 --- a/tests/codegen/powerpc64le-struct-align-128.rs +++ b/tests/codegen/powerpc64le-struct-align-128.rs @@ -8,12 +8,12 @@ #![crate_type = "lib"] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="freeze"] -trait Freeze { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} #[repr(C)] pub struct Align8 { @@ -23,7 +23,7 @@ pub struct Align8 { #[repr(transparent)] pub struct Transparent8 { - a: Align8 + a: Align8, } #[repr(C)] @@ -45,7 +45,7 @@ pub struct Align16 { #[repr(transparent)] pub struct Transparent16 { - a: Align16 + a: Align16, } #[repr(C)] @@ -69,7 +69,7 @@ pub struct Align32 { #[repr(transparent)] pub struct Transparent32 { - a: Align32 + a: Align32, } #[repr(C)] @@ -83,9 +83,15 @@ extern "C" { } pub unsafe fn main( - a1: Align8, a2: Transparent8, a3: Wrapped8, - b1: Align16, b2: Transparent16, b3: Wrapped16, - c1: Align32, c2: Transparent32, c3: Wrapped32, + a1: Align8, + a2: Transparent8, + a3: Wrapped8, + b1: Align16, + b2: Transparent16, + b3: Wrapped16, + c1: Align32, + c2: Transparent32, + c3: Wrapped32, ) { test_8(a1, a2, a3); test_16(b1, b2, b3); diff --git a/tests/codegen/precondition-checks.rs b/tests/codegen/precondition-checks.rs index 191494450037..16812ca17207 100644 --- a/tests/codegen/precondition-checks.rs +++ b/tests/codegen/precondition-checks.rs @@ -21,7 +21,5 @@ use std::ptr::NonNull; #[no_mangle] pub unsafe fn nonnull_new(ptr: *mut u8) -> NonNull { // CHECK: ; call core::ptr::non_null::NonNull::new_unchecked - unsafe { - NonNull::new_unchecked(ptr) - } + unsafe { NonNull::new_unchecked(ptr) } } diff --git a/tests/codegen/refs.rs b/tests/codegen/refs.rs index 40ce04c07a11..97c362950855 100644 --- a/tests/codegen/refs.rs +++ b/tests/codegen/refs.rs @@ -5,17 +5,16 @@ // Hack to get the correct size for the length part in slices // CHECK: @helper([[USIZE:i[0-9]+]] %_1) #[no_mangle] -pub fn helper(_: usize) { -} +pub fn helper(_: usize) {} // CHECK-LABEL: @ref_dst #[no_mangle] pub fn ref_dst(s: &[u8]) { // We used to generate an extra alloca and memcpy to ref the dst, so check that we copy // directly to the alloca for "x" -// CHECK: store ptr %s.0, {{.*}} %x -// CHECK: [[X1:%[0-9]+]] = getelementptr inbounds i8, {{.*}} %x, {{i32 4|i64 8}} -// CHECK: store [[USIZE]] %s.1, {{.*}} [[X1]] + // CHECK: store ptr %s.0, {{.*}} %x + // CHECK: [[X1:%[0-9]+]] = getelementptr inbounds i8, {{.*}} %x, {{i32 4|i64 8}} + // CHECK: store [[USIZE]] %s.1, {{.*}} [[X1]] let x = &*s; &x; // keep variable in an alloca diff --git a/tests/codegen/repr/transparent-imm-array.rs b/tests/codegen/repr/transparent-imm-array.rs index 917a2c6ef527..1acd4742d356 100644 --- a/tests/codegen/repr/transparent-imm-array.rs +++ b/tests/codegen/repr/transparent-imm-array.rs @@ -26,15 +26,17 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} impl Copy for [u32; 16] {} impl Copy for BigS {} impl Copy for BigU {} - #[repr(C)] pub struct BigS([u32; 16]); @@ -53,20 +55,27 @@ pub enum TeBigS { // CHECK: define void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGS_RET_ATTRS2:.*]], [16 x i32] #[no_mangle] -pub extern fn test_BigS(_: BigS) -> BigS { loop {} } +pub extern "C" fn test_BigS(_: BigS) -> BigS { + loop {} +} // CHECK: define void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [16 x i32] #[no_mangle] -pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } +pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { + loop {} +} // CHECK: define void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [16 x i32] #[no_mangle] -pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } +pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { + loop {} +} // CHECK: define void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [16 x i32] #[no_mangle] -pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } - +pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { + loop {} +} #[repr(C)] pub union BigU { @@ -88,16 +97,24 @@ pub enum TeBigU { // CHECK: define void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], [16 x i32] #[no_mangle] -pub extern fn test_BigU(_: BigU) -> BigU { loop {} } +pub extern "C" fn test_BigU(_: BigU) -> BigU { + loop {} +} // CHECK: define void @test_TsBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [16 x i32] #[no_mangle] -pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } +pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { + loop {} +} // CHECK: define void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [16 x i32] #[no_mangle] -pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } +pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { + loop {} +} // CHECK: define void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [16 x i32] #[no_mangle] -pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } +pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { + loop {} +} diff --git a/tests/codegen/repr/transparent-mips64.rs b/tests/codegen/repr/transparent-mips64.rs index ebed8d7989fd..588d440b4d7b 100644 --- a/tests/codegen/repr/transparent-mips64.rs +++ b/tests/codegen/repr/transparent-mips64.rs @@ -13,9 +13,12 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} impl Copy for [u32; 16] {} impl Copy for BigS {} @@ -39,20 +42,27 @@ pub enum TeBigS { // CHECK: define void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGS_RET_ATTRS2:.*]], [8 x i64] #[no_mangle] -pub extern fn test_BigS(_: BigS) -> BigS { loop {} } +pub extern "C" fn test_BigS(_: BigS) -> BigS { + loop {} +} // CHECK: define void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [8 x i64] #[no_mangle] -pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } +pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { + loop {} +} // CHECK: define void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [8 x i64] #[no_mangle] -pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } +pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { + loop {} +} // CHECK: define void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [8 x i64] #[no_mangle] -pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } - +pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { + loop {} +} #[repr(C)] pub union BigU { @@ -74,16 +84,24 @@ pub enum TeBigU { // CHECK: define void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], [8 x i64] #[no_mangle] -pub extern fn test_BigU(_: BigU) -> BigU { loop {} } +pub extern "C" fn test_BigU(_: BigU) -> BigU { + loop {} +} // CHECK: define void @test_TsBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [8 x i64] #[no_mangle] -pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } +pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { + loop {} +} // CHECK: define void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [8 x i64] #[no_mangle] -pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } +pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { + loop {} +} // CHECK: define void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [8 x i64] #[no_mangle] -pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } +pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { + loop {} +} diff --git a/tests/codegen/repr/transparent-sparc64.rs b/tests/codegen/repr/transparent-sparc64.rs index 7005a07f554f..8e4c8ce2ee9b 100644 --- a/tests/codegen/repr/transparent-sparc64.rs +++ b/tests/codegen/repr/transparent-sparc64.rs @@ -8,15 +8,17 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} impl Copy for [u32; 16] {} impl Copy for BigS {} impl Copy for BigU {} - #[repr(C)] pub struct BigS([u32; 16]); @@ -37,26 +39,33 @@ pub enum TeBigS { // CHECK-NOT: byval // CHECK-SAME: %{{[0-9a-z_]+}}) #[no_mangle] -pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} } +pub extern "C" fn test_BigS(_: BigS) -> BigS { + loop {} +} // CHECK: define{{.*}}void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr // CHECK-NOT: byval // CHECK-SAME: %{{[0-9a-z_]+}}) #[no_mangle] -pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } +pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { + loop {} +} // CHECK: define{{.*}}void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr // CHECK-NOT: byval // CHECK-SAME: %{{[0-9a-z_]+}}) #[no_mangle] -pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } +pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { + loop {} +} // CHECK: define{{.*}}void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr // CHECK-NOT: byval // CHECK-SAME: %{{[0-9a-z_]+}}) #[no_mangle] -pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } - +pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { + loop {} +} #[repr(C)] pub union BigU { @@ -80,22 +89,30 @@ pub enum TeBigU { // CHECK-NOT: byval // CHECK-SAME: %{{[0-9a-z_]+}}) #[no_mangle] -pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} } +pub extern "C" fn test_BigU(_: BigU) -> BigU { + loop {} +} // CHECK: define{{.*}}void @test_TsBigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr // CHECK-NOT: byval // CHECK-SAME: %{{[0-9a-z_]+}}) #[no_mangle] -pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } +pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { + loop {} +} // CHECK: define{{.*}}void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr // CHECK-NOT: byval // CHECK-SAME: %{{[0-9a-z_]+}}) #[no_mangle] -pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } +pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { + loop {} +} // CHECK: define{{.*}}void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr // CHECK-NOT: byval // CHECK-SAME: %{{[0-9a-z_]+}}) #[no_mangle] -pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } +pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { + loop {} +} diff --git a/tests/codegen/repr/transparent-struct-ptr.rs b/tests/codegen/repr/transparent-struct-ptr.rs index 26f0120752f2..9cffd6c7f732 100644 --- a/tests/codegen/repr/transparent-struct-ptr.rs +++ b/tests/codegen/repr/transparent-struct-ptr.rs @@ -22,15 +22,17 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} impl Copy for [u32; 16] {} impl Copy for BigS {} impl Copy for BigU {} - #[repr(C)] pub struct BigS([u32; 16]); @@ -49,20 +51,27 @@ pub enum TeBigS { // CHECK: define{{.*}}void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGS_RET_ATTRS2:.*]], ptr [[BIGS_ARG_ATTRS1:.*]] byval([64 x i8]) [[BIGS_ARG_ATTRS2:.*]]) #[no_mangle] -pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} } +pub extern "C" fn test_BigS(_: BigS) -> BigS { + loop {} +} // CHECK: define{{.*}}void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval([64 x i8]) [[BIGS_ARG_ATTRS2:.*]]) #[no_mangle] -pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } +pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { + loop {} +} // CHECK: define{{.*}}void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval([64 x i8]) [[BIGS_ARG_ATTRS2:.*]]) #[no_mangle] -pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } +pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { + loop {} +} // CHECK: define{{.*}}void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval([64 x i8]) [[BIGS_ARG_ATTRS2]]) #[no_mangle] -pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } - +pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { + loop {} +} #[repr(C)] pub union BigU { @@ -84,16 +93,24 @@ pub enum TeBigU { // CHECK: define{{.*}}void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1:.*]] byval([64 x i8]) [[BIGU_ARG_ATTRS2:.*]]) #[no_mangle] -pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} } +pub extern "C" fn test_BigU(_: BigU) -> BigU { + loop {} +} // CHECK: define{{.*}}void @test_TsBigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval([64 x i8]) [[BIGU_ARG_ATTRS2]]) #[no_mangle] -pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } +pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { + loop {} +} // CHECK: define{{.*}}void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval([64 x i8]) [[BIGU_ARG_ATTRS2]]) #[no_mangle] -pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } +pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { + loop {} +} // CHECK: define{{.*}}void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval([64 x i8]) [[BIGU_ARG_ATTRS2]]) #[no_mangle] -pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } +pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { + loop {} +} diff --git a/tests/codegen/repr/transparent-sysv64.rs b/tests/codegen/repr/transparent-sysv64.rs index 1c7bca7ee406..afb06dcc1bdf 100644 --- a/tests/codegen/repr/transparent-sysv64.rs +++ b/tests/codegen/repr/transparent-sysv64.rs @@ -13,19 +13,28 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} #[repr(C)] -pub struct Rgb8 { r: u8, g: u8, b: u8 } +pub struct Rgb8 { + r: u8, + g: u8, + b: u8, +} #[repr(transparent)] pub struct Rgb8Wrap(Rgb8); // CHECK: i24 @test_Rgb8Wrap(i24{{( %0)?}}) #[no_mangle] -pub extern "sysv64" fn test_Rgb8Wrap(_: Rgb8Wrap) -> Rgb8Wrap { loop {} } +pub extern "sysv64" fn test_Rgb8Wrap(_: Rgb8Wrap) -> Rgb8Wrap { + loop {} +} #[repr(C)] pub union FloatBits { @@ -38,4 +47,6 @@ pub struct SmallUnion(FloatBits); // CHECK: i32 @test_SmallUnion(i32{{( %0)?}}) #[no_mangle] -pub extern "sysv64" fn test_SmallUnion(_: SmallUnion) -> SmallUnion { loop {} } +pub extern "sysv64" fn test_SmallUnion(_: SmallUnion) -> SmallUnion { + loop {} +} diff --git a/tests/codegen/repr/transparent.rs b/tests/codegen/repr/transparent.rs index 17ec476035f2..4b41332db451 100644 --- a/tests/codegen/repr/transparent.rs +++ b/tests/codegen/repr/transparent.rs @@ -8,7 +8,7 @@ // For RISCV: see codegen/riscv-abi // For LoongArch: see codegen/loongarch-abi -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(repr_simd, transparent_unions)] use std::marker::PhantomData; @@ -24,83 +24,112 @@ pub struct F32(f32); // CHECK: define{{.*}}float @test_F32(float noundef %_1) #[no_mangle] -pub extern "C" fn test_F32(_: F32) -> F32 { loop {} } +pub extern "C" fn test_F32(_: F32) -> F32 { + loop {} +} #[repr(transparent)] pub struct Ptr(*mut u8); // CHECK: define{{.*}}ptr @test_Ptr(ptr noundef %_1) #[no_mangle] -pub extern "C" fn test_Ptr(_: Ptr) -> Ptr { loop {} } +pub extern "C" fn test_Ptr(_: Ptr) -> Ptr { + loop {} +} #[repr(transparent)] pub struct WithZst(u64, Zst1); // CHECK: define{{.*}}i64 @test_WithZst(i64 noundef %_1) #[no_mangle] -pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} } +pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { + loop {} +} #[repr(transparent)] pub struct WithZeroSizedArray(*const f32, [i8; 0]); // CHECK: define{{.*}}ptr @test_WithZeroSizedArray(ptr noundef %_1) #[no_mangle] -pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} } +pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { + loop {} +} #[repr(transparent)] pub struct Generic(T); // CHECK: define{{.*}}double @test_Generic(double noundef %_1) #[no_mangle] -pub extern "C" fn test_Generic(_: Generic) -> Generic { loop {} } +pub extern "C" fn test_Generic(_: Generic) -> Generic { + loop {} +} #[repr(transparent)] pub struct GenericPlusZst(T, Zst2); #[repr(u8)] -pub enum Bool { True, False, FileNotFound } +pub enum Bool { + True, + False, + FileNotFound, +} // CHECK: define{{( dso_local)?}} noundef{{( zeroext)?}} i8 @test_Gpz(i8 noundef{{( zeroext)?}} %_1) #[no_mangle] -pub extern "C" fn test_Gpz(_: GenericPlusZst) -> GenericPlusZst { loop {} } +pub extern "C" fn test_Gpz(_: GenericPlusZst) -> GenericPlusZst { + loop {} +} #[repr(transparent)] pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>); // CHECK: define{{.*}}ptr @test_LifetimePhantom(ptr noundef %_1) #[no_mangle] -pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom) -> LifetimePhantom { loop {} } +pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom) -> LifetimePhantom { + loop {} +} // This works despite current alignment resrictions because PhantomData is always align(1) #[repr(transparent)] -pub struct UnitPhantom { val: T, unit: PhantomData } +pub struct UnitPhantom { + val: T, + unit: PhantomData, +} pub struct Px; // CHECK: define{{.*}}float @test_UnitPhantom(float noundef %_1) #[no_mangle] -pub extern "C" fn test_UnitPhantom(_: UnitPhantom) -> UnitPhantom { loop {} } +pub extern "C" fn test_UnitPhantom(_: UnitPhantom) -> UnitPhantom { + loop {} +} #[repr(transparent)] pub struct TwoZsts(Zst1, i8, Zst2); // CHECK: define{{( dso_local)?}} noundef{{( signext)?}} i8 @test_TwoZsts(i8 noundef{{( signext)?}} %_1) #[no_mangle] -pub extern "C" fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} } +pub extern "C" fn test_TwoZsts(_: TwoZsts) -> TwoZsts { + loop {} +} #[repr(transparent)] pub struct Nested1(Zst2, Generic); // CHECK: define{{.*}}double @test_Nested1(double noundef %_1) #[no_mangle] -pub extern "C" fn test_Nested1(_: Nested1) -> Nested1 { loop {} } +pub extern "C" fn test_Nested1(_: Nested1) -> Nested1 { + loop {} +} #[repr(transparent)] pub struct Nested2(Nested1, Zst1); // CHECK: define{{.*}}double @test_Nested2(double noundef %_1) #[no_mangle] -pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 { loop {} } +pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 { + loop {} +} #[repr(simd)] struct f32x4(f32, f32, f32, f32); @@ -110,35 +139,47 @@ pub struct Vector(f32x4); // CHECK: define{{.*}}<4 x float> @test_Vector(<4 x float> %_1) #[no_mangle] -pub extern "C" fn test_Vector(_: Vector) -> Vector { loop {} } +pub extern "C" fn test_Vector(_: Vector) -> Vector { + loop {} +} -trait Mirror { type It: ?Sized; } -impl Mirror for T { type It = Self; } +trait Mirror { + type It: ?Sized; +} +impl Mirror for T { + type It = Self; +} #[repr(transparent)] pub struct StructWithProjection(::It); // CHECK: define{{.*}}float @test_Projection(float noundef %_1) #[no_mangle] -pub extern "C" fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} } +pub extern "C" fn test_Projection(_: StructWithProjection) -> StructWithProjection { + loop {} +} #[repr(transparent)] pub enum EnumF32 { - Variant(F32) + Variant(F32), } // CHECK: define{{.*}}float @test_EnumF32(float noundef %_1) #[no_mangle] -pub extern "C" fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} } +pub extern "C" fn test_EnumF32(_: EnumF32) -> EnumF32 { + loop {} +} #[repr(transparent)] pub enum EnumF32WithZsts { - Variant(Zst1, F32, Zst2) + Variant(Zst1, F32, Zst2), } // CHECK: define{{.*}}float @test_EnumF32WithZsts(float noundef %_1) #[no_mangle] -pub extern "C" fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} } +pub extern "C" fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { + loop {} +} #[repr(transparent)] pub union UnionF32 { @@ -147,7 +188,9 @@ pub union UnionF32 { // CHECK: define{{.*}} float @test_UnionF32(float %_1) #[no_mangle] -pub extern "C" fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} } +pub extern "C" fn test_UnionF32(_: UnionF32) -> UnionF32 { + loop {} +} #[repr(transparent)] pub union UnionF32WithZsts { @@ -158,8 +201,9 @@ pub union UnionF32WithZsts { // CHECK: define{{.*}}float @test_UnionF32WithZsts(float %_1) #[no_mangle] -pub extern "C" fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} } - +pub extern "C" fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { + loop {} +} // All that remains to be tested are aggregates. They are tested in separate files called // transparent-*.rs with `only-*` or `ignore-*` directives, because the expected LLVM IR diff --git a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs index 95c936ece730..977749ad578a 100644 --- a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs +++ b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs @@ -83,8 +83,7 @@ pub struct Tiny { // CHECK: define void @f_agg_tiny(i64 %0) #[no_mangle] -pub extern "C" fn f_agg_tiny(mut e: Tiny) { -} +pub extern "C" fn f_agg_tiny(mut e: Tiny) {} // CHECK: define i64 @f_agg_tiny_ret() #[no_mangle] @@ -100,8 +99,7 @@ pub struct Small { // CHECK: define void @f_agg_small([2 x i64] %0) #[no_mangle] -pub extern "C" fn f_agg_small(mut x: Small) { -} +pub extern "C" fn f_agg_small(mut x: Small) {} // CHECK: define [2 x i64] @f_agg_small_ret() #[no_mangle] @@ -116,8 +114,7 @@ pub struct SmallAligned { // CHECK: define void @f_agg_small_aligned(i128 %0) #[no_mangle] -pub extern "C" fn f_agg_small_aligned(mut x: SmallAligned) { -} +pub extern "C" fn f_agg_small_aligned(mut x: SmallAligned) {} #[repr(C)] pub struct Large { @@ -129,8 +126,7 @@ pub struct Large { // CHECK: define void @f_agg_large(ptr {{.*}}%x) #[no_mangle] -pub extern "C" fn f_agg_large(mut x: Large) { -} +pub extern "C" fn f_agg_large(mut x: Large) {} // CHECK: define void @f_agg_large_ret(ptr {{.*}}sret{{.*}}, i32 noundef signext %i, i8 noundef signext %j) #[no_mangle] diff --git a/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs index 8ffa235c18f1..f319306f93fd 100644 --- a/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs +++ b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs @@ -23,7 +23,7 @@ //@[ASAN] compile-flags: //@[ASAN-FAT-LTO] compile-flags: -Cprefer-dynamic=false -Clto=fat -#![crate_type="staticlib"] +#![crate_type = "staticlib"] // The test below mimics `CACHED_POW10` from `library/core/src/num/flt2dec/strategy/grisu.rs` which // (because of incorrect handling of `___asan_globals_registered` during LTO) was incorrectly diff --git a/tests/codegen/sanitizer/cfi/add-canonical-jump-tables-flag.rs b/tests/codegen/sanitizer/cfi/add-canonical-jump-tables-flag.rs index f122fbdc0866..22577e2a3c46 100644 --- a/tests/codegen/sanitizer/cfi/add-canonical-jump-tables-flag.rs +++ b/tests/codegen/sanitizer/cfi/add-canonical-jump-tables-flag.rs @@ -3,9 +3,8 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -#![crate_type="lib"] +#![crate_type = "lib"] -pub fn foo() { -} +pub fn foo() {} // CHECK: !{{[0-9]+}} = !{i32 4, !"CFI Canonical Jump Tables", i32 1} diff --git a/tests/codegen/sanitizer/cfi/add-enable-split-lto-unit-flag.rs b/tests/codegen/sanitizer/cfi/add-enable-split-lto-unit-flag.rs index 05eea13c6ee0..283b8f261029 100644 --- a/tests/codegen/sanitizer/cfi/add-enable-split-lto-unit-flag.rs +++ b/tests/codegen/sanitizer/cfi/add-enable-split-lto-unit-flag.rs @@ -3,9 +3,8 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -#![crate_type="lib"] +#![crate_type = "lib"] -pub fn foo() { -} +pub fn foo() {} // CHECK: !{{[0-9]+}} = !{i32 4, !"EnableSplitLTOUnit", i32 1} diff --git a/tests/codegen/sanitizer/cfi/emit-type-checks-attr-no-sanitize.rs b/tests/codegen/sanitizer/cfi/emit-type-checks-attr-no-sanitize.rs index 9f72de2ebcc9..259967e89181 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-checks-attr-no-sanitize.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-checks-attr-no-sanitize.rs @@ -3,7 +3,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(no_sanitize)] #[no_sanitize(cfi)] diff --git a/tests/codegen/sanitizer/cfi/emit-type-checks.rs b/tests/codegen/sanitizer/cfi/emit-type-checks.rs index 6ec6f0e5476d..37edbefee56a 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-checks.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-checks.rs @@ -3,7 +3,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs index be4af9b7962d..9bc2e42db0f6 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs @@ -3,13 +3,13 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(cfi_encoding, extern_types)] #[cfi_encoding = "3Foo"] pub struct Type1(i32); -extern { +extern "C" { #[cfi_encoding = "3Bar"] type Type2; } @@ -25,35 +25,35 @@ pub struct Type4(i32); #[repr(transparent)] pub struct Type5(u32); -pub fn foo0(_: Type1) { } +pub fn foo0(_: Type1) {} // CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo1(_: Type1, _: Type1) { } +pub fn foo1(_: Type1, _: Type1) {} // CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: Type1, _: Type1, _: Type1) { } +pub fn foo2(_: Type1, _: Type1, _: Type1) {} // CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: *mut Type2) { } +pub fn foo3(_: *mut Type2) {} // CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo4(_: *mut Type2, _: *mut Type2) { } +pub fn foo4(_: *mut Type2, _: *mut Type2) {} // CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo5(_: *mut Type2, _: *mut Type2, _: *mut Type2) { } +pub fn foo5(_: *mut Type2, _: *mut Type2, _: *mut Type2) {} // CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo6(_: *mut Type3) { } +pub fn foo6(_: *mut Type3) {} // CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo7(_: *mut Type3, _: *mut Type3) { } +pub fn foo7(_: *mut Type3, _: *mut Type3) {} // CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo8(_: *mut Type3, _: *mut Type3, _: *mut Type3) { } +pub fn foo8(_: *mut Type3, _: *mut Type3, _: *mut Type3) {} // CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo9(_: Type4) { } +pub fn foo9(_: Type4) {} // CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo10(_: Type4, _: Type4) { } +pub fn foo10(_: Type4, _: Type4) {} // CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo11(_: Type4, _: Type4, _: Type4) { } +pub fn foo11(_: Type4, _: Type4, _: Type4) {} // CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo12(_: Type5) { } +pub fn foo12(_: Type5) {} // CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo13(_: Type5, _: Type5) { } +pub fn foo13(_: Type5, _: Type5) {} // CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo14(_: Type5, _: Type5, _: Type5) { } +pub fn foo14(_: Type5, _: Type5, _: Type5) {} // CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFv3FooE"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs index 6608caca8af8..25dba97962ae 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs @@ -4,25 +4,26 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(type_alias_impl_trait)] extern crate core; pub type Type1 = impl Send; -pub fn foo() where +pub fn foo() +where Type1: 'static, { pub struct Foo([T; N]); let _: Type1 = Foo([0; 32]); } -pub fn foo1(_: Type1) { } +pub fn foo1(_: Type1) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: Type1, _: Type1) { } +pub fn foo2(_: Type1, _: Type1) {} // CHECK: define{{.*}}4foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: Type1, _: Type1, _: Type1) { } +pub fn foo3(_: Type1, _: Type1, _: Type1) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EEE"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs index 3ec1988edd6e..2a7eca6fc196 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs @@ -3,7 +3,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -#![crate_type="lib"] +#![crate_type = "lib"] // CHECK-LABEL: define{{.*}}4core3ptr47drop_in_place$LT$dyn$u20$core..marker..Send$GT$ // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs index c5dadf70de95..7e60aafff680 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs @@ -4,29 +4,29 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -#![crate_type="lib"] +#![crate_type = "lib"] -pub fn foo1(_: fn(i32) -> i32) { } +pub fn foo1(_: fn(i32) -> i32) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: fn(i32) -> i32, _: fn(i32) -> i32) { } +pub fn foo2(_: fn(i32) -> i32, _: fn(i32) -> i32) {} // CHECK: define{{.*}}4foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: fn(i32) -> i32, _: fn(i32) -> i32, _: fn(i32) -> i32) { } +pub fn foo3(_: fn(i32) -> i32, _: fn(i32) -> i32, _: fn(i32) -> i32) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo4(_: &dyn Fn(i32) -> i32) { } +pub fn foo4(_: &dyn Fn(i32) -> i32) {} // CHECK: define{{.*}}4foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo5(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { } +pub fn foo5(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) {} // CHECK: define{{.*}}4foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo6(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { } +pub fn foo6(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) {} // CHECK: define{{.*}}4foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo7(_: &dyn FnMut(i32) -> i32) { } +pub fn foo7(_: &dyn FnMut(i32) -> i32) {} // CHECK: define{{.*}}4foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo8(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { } +pub fn foo8(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) {} // CHECK: define{{.*}}4foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo9(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { } +pub fn foo9(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) {} // CHECK: define{{.*}}4foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo10(_: &dyn FnOnce(i32) -> i32) { } +pub fn foo10(_: &dyn FnOnce(i32) -> i32) {} // CHECK: define{{.*}}5foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo11(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) { } +pub fn foo11(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) {} // CHECK: define{{.*}}5foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo12(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) {} // CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs index 4d08c0c3039a..3ef119fd905a 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs @@ -4,14 +4,15 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(type_alias_impl_trait)] extern crate core; pub type Type1 = impl Send; -pub fn foo<'a>() where +pub fn foo<'a>() +where Type1: 'static, { pub struct Foo<'a>(&'a i32); @@ -19,9 +20,9 @@ pub fn foo<'a>() where let _: Type1 = Bar; } -pub fn foo1(_: Type1) { } +pub fn foo1(_: Type1) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: Type1, _: Type1) { } +pub fn foo2(_: Type1, _: Type1) {} // CHECK: define{{.*}}4foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: Type1, _: Type1, _: Type1) { } +pub fn foo3(_: Type1, _: Type1, _: Type1) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs index 671db563dde7..9d611777ff0b 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs @@ -4,7 +4,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -#![crate_type="lib"] +#![crate_type = "lib"] trait Trait1 { fn foo(&self); @@ -17,6 +17,5 @@ impl Trait1 for Type1 { // CHECK: define{{.*}}3foo{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} } - // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait1u6regionEEE"} // CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type1EE"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs index 6ad6f3ac3489..d37bb740f550 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs @@ -4,37 +4,37 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -#![crate_type="lib"] +#![crate_type = "lib"] -pub fn foo1(_: &mut i32) { } +pub fn foo1(_: &mut i32) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: &mut i32, _: &i32) { } +pub fn foo2(_: &mut i32, _: &i32) {} // CHECK: define{{.*}}4foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: &mut i32, _: &i32, _: &i32) { } +pub fn foo3(_: &mut i32, _: &i32, _: &i32) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo4(_: &i32) { } +pub fn foo4(_: &i32) {} // CHECK: define{{.*}}4foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo5(_: &i32, _: &mut i32) { } +pub fn foo5(_: &i32, _: &mut i32) {} // CHECK: define{{.*}}4foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo6(_: &i32, _: &mut i32, _: &mut i32) { } +pub fn foo6(_: &i32, _: &mut i32, _: &mut i32) {} // CHECK: define{{.*}}4foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo7(_: *mut i32) { } +pub fn foo7(_: *mut i32) {} // CHECK: define{{.*}}4foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo8(_: *mut i32, _: *const i32) { } +pub fn foo8(_: *mut i32, _: *const i32) {} // CHECK: define{{.*}}4foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo9(_: *mut i32, _: *const i32, _: *const i32) { } +pub fn foo9(_: *mut i32, _: *const i32, _: *const i32) {} // CHECK: define{{.*}}4foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo10(_: *const i32) { } +pub fn foo10(_: *const i32) {} // CHECK: define{{.*}}5foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo11(_: *const i32, _: *mut i32) { } +pub fn foo11(_: *const i32, _: *mut i32) {} // CHECK: define{{.*}}5foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo12(_: *const i32, _: *mut i32, _: *mut i32) { } +pub fn foo12(_: *const i32, _: *mut i32, _: *mut i32) {} // CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo13(_: fn(i32) -> i32) { } +pub fn foo13(_: fn(i32) -> i32) {} // CHECK: define{{.*}}5foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo14(_: fn(i32) -> i32, _: fn(i32) -> i32) { } +pub fn foo14(_: fn(i32) -> i32, _: fn(i32) -> i32) {} // CHECK: define{{.*}}5foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo15(_: fn(i32) -> i32, _: fn(i32) -> i32, _: fn(i32) -> i32) { } +pub fn foo15(_: fn(i32) -> i32, _: fn(i32) -> i32, _: fn(i32) -> i32) {} // CHECK: define{{.*}}5foo15{{.*}}!type ![[TYPE15:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvU3mutu3refIu3i32EE"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs index 38f507856bde..7d9e4d058727 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs @@ -4,130 +4,130 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -#![crate_type="lib"] +#![crate_type = "lib"] extern crate core; use core::ffi::*; -pub fn foo1(_: ()) { } +pub fn foo1(_: ()) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: (), _: c_void) { } +pub fn foo2(_: (), _: c_void) {} // CHECK: define{{.*}}4foo2{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: (), _: c_void, _: c_void) { } +pub fn foo3(_: (), _: c_void, _: c_void) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo4(_: *mut ()) { } +pub fn foo4(_: *mut ()) {} // CHECK: define{{.*}}4foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo5(_: *mut (), _: *mut c_void) { } +pub fn foo5(_: *mut (), _: *mut c_void) {} // CHECK: define{{.*}}4foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo6(_: *mut (), _: *mut c_void, _: *mut c_void) { } +pub fn foo6(_: *mut (), _: *mut c_void, _: *mut c_void) {} // CHECK: define{{.*}}4foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo7(_: *const ()) { } +pub fn foo7(_: *const ()) {} // CHECK: define{{.*}}4foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo8(_: *const (), _: *const c_void) { } +pub fn foo8(_: *const (), _: *const c_void) {} // CHECK: define{{.*}}4foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo9(_: *const (), _: *const c_void, _: *const c_void) { } +pub fn foo9(_: *const (), _: *const c_void, _: *const c_void) {} // CHECK: define{{.*}}4foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo10(_: bool) { } +pub fn foo10(_: bool) {} // CHECK: define{{.*}}5foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo11(_: bool, _: bool) { } +pub fn foo11(_: bool, _: bool) {} // CHECK: define{{.*}}5foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo12(_: bool, _: bool, _: bool) { } +pub fn foo12(_: bool, _: bool, _: bool) {} // CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo13(_: i8) { } +pub fn foo13(_: i8) {} // CHECK: define{{.*}}5foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo14(_: i8, _: i8) { } +pub fn foo14(_: i8, _: i8) {} // CHECK: define{{.*}}5foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo15(_: i8, _: i8, _: i8) { } +pub fn foo15(_: i8, _: i8, _: i8) {} // CHECK: define{{.*}}5foo15{{.*}}!type ![[TYPE15:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo16(_: i16) { } +pub fn foo16(_: i16) {} // CHECK: define{{.*}}5foo16{{.*}}!type ![[TYPE16:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo17(_: i16, _: i16) { } +pub fn foo17(_: i16, _: i16) {} // CHECK: define{{.*}}5foo17{{.*}}!type ![[TYPE17:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo18(_: i16, _: i16, _: i16) { } +pub fn foo18(_: i16, _: i16, _: i16) {} // CHECK: define{{.*}}5foo18{{.*}}!type ![[TYPE18:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo19(_: i32) { } +pub fn foo19(_: i32) {} // CHECK: define{{.*}}5foo19{{.*}}!type ![[TYPE19:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo20(_: i32, _: i32) { } +pub fn foo20(_: i32, _: i32) {} // CHECK: define{{.*}}5foo20{{.*}}!type ![[TYPE20:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo21(_: i32, _: i32, _: i32) { } +pub fn foo21(_: i32, _: i32, _: i32) {} // CHECK: define{{.*}}5foo21{{.*}}!type ![[TYPE21:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo22(_: i64) { } +pub fn foo22(_: i64) {} // CHECK: define{{.*}}5foo22{{.*}}!type ![[TYPE22:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo23(_: i64, _: i64) { } +pub fn foo23(_: i64, _: i64) {} // CHECK: define{{.*}}5foo23{{.*}}!type ![[TYPE23:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo24(_: i64, _: i64, _: i64) { } +pub fn foo24(_: i64, _: i64, _: i64) {} // CHECK: define{{.*}}5foo24{{.*}}!type ![[TYPE24:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo25(_: i128) { } +pub fn foo25(_: i128) {} // CHECK: define{{.*}}5foo25{{.*}}!type ![[TYPE25:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo26(_: i128, _: i128) { } +pub fn foo26(_: i128, _: i128) {} // CHECK: define{{.*}}5foo26{{.*}}!type ![[TYPE26:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo27(_: i128, _: i128, _: i128) { } +pub fn foo27(_: i128, _: i128, _: i128) {} // CHECK: define{{.*}}5foo27{{.*}}!type ![[TYPE27:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo28(_: isize) { } +pub fn foo28(_: isize) {} // CHECK: define{{.*}}5foo28{{.*}}!type ![[TYPE28:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo29(_: isize, _: isize) { } +pub fn foo29(_: isize, _: isize) {} // CHECK: define{{.*}}5foo29{{.*}}!type ![[TYPE29:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo30(_: isize, _: isize, _: isize) { } +pub fn foo30(_: isize, _: isize, _: isize) {} // CHECK: define{{.*}}5foo30{{.*}}!type ![[TYPE30:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo31(_: u8) { } +pub fn foo31(_: u8) {} // CHECK: define{{.*}}5foo31{{.*}}!type ![[TYPE31:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo32(_: u8, _: u8) { } +pub fn foo32(_: u8, _: u8) {} // CHECK: define{{.*}}5foo32{{.*}}!type ![[TYPE32:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo33(_: u8, _: u8, _: u8) { } +pub fn foo33(_: u8, _: u8, _: u8) {} // CHECK: define{{.*}}5foo33{{.*}}!type ![[TYPE33:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo34(_: u16) { } +pub fn foo34(_: u16) {} // CHECK: define{{.*}}5foo34{{.*}}!type ![[TYPE34:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo35(_: u16, _: u16) { } +pub fn foo35(_: u16, _: u16) {} // CHECK: define{{.*}}5foo35{{.*}}!type ![[TYPE35:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo36(_: u16, _: u16, _: u16) { } +pub fn foo36(_: u16, _: u16, _: u16) {} // CHECK: define{{.*}}5foo36{{.*}}!type ![[TYPE36:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo37(_: u32) { } +pub fn foo37(_: u32) {} // CHECK: define{{.*}}5foo37{{.*}}!type ![[TYPE37:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo38(_: u32, _: u32) { } +pub fn foo38(_: u32, _: u32) {} // CHECK: define{{.*}}5foo38{{.*}}!type ![[TYPE38:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo39(_: u32, _: u32, _: u32) { } +pub fn foo39(_: u32, _: u32, _: u32) {} // CHECK: define{{.*}}5foo39{{.*}}!type ![[TYPE39:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo40(_: u64) { } +pub fn foo40(_: u64) {} // CHECK: define{{.*}}5foo40{{.*}}!type ![[TYPE40:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo41(_: u64, _: u64) { } +pub fn foo41(_: u64, _: u64) {} // CHECK: define{{.*}}5foo41{{.*}}!type ![[TYPE41:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo42(_: u64, _: u64, _: u64) { } +pub fn foo42(_: u64, _: u64, _: u64) {} // CHECK: define{{.*}}5foo42{{.*}}!type ![[TYPE42:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo43(_: u128) { } +pub fn foo43(_: u128) {} // CHECK: define{{.*}}5foo43{{.*}}!type ![[TYPE43:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo44(_: u128, _: u128) { } +pub fn foo44(_: u128, _: u128) {} // CHECK: define{{.*}}5foo44{{.*}}!type ![[TYPE44:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo45(_: u128, _: u128, _: u128) { } +pub fn foo45(_: u128, _: u128, _: u128) {} // CHECK: define{{.*}}5foo45{{.*}}!type ![[TYPE45:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo46(_: usize) { } +pub fn foo46(_: usize) {} // CHECK: define{{.*}}5foo46{{.*}}!type ![[TYPE46:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo47(_: usize, _: usize) { } +pub fn foo47(_: usize, _: usize) {} // CHECK: define{{.*}}5foo47{{.*}}!type ![[TYPE47:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo48(_: usize, _: usize, _: usize) { } +pub fn foo48(_: usize, _: usize, _: usize) {} // CHECK: define{{.*}}5foo48{{.*}}!type ![[TYPE48:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo49(_: f32) { } +pub fn foo49(_: f32) {} // CHECK: define{{.*}}5foo49{{.*}}!type ![[TYPE49:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo50(_: f32, _: f32) { } +pub fn foo50(_: f32, _: f32) {} // CHECK: define{{.*}}5foo50{{.*}}!type ![[TYPE50:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo51(_: f32, _: f32, _: f32) { } +pub fn foo51(_: f32, _: f32, _: f32) {} // CHECK: define{{.*}}5foo51{{.*}}!type ![[TYPE51:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo52(_: f64) { } +pub fn foo52(_: f64) {} // CHECK: define{{.*}}5foo52{{.*}}!type ![[TYPE52:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo53(_: f64, _: f64) { } +pub fn foo53(_: f64, _: f64) {} // CHECK: define{{.*}}5foo53{{.*}}!type ![[TYPE53:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo54(_: f64, _: f64, _: f64) { } +pub fn foo54(_: f64, _: f64, _: f64) {} // CHECK: define{{.*}}5foo54{{.*}}!type ![[TYPE54:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo55(_: char) { } +pub fn foo55(_: char) {} // CHECK: define{{.*}}5foo55{{.*}}!type ![[TYPE55:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo56(_: char, _: char) { } +pub fn foo56(_: char, _: char) {} // CHECK: define{{.*}}5foo56{{.*}}!type ![[TYPE56:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo57(_: char, _: char, _: char) { } +pub fn foo57(_: char, _: char, _: char) {} // CHECK: define{{.*}}5foo57{{.*}}!type ![[TYPE57:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo58(_: &str) { } +pub fn foo58(_: &str) {} // CHECK: define{{.*}}5foo58{{.*}}!type ![[TYPE58:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo59(_: &str, _: &str) { } +pub fn foo59(_: &str, _: &str) {} // CHECK: define{{.*}}5foo59{{.*}}!type ![[TYPE59:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo60(_: &str, _: &str, _: &str) { } +pub fn foo60(_: &str, _: &str, _: &str) {} // CHECK: define{{.*}}5foo60{{.*}}!type ![[TYPE60:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvvE"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs index 1332338b26ab..0f97c70f3f92 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs @@ -4,7 +4,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -#![crate_type="lib"] +#![crate_type = "lib"] extern crate core; use core::ffi::*; @@ -40,32 +40,31 @@ pub struct Type4(Type4Helper); #[repr(transparent)] pub struct Type4Helper(*mut T); -pub fn foo1(_: Type1) { } +pub fn foo1(_: Type1) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: Type1, _: Type1) { } +pub fn foo2(_: Type1, _: Type1) {} // CHECK: define{{.*}}4foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: Type1, _: Type1, _: Type1) { } +pub fn foo3(_: Type1, _: Type1, _: Type1) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo4(_: Type2) { } +pub fn foo4(_: Type2) {} // CHECK: define{{.*}}4foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo5(_: Type2, _: Type2) { } +pub fn foo5(_: Type2, _: Type2) {} // CHECK: define{{.*}}4foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo6(_: Type2, _: Type2, _: Type2) { } +pub fn foo6(_: Type2, _: Type2, _: Type2) {} // CHECK: define{{.*}}4foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo7(_: Type3) { } +pub fn foo7(_: Type3) {} // CHECK: define{{.*}}4foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo8(_: Type3, _: Type3) { } +pub fn foo8(_: Type3, _: Type3) {} // CHECK: define{{.*}}4foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo9(_: Type3, _: Type3, _: Type3) { } +pub fn foo9(_: Type3, _: Type3, _: Type3) {} // CHECK: define{{.*}}4foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo10(_: Type4) { } +pub fn foo10(_: Type4) {} // CHECK: define{{.*}}5foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo11(_: Type4, _: Type4) { } +pub fn foo11(_: Type4, _: Type4) {} // CHECK: define{{.*}}5foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo12(_: Type4, _: Type4, _: Type4) { } +pub fn foo12(_: Type4, _: Type4, _: Type4) {} // CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} - // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3FooE"} // CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3FooS_E"} // CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3FooS_S_E"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs index dd2e05dd2ec6..bdee3f47a837 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs @@ -4,25 +4,25 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -#![crate_type="lib"] +#![crate_type = "lib"] -pub fn foo1(_: (i32, i32)) { } +pub fn foo1(_: (i32, i32)) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: (i32, i32), _: (i32, i32)) { } +pub fn foo2(_: (i32, i32), _: (i32, i32)) {} // CHECK: define{{.*}}4foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: (i32, i32), _: (i32, i32), _: (i32, i32)) { } +pub fn foo3(_: (i32, i32), _: (i32, i32), _: (i32, i32)) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo4(_: [i32; 32]) { } +pub fn foo4(_: [i32; 32]) {} // CHECK: define{{.*}}4foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo5(_: [i32; 32], _: [i32; 32]) { } +pub fn foo5(_: [i32; 32], _: [i32; 32]) {} // CHECK: define{{.*}}4foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo6(_: [i32; 32], _: [i32; 32], _: [i32; 32]) { } +pub fn foo6(_: [i32; 32], _: [i32; 32], _: [i32; 32]) {} // CHECK: define{{.*}}4foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo7(_: &[i32]) { } +pub fn foo7(_: &[i32]) {} // CHECK: define{{.*}}4foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo8(_: &[i32], _: &[i32]) { } +pub fn foo8(_: &[i32], _: &[i32]) {} // CHECK: define{{.*}}4foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo9(_: &[i32], _: &[i32], _: &[i32]) { } +pub fn foo9(_: &[i32], _: &[i32], _: &[i32]) {} // CHECK: define{{.*}}4foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu5tupleIu3i32S_EE"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs index 6d9fe7040f70..55e816178f8f 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs @@ -4,7 +4,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -#![crate_type="lib"] +#![crate_type = "lib"] extern crate core; @@ -16,8 +16,7 @@ pub trait Trait1 { pub struct Type1; impl Trait1 for Type1 { - fn foo(&self) { - } + fn foo(&self) {} } pub trait Trait2 { @@ -27,8 +26,7 @@ pub trait Trait2 { pub struct Type2; impl Trait2 for Type2 { - fn bar(&self) { - } + fn bar(&self) {} } pub trait Trait3 { @@ -38,8 +36,7 @@ pub trait Trait3 { pub struct Type3; impl Trait3 for T { - fn baz(&self, _: &U) { - } + fn baz(&self, _: &U) {} } pub trait Trait4<'a, T> { @@ -64,71 +61,88 @@ pub trait Trait5 { pub struct Type5; impl Trait5 for T { - fn quux(&self, _: &[U; N]) { - } + fn quux(&self, _: &[U; N]) {} } -pub fn foo1(_: &dyn Send) { } +pub fn foo1(_: &dyn Send) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: &dyn Send, _: &dyn Send) { } +pub fn foo2(_: &dyn Send, _: &dyn Send) {} // CHECK: define{{.*}}4foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: &dyn Send, _: &dyn Send, _: &dyn Send) { } +pub fn foo3(_: &dyn Send, _: &dyn Send, _: &dyn Send) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo4(_: &(dyn Send + Sync)) { } +pub fn foo4(_: &(dyn Send + Sync)) {} // CHECK: define{{.*}}4foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo5(_: &(dyn Send + Sync), _: &(dyn Sync + Send)) { } +pub fn foo5(_: &(dyn Send + Sync), _: &(dyn Sync + Send)) {} // CHECK: define{{.*}}4foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo6(_: &(dyn Send + Sync), _: &(dyn Sync + Send), _: &(dyn Sync + Send)) { } +pub fn foo6(_: &(dyn Send + Sync), _: &(dyn Sync + Send), _: &(dyn Sync + Send)) {} // CHECK: define{{.*}}4foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo7(_: &(dyn Trait1 + Send)) { } +pub fn foo7(_: &(dyn Trait1 + Send)) {} // CHECK: define{{.*}}4foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo8(_: &(dyn Trait1 + Send), _: &(dyn Trait1 + Send)) { } +pub fn foo8(_: &(dyn Trait1 + Send), _: &(dyn Trait1 + Send)) {} // CHECK: define{{.*}}4foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo9(_: &(dyn Trait1 + Send), _: &(dyn Trait1 + Send), _: &(dyn Trait1 + Send)) { } +pub fn foo9(_: &(dyn Trait1 + Send), _: &(dyn Trait1 + Send), _: &(dyn Trait1 + Send)) {} // CHECK: define{{.*}}4foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo10(_: &(dyn Trait1 + Send + Sync)) { } +pub fn foo10(_: &(dyn Trait1 + Send + Sync)) {} // CHECK: define{{.*}}5foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo11(_: &(dyn Trait1 + Send + Sync), _: &(dyn Trait1 + Sync + Send)) { } +pub fn foo11(_: &(dyn Trait1 + Send + Sync), _: &(dyn Trait1 + Sync + Send)) {} // CHECK: define{{.*}}5foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo12(_: &(dyn Trait1 + Send + Sync), - _: &(dyn Trait1 + Sync + Send), - _: &(dyn Trait1 + Sync + Send)) { } +pub fn foo12( + _: &(dyn Trait1 + Send + Sync), + _: &(dyn Trait1 + Sync + Send), + _: &(dyn Trait1 + Sync + Send), +) { +} // CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo13(_: &dyn Trait1) { } +pub fn foo13(_: &dyn Trait1) {} // CHECK: define{{.*}}5foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo14(_: &dyn Trait1, _: &dyn Trait1) { } +pub fn foo14(_: &dyn Trait1, _: &dyn Trait1) {} // CHECK: define{{.*}}5foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo15(_: &dyn Trait1, _: &dyn Trait1, _: &dyn Trait1) { } +pub fn foo15(_: &dyn Trait1, _: &dyn Trait1, _: &dyn Trait1) {} // CHECK: define{{.*}}5foo15{{.*}}!type ![[TYPE15:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo16(_: &dyn Trait2) { } -pub fn bar16() { let a = Type2; foo16(&a); } +pub fn foo16(_: &dyn Trait2) {} +pub fn bar16() { + let a = Type2; + foo16(&a); +} // CHECK: define{{.*}}5foo16{{.*}}!type ![[TYPE16:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo17(_: &dyn Trait2, _: &dyn Trait2) { } -pub fn bar17() { let a = Type2; foo17(&a, &a); } +pub fn foo17(_: &dyn Trait2, _: &dyn Trait2) {} +pub fn bar17() { + let a = Type2; + foo17(&a, &a); +} // CHECK: define{{.*}}5foo17{{.*}}!type ![[TYPE17:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo18(_: &dyn Trait2, _: &dyn Trait2, _: &dyn Trait2) { } -pub fn bar18() { let a = Type2; foo18(&a, &a, &a); } +pub fn foo18(_: &dyn Trait2, _: &dyn Trait2, _: &dyn Trait2) {} +pub fn bar18() { + let a = Type2; + foo18(&a, &a, &a); +} // CHECK: define{{.*}}5foo18{{.*}}!type ![[TYPE18:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo19(_: &dyn Trait3) { } +pub fn foo19(_: &dyn Trait3) {} // CHECK: define{{.*}}5foo19{{.*}}!type ![[TYPE19:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo20(_: &dyn Trait3, _: &dyn Trait3) { } +pub fn foo20(_: &dyn Trait3, _: &dyn Trait3) {} // CHECK: define{{.*}}5foo20{{.*}}!type ![[TYPE20:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo21(_: &dyn Trait3, _: &dyn Trait3, _: &dyn Trait3) { } +pub fn foo21(_: &dyn Trait3, _: &dyn Trait3, _: &dyn Trait3) {} // CHECK: define{{.*}}5foo21{{.*}}!type ![[TYPE21:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo22<'a>(_: &dyn Trait4<'a, Type4, Output = &'a i32>) { } +pub fn foo22<'a>(_: &dyn Trait4<'a, Type4, Output = &'a i32>) {} // CHECK: define{{.*}}5foo22{{.*}}!type ![[TYPE22:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo23<'a>(_: &dyn Trait4<'a, Type4, Output = &'a i32>, - _: &dyn Trait4<'a, Type4, Output = &'a i32>) { } +pub fn foo23<'a>( + _: &dyn Trait4<'a, Type4, Output = &'a i32>, + _: &dyn Trait4<'a, Type4, Output = &'a i32>, +) { +} // CHECK: define{{.*}}5foo23{{.*}}!type ![[TYPE23:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo24<'a>(_: &dyn Trait4<'a, Type4, Output = &'a i32>, - _: &dyn Trait4<'a, Type4, Output = &'a i32>, - _: &dyn Trait4<'a, Type4, Output = &'a i32>) { } +pub fn foo24<'a>( + _: &dyn Trait4<'a, Type4, Output = &'a i32>, + _: &dyn Trait4<'a, Type4, Output = &'a i32>, + _: &dyn Trait4<'a, Type4, Output = &'a i32>, +) { +} // CHECK: define{{.*}}5foo24{{.*}}!type ![[TYPE24:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo25(_: &dyn Trait5) { } +pub fn foo25(_: &dyn Trait5) {} // CHECK: define{{.*}}5foo25{{.*}}!type ![[TYPE25:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo26(_: &dyn Trait5, _: &dyn Trait5) { } +pub fn foo26(_: &dyn Trait5, _: &dyn Trait5) {} // CHECK: define{{.*}}5foo26{{.*}}!type ![[TYPE26:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo27(_: &dyn Trait5, _: &dyn Trait5, _: &dyn Trait5) { } +pub fn foo27(_: &dyn Trait5, _: &dyn Trait5, _: &dyn Trait5) {} // CHECK: define{{.*}}5foo27{{.*}}!type ![[TYPE27:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: ![[TYPE13]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait1u6regionEEE"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs index 4eaf42bf87d1..c1f3ca61afeb 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs @@ -4,7 +4,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(extern_types)] pub struct Struct1 { @@ -19,33 +19,33 @@ pub union Union1 { member1: std::mem::ManuallyDrop, } -extern { +extern "C" { pub type type1; } -pub fn foo1(_: &Struct1::) { } +pub fn foo1(_: &Struct1) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: &Struct1::, _: &Struct1::) { } +pub fn foo2(_: &Struct1, _: &Struct1) {} // CHECK: define{{.*}}4foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: &Struct1::, _: &Struct1::, _: &Struct1::) { } +pub fn foo3(_: &Struct1, _: &Struct1, _: &Struct1) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo4(_: &Enum1::) { } +pub fn foo4(_: &Enum1) {} // CHECK: define{{.*}}4foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo5(_: &Enum1::, _: &Enum1::) { } +pub fn foo5(_: &Enum1, _: &Enum1) {} // CHECK: define{{.*}}4foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo6(_: &Enum1::, _: &Enum1::, _: &Enum1::) { } +pub fn foo6(_: &Enum1, _: &Enum1, _: &Enum1) {} // CHECK: define{{.*}}4foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo7(_: &Union1::) { } +pub fn foo7(_: &Union1) {} // CHECK: define{{.*}}4foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo8(_: &Union1::, _: &Union1::) { } +pub fn foo8(_: &Union1, _: &Union1) {} // CHECK: define{{.*}}4foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo9(_: &Union1::, _: &Union1::, _: &Union1::) { } +pub fn foo9(_: &Union1, _: &Union1, _: &Union1) {} // CHECK: define{{.*}}4foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo10(_: *mut type1) { } +pub fn foo10(_: *mut type1) {} // CHECK: define{{.*}}5foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo11(_: *mut type1, _: *mut type1) { } +pub fn foo11(_: *mut type1, _: *mut type1) {} // CHECK: define{{.*}}5foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo12(_: *mut type1, _: *mut type1, _: *mut type1) { } +pub fn foo12(_: *mut type1, _: *mut type1, _: *mut type1) {} // CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}7Struct1Iu3i32EEE"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs index ccd7ee93ca1f..32637b64b3ea 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs @@ -3,7 +3,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers -#![crate_type="lib"] +#![crate_type = "lib"] pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs index d41300341780..51121b0aef1a 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs @@ -3,7 +3,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers -#![crate_type="lib"] +#![crate_type = "lib"] pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs index ac18379165de..1cfdd23006e3 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs @@ -3,7 +3,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -#![crate_type="lib"] +#![crate_type = "lib"] pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs index 526ba62c264d..56ab1ce4b358 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs @@ -3,7 +3,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -#![crate_type="lib"] +#![crate_type = "lib"] pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-trait-objects.rs index 318aad9291c4..0e57ce322d12 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-trait-objects.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-trait-objects.rs @@ -3,7 +3,7 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Ctarget-feature=-crt-static -Zsanitizer=cfi -#![crate_type="lib"] +#![crate_type = "lib"] pub trait Trait1 { fn foo(&self); @@ -13,8 +13,7 @@ pub trait Trait1 { pub struct Type1; impl Trait1 for Type1 { - fn foo(&self) { - } + fn foo(&self) {} } pub trait Trait2 { @@ -24,8 +23,7 @@ pub trait Trait2 { pub struct Type2; impl Trait2 for Type2 { - fn bar(&self) { - } + fn bar(&self) {} } pub trait Trait3 { @@ -35,8 +33,7 @@ pub trait Trait3 { pub struct Type3; impl Trait3 for T { - fn baz(&self, _: &U) { - } + fn baz(&self, _: &U) {} } pub trait Trait4<'a, T> { @@ -61,8 +58,7 @@ pub trait Trait5 { pub struct Type5; impl Trait5 for T { - fn quux(&self, _: &[U; N]) { - } + fn quux(&self, _: &[U; N]) {} } pub fn foo1(a: &dyn Trait1) { diff --git a/tests/codegen/sanitizer/cfi/generalize-pointers.rs b/tests/codegen/sanitizer/cfi/generalize-pointers.rs index eaf3dad19092..57004da6f8e0 100644 --- a/tests/codegen/sanitizer/cfi/generalize-pointers.rs +++ b/tests/codegen/sanitizer/cfi/generalize-pointers.rs @@ -3,33 +3,33 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] extern crate core; -pub fn foo0(_: &mut i32) { } +pub fn foo0(_: &mut i32) {} // CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo1(_: &mut i32, _: &mut i32) { } +pub fn foo1(_: &mut i32, _: &mut i32) {} // CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: &mut i32, _: &mut i32, _: &mut i32) { } +pub fn foo2(_: &mut i32, _: &mut i32, _: &mut i32) {} // CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: &i32) { } +pub fn foo3(_: &i32) {} // CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo4(_: &i32, _: &i32) { } +pub fn foo4(_: &i32, _: &i32) {} // CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo5(_: &i32, _: &i32, _: &i32) { } +pub fn foo5(_: &i32, _: &i32, _: &i32) {} // CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo6(_: *mut i32) { } +pub fn foo6(_: *mut i32) {} // CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo7(_: *mut i32, _: *mut i32) { } +pub fn foo7(_: *mut i32, _: *mut i32) {} // CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo8(_: *mut i32, _: *mut i32, _: *mut i32) { } +pub fn foo8(_: *mut i32, _: *mut i32, _: *mut i32) {} // CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo9(_: *const i32) { } +pub fn foo9(_: *const i32) {} // CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo10(_: *const i32, _: *const i32) { } +pub fn foo10(_: *const i32, _: *const i32) {} // CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo11(_: *const i32, _: *const i32, _: *const i32) { } +pub fn foo11(_: *const i32, _: *const i32, _: *const i32) {} // CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} // CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvU3mutu3refIvEE.generalized"} diff --git a/tests/codegen/sanitizer/cfi/normalize-integers.rs b/tests/codegen/sanitizer/cfi/normalize-integers.rs index 801ed312be5b..770ee4e64e08 100644 --- a/tests/codegen/sanitizer/cfi/normalize-integers.rs +++ b/tests/codegen/sanitizer/cfi/normalize-integers.rs @@ -3,33 +3,33 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] extern crate core; -pub fn foo0(_: bool) { } +pub fn foo0(_: bool) {} // CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} -pub fn foo1(_: bool, _: bool) { } +pub fn foo1(_: bool, _: bool) {} // CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} -pub fn foo2(_: bool, _: bool, _: bool) { } +pub fn foo2(_: bool, _: bool, _: bool) {} // CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} -pub fn foo3(_: char) { } +pub fn foo3(_: char) {} // CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} -pub fn foo4(_: char, _: char) { } +pub fn foo4(_: char, _: char) {} // CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} -pub fn foo5(_: char, _: char, _: char) { } +pub fn foo5(_: char, _: char, _: char) {} // CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} -pub fn foo6(_: isize) { } +pub fn foo6(_: isize) {} // CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} -pub fn foo7(_: isize, _: isize) { } +pub fn foo7(_: isize, _: isize) {} // CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} -pub fn foo8(_: isize, _: isize, _: isize) { } +pub fn foo8(_: isize, _: isize, _: isize) {} // CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} -pub fn foo9(_: (), _: usize) { } +pub fn foo9(_: (), _: usize) {} // CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} -pub fn foo10(_: (), _: usize, _: usize) { } +pub fn foo10(_: (), _: usize, _: usize) {} // CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} -pub fn foo11(_: (), _: usize, _: usize, _: usize) { } +pub fn foo11(_: (), _: usize, _: usize, _: usize) {} // CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} // CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvu2u8E.normalized"} diff --git a/tests/codegen/sanitizer/dataflow-instrument-functions.rs b/tests/codegen/sanitizer/dataflow-instrument-functions.rs index 69c3560882c1..a2d0d63cc175 100644 --- a/tests/codegen/sanitizer/dataflow-instrument-functions.rs +++ b/tests/codegen/sanitizer/dataflow-instrument-functions.rs @@ -3,8 +3,7 @@ //@ needs-sanitizer-dataflow //@ compile-flags: -Copt-level=0 -Zsanitizer=dataflow -#![crate_type="lib"] +#![crate_type = "lib"] -pub fn foo() { -} +pub fn foo() {} // CHECK: define{{.*}}foo{{.*}}.dfsan diff --git a/tests/codegen/sanitizer/kcfi/add-kcfi-flag.rs b/tests/codegen/sanitizer/kcfi/add-kcfi-flag.rs index 7751d3baf79a..013de74f8d68 100644 --- a/tests/codegen/sanitizer/kcfi/add-kcfi-flag.rs +++ b/tests/codegen/sanitizer/kcfi/add-kcfi-flag.rs @@ -8,15 +8,14 @@ //@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi #![feature(no_core, lang_items)] -#![crate_type="lib"] +#![crate_type = "lib"] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} -pub fn foo() { -} +pub fn foo() {} // CHECK: !{{[0-9]+}} = !{i32 4, !"kcfi", i32 1} diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs index 8055c63a2f8f..ba2e397f6daa 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs @@ -7,14 +7,14 @@ //@ [x86_64] needs-llvm-components: //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(no_core, no_sanitize, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} impl Copy for i32 {} diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs index bd1dfc4c413e..4e95bdf4d7c4 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs @@ -7,14 +7,14 @@ //@ [x86_64] needs-llvm-components: //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-generalize-pointers -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} impl Copy for i32 {} diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs index b8275f44fac5..31b43b509880 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs @@ -7,14 +7,14 @@ //@ [x86_64] needs-llvm-components: //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} impl Copy for i32 {} diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs index cd1b0c5efb0a..4755f6062aaa 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs @@ -7,14 +7,14 @@ //@ [x86_64] needs-llvm-components: //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} impl Copy for i32 {} diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs index 12690577da7a..be9760bd9afa 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs @@ -7,14 +7,14 @@ //@ [x86_64] needs-llvm-components: //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} impl Copy for i32 {} diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle.rs index f4b3e48638e4..c9c94cdb3292 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle.rs @@ -7,14 +7,14 @@ //@ [x86_64] needs-llvm-components: //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} impl Copy for i32 {} diff --git a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs index f9c7cca39898..fc4d570dc2eb 100644 --- a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs +++ b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs @@ -7,30 +7,32 @@ //@ [x86_64] needs-llvm-components: //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(arbitrary_self_types, no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } -#[lang="receiver"] -trait Receiver { } -#[lang="dispatch_from_dyn"] -trait DispatchFromDyn { } +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} +#[lang = "receiver"] +trait Receiver {} +#[lang = "dispatch_from_dyn"] +trait DispatchFromDyn {} impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} #[lang = "unsize"] -trait Unsize { } +trait Unsize {} #[lang = "coerce_unsized"] -pub trait CoerceUnsized { } +pub trait CoerceUnsized {} impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -#[lang="freeze"] -trait Freeze { } -#[lang="drop_in_place"] -fn drop_in_place_fn() { } -#[lang="drop"] -trait Drop { fn drop(&mut self); } +#[lang = "freeze"] +trait Freeze {} +#[lang = "drop_in_place"] +fn drop_in_place_fn() {} +#[lang = "drop"] +trait Drop { + fn drop(&mut self); +} pub trait Trait1 { fn foo(&self); @@ -39,8 +41,7 @@ pub trait Trait1 { pub struct Type1; impl Trait1 for Type1 { - fn foo(&self) { - } + fn foo(&self) {} } pub trait Trait2 { @@ -50,8 +51,7 @@ pub trait Trait2 { pub struct Type2; impl Trait2 for Type2 { - fn bar(&self) { - } + fn bar(&self) {} } pub trait Trait3 { @@ -61,8 +61,7 @@ pub trait Trait3 { pub struct Type3; impl Trait3 for T { - fn baz(&self, _: &U) { - } + fn baz(&self, _: &U) {} } pub trait Trait4<'a, T> { @@ -88,8 +87,7 @@ pub struct Type5; impl Copy for Type5 {} impl Trait5 for T { - fn quux(&self, _: &[U; N]) { - } + fn quux(&self, _: &[U; N]) {} } pub fn foo1(a: &dyn Trait1) { diff --git a/tests/codegen/sanitizer/memory-track-origins.rs b/tests/codegen/sanitizer/memory-track-origins.rs index 956053ec42c7..318c277e10cb 100644 --- a/tests/codegen/sanitizer/memory-track-origins.rs +++ b/tests/codegen/sanitizer/memory-track-origins.rs @@ -11,7 +11,7 @@ //@[MSAN-1-LTO] compile-flags: -Zsanitizer-memory-track-origins=1 -C lto=fat //@[MSAN-2-LTO] compile-flags: -Zsanitizer-memory-track-origins -C lto=fat -#![crate_type="lib"] +#![crate_type = "lib"] // MSAN-0-NOT: @__msan_track_origins // MSAN-1: @__msan_track_origins = weak_odr {{.*}}constant i32 1 diff --git a/tests/codegen/sanitizer/no-sanitize-inlining.rs b/tests/codegen/sanitizer/no-sanitize-inlining.rs index d5e47884f858..4bd832d2ab19 100644 --- a/tests/codegen/sanitizer/no-sanitize-inlining.rs +++ b/tests/codegen/sanitizer/no-sanitize-inlining.rs @@ -8,7 +8,7 @@ //@[ASAN] compile-flags: -Zsanitizer=address //@[LSAN] compile-flags: -Zsanitizer=leak -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(no_sanitize)] // ASAN-LABEL: define void @test diff --git a/tests/codegen/sanitizer/no-sanitize.rs b/tests/codegen/sanitizer/no-sanitize.rs index 2614416210ff..47d3fd83f112 100644 --- a/tests/codegen/sanitizer/no-sanitize.rs +++ b/tests/codegen/sanitizer/no-sanitize.rs @@ -4,7 +4,7 @@ //@ needs-sanitizer-address //@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static -Copt-level=0 -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(no_sanitize)] // CHECK-LABEL: ; no_sanitize::unsanitized diff --git a/tests/codegen/set-discriminant-invalid.rs b/tests/codegen/set-discriminant-invalid.rs index 593da8cf80d0..0b7cb14880c9 100644 --- a/tests/codegen/set-discriminant-invalid.rs +++ b/tests/codegen/set-discriminant-invalid.rs @@ -7,17 +7,12 @@ pub struct TokioError { b: bool, } pub enum Error { - Api { - source: ApiError, - }, + Api { source: ApiError }, Ethereum, - Tokio { - source: TokioError, - }, + Tokio { source: TokioError }, } struct Api; -impl IntoError for Api -{ +impl IntoError for Api { type Source = ApiError; // CHECK-LABEL: @into_error // CHECK: llvm.trap() @@ -27,14 +22,11 @@ impl IntoError for Api // CHECK-NEXT: ret #[no_mangle] fn into_error(self, error: Self::Source) -> Error { - Error::Api { - source: error, - } + Error::Api { source: error } } } -pub trait IntoError -{ +pub trait IntoError { /// The underlying error type Source; diff --git a/tests/codegen/simd/issue-120720-reduce-nan.rs b/tests/codegen/simd/issue-120720-reduce-nan.rs index 0372582bf7f3..13af0bb076e6 100644 --- a/tests/codegen/simd/issue-120720-reduce-nan.rs +++ b/tests/codegen/simd/issue-120720-reduce-nan.rs @@ -15,8 +15,7 @@ pub unsafe fn demo() -> bool { // CHECK: %0 = tail call reassoc double @llvm.vector.reduce.fadd.v8f64( // CHECK: %_0.i = fcmp uno double %0, 0.000000e+00 // CHECK: ret i1 %_0.i - let res = unsafe { - _mm512_reduce_add_pd(_mm512_set_pd(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, f64::NAN)) - }; + let res = + unsafe { _mm512_reduce_add_pd(_mm512_set_pd(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, f64::NAN)) }; res.is_nan() } diff --git a/tests/codegen/simd/packed-simd-alignment.rs b/tests/codegen/simd/packed-simd-alignment.rs new file mode 100644 index 000000000000..53e88d8e5cf1 --- /dev/null +++ b/tests/codegen/simd/packed-simd-alignment.rs @@ -0,0 +1,44 @@ +//@ compile-flags: -Cno-prepopulate-passes + +#![crate_type = "lib"] +#![feature(repr_simd, core_intrinsics)] +// make sure that codegen emits correctly-aligned loads and stores for repr(packed, simd) types +// the alignment of a load should be no less than T, and no more than the size of the vector type +use std::intrinsics::simd as intrinsics; + +#[derive(Copy, Clone)] +#[repr(packed, simd)] +struct f32x3([f32; 3]); + +#[derive(Copy, Clone)] +#[repr(packed, simd)] +struct f32x4([f32; 4]); + +// CHECK-LABEL: load_f32x3 +#[no_mangle] +pub fn load_f32x3(floats: &f32x3) -> f32x3 { + // FIXME: Is a memcpy really the best we can do? + // CHECK: @llvm.memcpy.{{.*}}ptr align 4 {{.*}}ptr align 4 + *floats +} + +// CHECK-LABEL: load_f32x4 +#[no_mangle] +pub fn load_f32x4(floats: &f32x4) -> f32x4 { + // CHECK: load <4 x float>, ptr %{{[a-z0-9_]*}}, align {{4|8|16}} + *floats +} + +// CHECK-LABEL: add_f32x3 +#[no_mangle] +pub fn add_f32x3(x: f32x3, y: f32x3) -> f32x3 { + // CHECK: load <3 x float>, ptr %{{[a-z0-9_]*}}, align 4 + unsafe { intrinsics::simd_add(x, y) } +} + +// CHECK-LABEL: add_f32x4 +#[no_mangle] +pub fn add_f32x4(x: f32x4, y: f32x4) -> f32x4 { + // CHECK: load <4 x float>, ptr %{{[a-z0-9_]*}}, align {{4|8|16}} + unsafe { intrinsics::simd_add(x, y) } +} diff --git a/tests/codegen/simd/packed-simd.rs b/tests/codegen/simd/packed-simd.rs new file mode 100644 index 000000000000..f0911b6e3602 --- /dev/null +++ b/tests/codegen/simd/packed-simd.rs @@ -0,0 +1,44 @@ +//@ revisions:opt3 noopt +//@[opt3] compile-flags: -Copt-level=3 +//@[noopt] compile-flags: -Cno-prepopulate-passes + +#![crate_type = "lib"] +#![no_std] +#![feature(repr_simd, core_intrinsics)] +use core::intrinsics::simd as intrinsics; +use core::{mem, ptr}; + +// Test codegen for not only "packed" but also "fully aligned" SIMD types, and conversion between +// A repr(packed,simd) type with 3 elements can't exceed its element alignment, +// whereas the same type as repr(simd) will instead have padding. + +#[repr(simd, packed)] +pub struct Simd([T; N]); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct FullSimd([T; N]); + +// non-powers-of-two have padding and need to be expanded to full vectors +fn load(v: Simd) -> FullSimd { + unsafe { + let mut tmp = mem::MaybeUninit::>::uninit(); + ptr::copy_nonoverlapping(&v as *const _, tmp.as_mut_ptr().cast(), 1); + tmp.assume_init() + } +} + +// CHECK-LABEL: square_packed +// CHECK-SAME: ptr{{[a-z_ ]*}} sret([[RET_TYPE:[^)]+]]) [[RET_ALIGN:align (8|16)]]{{[^%]*}} [[RET_VREG:%[_0-9]*]] +// CHECK-SAME: ptr{{[a-z_ ]*}} align 4 +#[no_mangle] +pub fn square_packed(x: Simd) -> FullSimd { + // CHECK-NEXT: start + // noopt: alloca [[RET_TYPE]], [[RET_ALIGN]] + // CHECK: load <3 x float> + let x = load(x); + // CHECK: [[VREG:%[a-z0-9_]+]] = fmul <3 x float> + // CHECK-NEXT: store <3 x float> [[VREG]], ptr [[RET_VREG]], [[RET_ALIGN]] + // CHECK-NEXT: ret void + unsafe { intrinsics::simd_mul(x, x) } +} diff --git a/tests/codegen/simd/swap-simd-types.rs b/tests/codegen/simd/swap-simd-types.rs index 32e75220d696..cd6e84286e1c 100644 --- a/tests/codegen/simd/swap-simd-types.rs +++ b/tests/codegen/simd/swap-simd-types.rs @@ -13,18 +13,18 @@ use core::arch::x86_64::__m256; // CHECK-LABEL: @swap_single_m256 #[no_mangle] pub fn swap_single_m256(x: &mut __m256, y: &mut __m256) { -// CHECK-NOT: alloca -// CHECK: load <8 x float>{{.+}}align 32 -// CHECK: store <8 x float>{{.+}}align 32 + // CHECK-NOT: alloca + // CHECK: load <8 x float>{{.+}}align 32 + // CHECK: store <8 x float>{{.+}}align 32 swap(x, y) } // CHECK-LABEL: @swap_m256_slice #[no_mangle] pub fn swap_m256_slice(x: &mut [__m256], y: &mut [__m256]) { -// CHECK-NOT: alloca -// CHECK: load <8 x float>{{.+}}align 32 -// CHECK: store <8 x float>{{.+}}align 32 + // CHECK-NOT: alloca + // CHECK: load <8 x float>{{.+}}align 32 + // CHECK: store <8 x float>{{.+}}align 32 if x.len() == y.len() { x.swap_with_slice(y); } @@ -33,8 +33,8 @@ pub fn swap_m256_slice(x: &mut [__m256], y: &mut [__m256]) { // CHECK-LABEL: @swap_bytes32 #[no_mangle] pub fn swap_bytes32(x: &mut [u8; 32], y: &mut [u8; 32]) { -// CHECK-NOT: alloca -// CHECK: load <32 x i8>{{.+}}align 1 -// CHECK: store <32 x i8>{{.+}}align 1 + // CHECK-NOT: alloca + // CHECK: load <32 x i8>{{.+}}align 1 + // CHECK: store <32 x i8>{{.+}}align 1 swap(x, y) } diff --git a/tests/codegen/slice-position-bounds-check.rs b/tests/codegen/slice-position-bounds-check.rs index 301895883ee3..f83e2f2ec440 100644 --- a/tests/codegen/slice-position-bounds-check.rs +++ b/tests/codegen/slice-position-bounds-check.rs @@ -3,9 +3,7 @@ fn search(arr: &mut [T], a: &T) -> Result { match arr.iter().position(|x| x == a) { - Some(p) => { - Ok(p) - }, + Some(p) => Ok(p), None => Err(()), } } @@ -15,11 +13,7 @@ fn search(arr: &mut [T], a: &T) -> Result { pub fn position_no_bounds_check(y: &mut [u32], x: &u32, z: &u32) -> bool { // This contains "call assume" so we cannot just rule out all calls // CHECK-NOT: panic_bounds_check - if let Ok(p) = search(y, x) { - y[p] == *z - } else { - false - } + if let Ok(p) = search(y, x) { y[p] == *z } else { false } } // just to make sure that panicking really emits "panic_bounds_check" somewhere in the IR diff --git a/tests/codegen/slice-windows-no-bounds-check.rs b/tests/codegen/slice-windows-no-bounds-check.rs index 188011ebe7fd..db3211c8defd 100644 --- a/tests/codegen/slice-windows-no-bounds-check.rs +++ b/tests/codegen/slice-windows-no-bounds-check.rs @@ -12,10 +12,7 @@ pub fn naive_string_search(haystack: &str, needle: &str) -> Option { } // CHECK-NOT: panic // CHECK-NOT: fail - haystack - .as_bytes() - .windows(needle.len()) - .position(|sub| sub == needle.as_bytes()) + haystack.as_bytes().windows(needle.len()).position(|sub| sub == needle.as_bytes()) } // CHECK-LABEL: @next diff --git a/tests/codegen/some-abis-do-extend-params-to-32-bits.rs b/tests/codegen/some-abis-do-extend-params-to-32-bits.rs index a75a239e2ab8..10970cacdcf0 100644 --- a/tests/codegen/some-abis-do-extend-params-to-32-bits.rs +++ b/tests/codegen/some-abis-do-extend-params-to-32-bits.rs @@ -24,9 +24,12 @@ #![no_std] #![no_core] -#[lang="sized"] trait Sized { } -#[lang="freeze"] trait Freeze { } -#[lang="copy"] trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} // The patterns in this file are written in the style of a table to make the // uniformities and distinctions more apparent. @@ -40,7 +43,8 @@ // aarch64-linux: void @c_arg_u8(i8 %_a) // arm: void @c_arg_u8(i8 zeroext %_a) // riscv: void @c_arg_u8(i8 zeroext %_a) -#[no_mangle] pub extern "C" fn c_arg_u8(_a: u8) { } +#[no_mangle] +pub extern "C" fn c_arg_u8(_a: u8) {} // x86_64: void @c_arg_u16(i16 zeroext %_a) // i686: void @c_arg_u16(i16 zeroext %_a) @@ -49,7 +53,8 @@ // aarch64-linux: void @c_arg_u16(i16 %_a) // arm: void @c_arg_u16(i16 zeroext %_a) // riscv: void @c_arg_u16(i16 zeroext %_a) -#[no_mangle] pub extern "C" fn c_arg_u16(_a: u16) { } +#[no_mangle] +pub extern "C" fn c_arg_u16(_a: u16) {} // x86_64: void @c_arg_u32(i32 %_a) // i686: void @c_arg_u32(i32 %_a) @@ -58,7 +63,8 @@ // aarch64-linux: void @c_arg_u32(i32 %_a) // arm: void @c_arg_u32(i32 %_a) // riscv: void @c_arg_u32(i32 signext %_a) -#[no_mangle] pub extern "C" fn c_arg_u32(_a: u32) { } +#[no_mangle] +pub extern "C" fn c_arg_u32(_a: u32) {} // x86_64: void @c_arg_u64(i64 %_a) // i686: void @c_arg_u64(i64 %_a) @@ -67,7 +73,8 @@ // aarch64-linux: void @c_arg_u64(i64 %_a) // arm: void @c_arg_u64(i64 %_a) // riscv: void @c_arg_u64(i64 %_a) -#[no_mangle] pub extern "C" fn c_arg_u64(_a: u64) { } +#[no_mangle] +pub extern "C" fn c_arg_u64(_a: u64) {} // x86_64: void @c_arg_i8(i8 signext %_a) // i686: void @c_arg_i8(i8 signext %_a) @@ -76,7 +83,8 @@ // aarch64-linux: void @c_arg_i8(i8 %_a) // arm: void @c_arg_i8(i8 signext %_a) // riscv: void @c_arg_i8(i8 signext %_a) -#[no_mangle] pub extern "C" fn c_arg_i8(_a: i8) { } +#[no_mangle] +pub extern "C" fn c_arg_i8(_a: i8) {} // x86_64: void @c_arg_i16(i16 signext %_a) // i686: void @c_arg_i16(i16 signext %_a) @@ -85,7 +93,8 @@ // aarch64-linux: void @c_arg_i16(i16 %_a) // arm: void @c_arg_i16(i16 signext %_a) // riscv: void @c_arg_i16(i16 signext %_a) -#[no_mangle] pub extern "C" fn c_arg_i16(_a: i16) { } +#[no_mangle] +pub extern "C" fn c_arg_i16(_a: i16) {} // x86_64: void @c_arg_i32(i32 %_a) // i686: void @c_arg_i32(i32 %_a) @@ -94,7 +103,8 @@ // aarch64-linux: void @c_arg_i32(i32 %_a) // arm: void @c_arg_i32(i32 %_a) // riscv: void @c_arg_i32(i32 signext %_a) -#[no_mangle] pub extern "C" fn c_arg_i32(_a: i32) { } +#[no_mangle] +pub extern "C" fn c_arg_i32(_a: i32) {} // x86_64: void @c_arg_i64(i64 %_a) // i686: void @c_arg_i64(i64 %_a) @@ -103,7 +113,8 @@ // aarch64-linux: void @c_arg_i64(i64 %_a) // arm: void @c_arg_i64(i64 %_a) // riscv: void @c_arg_i64(i64 %_a) -#[no_mangle] pub extern "C" fn c_arg_i64(_a: i64) { } +#[no_mangle] +pub extern "C" fn c_arg_i64(_a: i64) {} // x86_64: zeroext i8 @c_ret_u8() // i686: zeroext i8 @c_ret_u8() @@ -112,7 +123,10 @@ // aarch64-linux: i8 @c_ret_u8() // arm: zeroext i8 @c_ret_u8() // riscv: zeroext i8 @c_ret_u8() -#[no_mangle] pub extern "C" fn c_ret_u8() -> u8 { 0 } +#[no_mangle] +pub extern "C" fn c_ret_u8() -> u8 { + 0 +} // x86_64: zeroext i16 @c_ret_u16() // i686: zeroext i16 @c_ret_u16() @@ -121,7 +135,10 @@ // aarch64-linux: i16 @c_ret_u16() // arm: zeroext i16 @c_ret_u16() // riscv: zeroext i16 @c_ret_u16() -#[no_mangle] pub extern "C" fn c_ret_u16() -> u16 { 0 } +#[no_mangle] +pub extern "C" fn c_ret_u16() -> u16 { + 0 +} // x86_64: i32 @c_ret_u32() // i686: i32 @c_ret_u32() @@ -130,7 +147,10 @@ // aarch64-linux: i32 @c_ret_u32() // arm: i32 @c_ret_u32() // riscv: signext i32 @c_ret_u32() -#[no_mangle] pub extern "C" fn c_ret_u32() -> u32 { 0 } +#[no_mangle] +pub extern "C" fn c_ret_u32() -> u32 { + 0 +} // x86_64: i64 @c_ret_u64() // i686: i64 @c_ret_u64() @@ -139,7 +159,10 @@ // aarch64-linux: i64 @c_ret_u64() // arm: i64 @c_ret_u64() // riscv: i64 @c_ret_u64() -#[no_mangle] pub extern "C" fn c_ret_u64() -> u64 { 0 } +#[no_mangle] +pub extern "C" fn c_ret_u64() -> u64 { + 0 +} // x86_64: signext i8 @c_ret_i8() // i686: signext i8 @c_ret_i8() @@ -148,7 +171,10 @@ // aarch64-linux: i8 @c_ret_i8() // arm: signext i8 @c_ret_i8() // riscv: signext i8 @c_ret_i8() -#[no_mangle] pub extern "C" fn c_ret_i8() -> i8 { 0 } +#[no_mangle] +pub extern "C" fn c_ret_i8() -> i8 { + 0 +} // x86_64: signext i16 @c_ret_i16() // i686: signext i16 @c_ret_i16() @@ -157,7 +183,10 @@ // aarch64-linux: i16 @c_ret_i16() // arm: signext i16 @c_ret_i16() // riscv: signext i16 @c_ret_i16() -#[no_mangle] pub extern "C" fn c_ret_i16() -> i16 { 0 } +#[no_mangle] +pub extern "C" fn c_ret_i16() -> i16 { + 0 +} // x86_64: i32 @c_ret_i32() // i686: i32 @c_ret_i32() @@ -166,7 +195,10 @@ // aarch64-linux: i32 @c_ret_i32() // arm: i32 @c_ret_i32() // riscv: signext i32 @c_ret_i32() -#[no_mangle] pub extern "C" fn c_ret_i32() -> i32 { 0 } +#[no_mangle] +pub extern "C" fn c_ret_i32() -> i32 { + 0 +} // x86_64: i64 @c_ret_i64() // i686: i64 @c_ret_i64() @@ -175,7 +207,10 @@ // aarch64-linux: i64 @c_ret_i64() // arm: i64 @c_ret_i64() // riscv: i64 @c_ret_i64() -#[no_mangle] pub extern "C" fn c_ret_i64() -> i64 { 0 } +#[no_mangle] +pub extern "C" fn c_ret_i64() -> i64 { + 0 +} const C_SOURCE_FILE: &'static str = r##" #include diff --git a/tests/codegen/sparc-struct-abi.rs b/tests/codegen/sparc-struct-abi.rs index 0850e9e15eaf..5d9781663570 100644 --- a/tests/codegen/sparc-struct-abi.rs +++ b/tests/codegen/sparc-struct-abi.rs @@ -6,12 +6,12 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="freeze"] -trait Freeze { } -#[lang="copy"] -trait Copy { } +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} #[repr(C)] pub struct Bool { @@ -26,7 +26,6 @@ pub extern "C" fn structbool() -> Bool { Bool { b: true } } - #[repr(C)] pub struct BoolFloat { b: bool, @@ -44,8 +43,7 @@ pub extern "C" fn structboolfloat() -> BoolFloat { // CHECK: define void @structboolfloat_input({ i32, float } inreg %0) // CHECK-NEXT: start: #[no_mangle] -pub extern "C" fn structboolfloat_input(a: BoolFloat) { } - +pub extern "C" fn structboolfloat_input(a: BoolFloat) {} #[repr(C)] pub struct ShortDouble { @@ -64,8 +62,7 @@ pub extern "C" fn structshortdouble() -> ShortDouble { // CHECK: define void @structshortdouble_input({ i64, double } %0) // CHECK-NEXT: start: #[no_mangle] -pub extern "C" fn structshortdouble_input(a: ShortDouble) { } - +pub extern "C" fn structshortdouble_input(a: ShortDouble) {} #[repr(C)] pub struct FloatLongFloat { diff --git a/tests/codegen/split-lto-unit.rs b/tests/codegen/split-lto-unit.rs index 6cea9a2d8d5f..7858a0e7b796 100644 --- a/tests/codegen/split-lto-unit.rs +++ b/tests/codegen/split-lto-unit.rs @@ -3,9 +3,8 @@ //@ needs-sanitizer-cfi //@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsplit-lto-unit -#![crate_type="lib"] +#![crate_type = "lib"] -pub fn foo() { -} +pub fn foo() {} // CHECK: !{{[0-9]+}} = !{i32 4, !"EnableSplitLTOUnit", i32 1} diff --git a/tests/codegen/sroa-fragment-debuginfo.rs b/tests/codegen/sroa-fragment-debuginfo.rs index 670ddb56540e..0413cf968942 100644 --- a/tests/codegen/sroa-fragment-debuginfo.rs +++ b/tests/codegen/sroa-fragment-debuginfo.rs @@ -13,13 +13,13 @@ pub struct ExtraSlice<'input> { #[no_mangle] pub fn extra(s: &[u8]) { -// CHECK: void @extra( -// CHECK: %slice.dbg.spill1 = alloca [4 x i8], -// CHECK: %slice.dbg.spill = alloca [16 x i8], -// CHECK: %s.dbg.spill = alloca [16 x i8], -// CHECK: dbg{{.}}declare({{(metadata )?}}ptr %s.dbg.spill, {{(metadata )?}}![[S_EXTRA:.*]], {{(metadata )?}}!DIExpression() -// CHECK: dbg{{.}}declare({{(metadata )?}}ptr %slice.dbg.spill, {{(metadata )?}}![[SLICE_EXTRA:.*]], {{(metadata )?}}!DIExpression(DW_OP_LLVM_fragment, 0, 128) -// CHECK: dbg{{.}}declare({{(metadata )?}}ptr %slice.dbg.spill1, {{(metadata )?}}![[SLICE_EXTRA]], {{(metadata )?}}!DIExpression(DW_OP_LLVM_fragment, 128, 32) + // CHECK: void @extra( + // CHECK: %slice.dbg.spill1 = alloca [4 x i8], + // CHECK: %slice.dbg.spill = alloca [16 x i8], + // CHECK: %s.dbg.spill = alloca [16 x i8], + // CHECK: dbg{{.}}declare({{(metadata )?}}ptr %s.dbg.spill, {{(metadata )?}}![[S_EXTRA:.*]], {{(metadata )?}}!DIExpression() + // CHECK: dbg{{.}}declare({{(metadata )?}}ptr %slice.dbg.spill, {{(metadata )?}}![[SLICE_EXTRA:.*]], {{(metadata )?}}!DIExpression(DW_OP_LLVM_fragment, 0, 128) + // CHECK: dbg{{.}}declare({{(metadata )?}}ptr %slice.dbg.spill1, {{(metadata )?}}![[SLICE_EXTRA]], {{(metadata )?}}!DIExpression(DW_OP_LLVM_fragment, 128, 32) let slice = ExtraSlice { slice: s, extra: s.len() as u32 }; } @@ -35,10 +35,10 @@ pub fn zst(s: &[u8]) { // The field `extra` is a ZST. The fragment for the field `slice` encompasses the whole // variable, so is not a fragment. In that case, the variable must have no fragment. -// CHECK: void @zst( -// CHECK-NOT: dbg{{.}}declare({{(metadata )?}}ptr %slice.dbg.spill, {{(metadata )?}}!{}, {{(metadata )?}}!DIExpression(DW_OP_LLVM_fragment, -// CHECK: dbg{{.}}declare({{(metadata )?}}ptr %{{.*}}, {{(metadata )?}}![[SLICE_ZST:.*]], {{(metadata )?}}!DIExpression() -// CHECK-NOT: dbg{{.}}declare({{(metadata )?}}ptr %{{.*}}, {{(metadata )?}}![[SLICE_ZST]], + // CHECK: void @zst( + // CHECK-NOT: dbg{{.}}declare({{(metadata )?}}ptr %slice.dbg.spill, {{(metadata )?}}!{}, {{(metadata )?}}!DIExpression(DW_OP_LLVM_fragment, + // CHECK: dbg{{.}}declare({{(metadata )?}}ptr %{{.*}}, {{(metadata )?}}![[SLICE_ZST:.*]], {{(metadata )?}}!DIExpression() + // CHECK-NOT: dbg{{.}}declare({{(metadata )?}}ptr %{{.*}}, {{(metadata )?}}![[SLICE_ZST]], let slice = ZstSlice { slice: s, extra: Zst }; } diff --git a/tests/codegen/stack-probes-inline.rs b/tests/codegen/stack-probes-inline.rs index 6bd6b0cb354c..c5073b9cc221 100644 --- a/tests/codegen/stack-probes-inline.rs +++ b/tests/codegen/stack-probes-inline.rs @@ -27,6 +27,6 @@ trait Sized {} #[no_mangle] pub fn foo() { -// CHECK: @foo() unnamed_addr #0 -// CHECK: attributes #0 = { {{.*}}"probe-stack"="inline-asm"{{.*}} } + // CHECK: @foo() unnamed_addr #0 + // CHECK: attributes #0 = { {{.*}}"probe-stack"="inline-asm"{{.*}} } } diff --git a/tests/codegen/static-relocation-model-msvc.rs b/tests/codegen/static-relocation-model-msvc.rs index 5501827498cc..8ed8331466c7 100644 --- a/tests/codegen/static-relocation-model-msvc.rs +++ b/tests/codegen/static-relocation-model-msvc.rs @@ -20,7 +20,5 @@ extern crate extern_decl; #[no_mangle] pub fn access_extern() -> u8 { - unsafe { - extern_decl::extern_fn() + extern_decl::extern_static - } + unsafe { extern_decl::extern_fn() + extern_decl::extern_static } } diff --git a/tests/codegen/stores.rs b/tests/codegen/stores.rs index 86ec52fa1015..aa3090db6d31 100644 --- a/tests/codegen/stores.rs +++ b/tests/codegen/stores.rs @@ -4,10 +4,10 @@ #![crate_type = "lib"] pub struct Bytes { - a: u8, - b: u8, - c: u8, - d: u8, + a: u8, + b: u8, + c: u8, + d: u8, } // CHECK-LABEL: small_array_alignment @@ -15,10 +15,10 @@ pub struct Bytes { // dependent alignment #[no_mangle] pub fn small_array_alignment(x: &mut [i8; 4], y: [i8; 4]) { -// CHECK: [[TMP:%.+]] = alloca [4 x i8], align 4 -// CHECK: %y = alloca [4 x i8], align 1 -// CHECK: store i32 %0, ptr [[TMP]] -// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 {{.+}}, ptr align 4 {{.+}}, i{{[0-9]+}} 4, i1 false) + // CHECK: [[TMP:%.+]] = alloca [4 x i8], align 4 + // CHECK: %y = alloca [4 x i8], align 1 + // CHECK: store i32 %0, ptr [[TMP]] + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 {{.+}}, ptr align 4 {{.+}}, i{{[0-9]+}} 4, i1 false) *x = y; } @@ -27,9 +27,9 @@ pub fn small_array_alignment(x: &mut [i8; 4], y: [i8; 4]) { // dependent alignment #[no_mangle] pub fn small_struct_alignment(x: &mut Bytes, y: Bytes) { -// CHECK: [[TMP:%.+]] = alloca [4 x i8], align 4 -// CHECK: %y = alloca [4 x i8], align 1 -// CHECK: store i32 %0, ptr [[TMP]] -// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 {{.+}}, ptr align 4 {{.+}}, i{{[0-9]+}} 4, i1 false) + // CHECK: [[TMP:%.+]] = alloca [4 x i8], align 4 + // CHECK: %y = alloca [4 x i8], align 1 + // CHECK: store i32 %0, ptr [[TMP]] + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 {{.+}}, ptr align 4 {{.+}}, i{{[0-9]+}} 4, i1 false) *x = y; } diff --git a/tests/codegen/swap-large-types.rs b/tests/codegen/swap-large-types.rs index b976f6fe207b..761d48969dad 100644 --- a/tests/codegen/swap-large-types.rs +++ b/tests/codegen/swap-large-types.rs @@ -4,7 +4,7 @@ #![crate_type = "lib"] use std::mem::swap; -use std::ptr::{read, copy_nonoverlapping, write}; +use std::ptr::{copy_nonoverlapping, read, write}; type KeccakBuffer = [[u64; 5]; 5]; @@ -15,7 +15,7 @@ type KeccakBuffer = [[u64; 5]; 5]; // CHECK-LABEL: @swap_basic #[no_mangle] pub fn swap_basic(x: &mut KeccakBuffer, y: &mut KeccakBuffer) { -// CHECK: alloca [200 x i8] + // CHECK: alloca [200 x i8] // SAFETY: exclusive references are always valid to read/write, // are non-overlapping, and nothing here panics so it's drop-safe. @@ -32,9 +32,9 @@ pub fn swap_basic(x: &mut KeccakBuffer, y: &mut KeccakBuffer) { // CHECK-LABEL: @swap_std #[no_mangle] pub fn swap_std(x: &mut KeccakBuffer, y: &mut KeccakBuffer) { -// CHECK-NOT: alloca -// CHECK: load <{{[0-9]+}} x i64> -// CHECK: store <{{[0-9]+}} x i64> + // CHECK-NOT: alloca + // CHECK: load <{{[0-9]+}} x i64> + // CHECK: store <{{[0-9]+}} x i64> swap(x, y) } @@ -44,9 +44,9 @@ pub fn swap_std(x: &mut KeccakBuffer, y: &mut KeccakBuffer) { // CHECK-LABEL: @swap_slice #[no_mangle] pub fn swap_slice(x: &mut [KeccakBuffer], y: &mut [KeccakBuffer]) { -// CHECK-NOT: alloca -// CHECK: load <{{[0-9]+}} x i64> -// CHECK: store <{{[0-9]+}} x i64> + // CHECK-NOT: alloca + // CHECK: load <{{[0-9]+}} x i64> + // CHECK: store <{{[0-9]+}} x i64> if x.len() == y.len() { x.swap_with_slice(y); } @@ -59,9 +59,9 @@ type OneKilobyteBuffer = [u8; 1024]; // CHECK-LABEL: @swap_1kb_slices #[no_mangle] pub fn swap_1kb_slices(x: &mut [OneKilobyteBuffer], y: &mut [OneKilobyteBuffer]) { -// CHECK-NOT: alloca -// CHECK: load <{{[0-9]+}} x i8> -// CHECK: store <{{[0-9]+}} x i8> + // CHECK-NOT: alloca + // CHECK: load <{{[0-9]+}} x i8> + // CHECK: store <{{[0-9]+}} x i8> if x.len() == y.len() { x.swap_with_slice(y); } @@ -81,10 +81,10 @@ pub struct BigButHighlyAligned([u8; 64 * 3]); // CHECK-LABEL: @swap_big_aligned #[no_mangle] pub fn swap_big_aligned(x: &mut BigButHighlyAligned, y: &mut BigButHighlyAligned) { -// CHECK-NOT: call void @llvm.memcpy -// CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192) -// CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192) -// CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192) -// CHECK-NOT: call void @llvm.memcpy + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192) + // CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192) + // CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192) + // CHECK-NOT: call void @llvm.memcpy swap(x, y) } diff --git a/tests/codegen/target-feature-overrides.rs b/tests/codegen/target-feature-overrides.rs index 61b1b3fd2578..1e2c364dbbc9 100644 --- a/tests/codegen/target-feature-overrides.rs +++ b/tests/codegen/target-feature-overrides.rs @@ -9,7 +9,6 @@ #![crate_type = "lib"] #![no_core] - #[lang = "sized"] trait Sized {} #[lang = "copy"] @@ -23,19 +22,19 @@ extern "C" { #[target_feature(enable = "avx")] #[no_mangle] pub unsafe fn apple() -> u32 { -// CHECK-LABEL: @apple() -// CHECK-SAME: [[APPLEATTRS:#[0-9]+]] { -// CHECK: {{.*}}call{{.*}}@peach + // CHECK-LABEL: @apple() + // CHECK-SAME: [[APPLEATTRS:#[0-9]+]] { + // CHECK: {{.*}}call{{.*}}@peach peach() } // target features same as global #[no_mangle] pub unsafe fn banana() -> u32 { -// CHECK-LABEL: @banana() -// CHECK-SAME: [[BANANAATTRS:#[0-9]+]] { -// COMPAT: {{.*}}call{{.*}}@peach -// INCOMPAT: {{.*}}call{{.*}}@apple + // CHECK-LABEL: @banana() + // CHECK-SAME: [[BANANAATTRS:#[0-9]+]] { + // COMPAT: {{.*}}call{{.*}}@peach + // INCOMPAT: {{.*}}call{{.*}}@apple apple() // Compatible for inline in COMPAT revision and can't be inlined in INCOMPAT } diff --git a/tests/codegen/thin-lto.rs b/tests/codegen/thin-lto.rs index c75f9841a773..4339d20532ea 100644 --- a/tests/codegen/thin-lto.rs +++ b/tests/codegen/thin-lto.rs @@ -3,5 +3,4 @@ // CHECK: main -pub fn main() { -} +pub fn main() {} diff --git a/tests/codegen/tied-features-strength.rs b/tests/codegen/tied-features-strength.rs index b97865295a23..7f0805bc1b43 100644 --- a/tests/codegen/tied-features-strength.rs +++ b/tests/codegen/tied-features-strength.rs @@ -19,7 +19,6 @@ //@ [ENABLE_NEON] compile-flags: -C target-feature=+neon -Copt-level=0 // ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(\+fp-armv8,?)|(\+neon,?))*}}" } - #![feature(no_core, lang_items)] #![no_core] diff --git a/tests/codegen/to_vec.rs b/tests/codegen/to_vec.rs index 651084d811ca..4666f8d6f153 100644 --- a/tests/codegen/to_vec.rs +++ b/tests/codegen/to_vec.rs @@ -5,6 +5,6 @@ // CHECK-LABEL: @copy_to_vec #[no_mangle] fn copy_to_vec(s: &[u64]) -> Vec { - s.to_vec() - // CHECK: call void @llvm.memcpy + s.to_vec() + // CHECK: call void @llvm.memcpy } diff --git a/tests/codegen/transmute-optimized.rs b/tests/codegen/transmute-optimized.rs index 8e5bcb2340e4..11bd0523788a 100644 --- a/tests/codegen/transmute-optimized.rs +++ b/tests/codegen/transmute-optimized.rs @@ -5,7 +5,9 @@ // destination types for transmutes. #[repr(u32)] -pub enum AlwaysZero32 { X = 0 } +pub enum AlwaysZero32 { + X = 0, +} // CHECK-LABEL: i32 @issue_109958(i32 #[no_mangle] @@ -81,7 +83,11 @@ pub fn div_transmute_nonzero(a: u32, b: std::num::NonZero) -> u32 { } #[repr(i8)] -pub enum OneTwoThree { One = 1, Two = 2, Three = 3 } +pub enum OneTwoThree { + One = 1, + Two = 2, + Three = 3, +} // CHECK-LABEL: i8 @ordering_transmute_onetwothree(i8 #[no_mangle] diff --git a/tests/codegen/try_identity.rs b/tests/codegen/try_identity.rs index 87b7d0727d08..6a3a8a06e82b 100644 --- a/tests/codegen/try_identity.rs +++ b/tests/codegen/try_identity.rs @@ -13,9 +13,9 @@ type R = Result; // optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not. #[no_mangle] pub fn try_identity(x: R) -> R { -// CHECK: start: -// FIXME(JakobDegen): Broken by deaggregation change CHECK-NOT\: br {{.*}} -// CHECK ret void + // CHECK: start: + // FIXME(JakobDegen): Broken by deaggregation change CHECK-NOT\: br {{.*}} + // CHECK ret void let y = match into_result(x) { Err(e) => return from_error(From::from(e)), Ok(v) => v, diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs index f6cdf9552097..c23f41f54671 100644 --- a/tests/codegen/try_question_mark_nop.rs +++ b/tests/codegen/try_question_mark_nop.rs @@ -4,7 +4,7 @@ #![crate_type = "lib"] #![feature(try_blocks)] -use std::ops::ControlFlow::{self, Continue, Break}; +use std::ops::ControlFlow::{self, Break, Continue}; use std::ptr::NonNull; // CHECK-LABEL: @option_nop_match_32 @@ -27,9 +27,7 @@ pub fn option_nop_traits_32(x: Option) -> Option { // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: ret { i32, i32 } - try { - x? - } + try { x? } } // CHECK-LABEL: @result_nop_match_32 @@ -52,9 +50,7 @@ pub fn result_nop_traits_32(x: Result) -> Result { // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: ret { i32, i32 } - try { - x? - } + try { x? } } // CHECK-LABEL: @result_nop_match_64 @@ -77,9 +73,7 @@ pub fn result_nop_traits_64(x: Result) -> Result { // CHECK-NEXT: insertvalue { i64, i64 } // CHECK-NEXT: insertvalue { i64, i64 } // CHECK-NEXT: ret { i64, i64 } - try { - x? - } + try { x? } } // CHECK-LABEL: @result_nop_match_ptr @@ -102,9 +96,7 @@ pub fn result_nop_traits_ptr(x: Result>) -> Result) -> ControlFlow ScalarZstLast { loop {} } +pub fn test_ScalarZstLast(_: ScalarZstLast) -> ScalarZstLast { + loop {} +} type ScalarZstFirst = ((), u128); // CHECK: define {{(dso_local )?}}i128 @test_ScalarZstFirst(i128 %_1) #[no_mangle] -pub fn test_ScalarZstFirst(_: ScalarZstFirst) -> ScalarZstFirst { loop {} } +pub fn test_ScalarZstFirst(_: ScalarZstFirst) -> ScalarZstFirst { + loop {} +} type ScalarPairZstLast = (u8, u128, ()); // CHECK: define {{(dso_local )?}}{ i128, i8 } @test_ScalarPairZstLast(i128 %_1.0, i8 %_1.1) #[no_mangle] -pub fn test_ScalarPairZstLast(_: ScalarPairZstLast) -> ScalarPairZstLast { loop {} } +pub fn test_ScalarPairZstLast(_: ScalarPairZstLast) -> ScalarPairZstLast { + loop {} +} type ScalarPairZstFirst = ((), u8, u128); // CHECK: define {{(dso_local )?}}{ i8, i128 } @test_ScalarPairZstFirst(i8 %_1.0, i128 %_1.1) #[no_mangle] -pub fn test_ScalarPairZstFirst(_: ScalarPairZstFirst) -> ScalarPairZstFirst { loop {} } +pub fn test_ScalarPairZstFirst(_: ScalarPairZstFirst) -> ScalarPairZstFirst { + loop {} +} type ScalarPairLotsOfZsts = ((), u8, (), u128, ()); // CHECK: define {{(dso_local )?}}{ i128, i8 } @test_ScalarPairLotsOfZsts(i128 %_1.0, i8 %_1.1) #[no_mangle] -pub fn test_ScalarPairLotsOfZsts(_: ScalarPairLotsOfZsts) -> ScalarPairLotsOfZsts { loop {} } +pub fn test_ScalarPairLotsOfZsts(_: ScalarPairLotsOfZsts) -> ScalarPairLotsOfZsts { + loop {} +} type ScalarPairLottaNesting = (((), ((), u8, (), u128, ())), ()); // CHECK: define {{(dso_local )?}}{ i128, i8 } @test_ScalarPairLottaNesting(i128 %_1.0, i8 %_1.1) #[no_mangle] -pub fn test_ScalarPairLottaNesting(_: ScalarPairLottaNesting) -> ScalarPairLottaNesting { loop {} } +pub fn test_ScalarPairLottaNesting(_: ScalarPairLottaNesting) -> ScalarPairLottaNesting { + loop {} +} diff --git a/tests/codegen/union-abi.rs b/tests/codegen/union-abi.rs index b1b0daa13b64..9e02fa9ff359 100644 --- a/tests/codegen/union-abi.rs +++ b/tests/codegen/union-abi.rs @@ -4,7 +4,7 @@ // This test that using union forward the abi of the inner type, as // discussed in #54668 -#![crate_type="lib"] +#![crate_type = "lib"] #![feature(repr_simd)] #[derive(Copy, Clone)] @@ -15,62 +15,111 @@ pub enum Unhab {} pub struct i64x4(i64, i64, i64, i64); #[derive(Copy, Clone)] -pub union UnionI64x4{ a:(), b: i64x4 } +pub union UnionI64x4 { + a: (), + b: i64x4, +} // CHECK: define {{(dso_local )?}}void @test_UnionI64x4(ptr {{.*}} %_1) #[no_mangle] -pub fn test_UnionI64x4(_: UnionI64x4) { loop {} } +pub fn test_UnionI64x4(_: UnionI64x4) { + loop {} +} -pub union UnionI64x4_{ a: i64x4, b: (), c:i64x4, d: Unhab, e: ((),()), f: UnionI64x4 } +pub union UnionI64x4_ { + a: i64x4, + b: (), + c: i64x4, + d: Unhab, + e: ((), ()), + f: UnionI64x4, +} // CHECK: define {{(dso_local )?}}void @test_UnionI64x4_(ptr {{.*}} %_1) #[no_mangle] -pub fn test_UnionI64x4_(_: UnionI64x4_) { loop {} } +pub fn test_UnionI64x4_(_: UnionI64x4_) { + loop {} +} -pub union UnionI64x4I64{ a: i64x4, b: i64 } +pub union UnionI64x4I64 { + a: i64x4, + b: i64, +} // CHECK: define {{(dso_local )?}}void @test_UnionI64x4I64(ptr {{.*}} %_1) #[no_mangle] -pub fn test_UnionI64x4I64(_: UnionI64x4I64) { loop {} } +pub fn test_UnionI64x4I64(_: UnionI64x4I64) { + loop {} +} -pub union UnionI64x4Tuple{ a: i64x4, b: (i64, i64, i64, i64) } +pub union UnionI64x4Tuple { + a: i64x4, + b: (i64, i64, i64, i64), +} // CHECK: define {{(dso_local )?}}void @test_UnionI64x4Tuple(ptr {{.*}} %_1) #[no_mangle] -pub fn test_UnionI64x4Tuple(_: UnionI64x4Tuple) { loop {} } +pub fn test_UnionI64x4Tuple(_: UnionI64x4Tuple) { + loop {} +} - -pub union UnionF32{a:f32} +pub union UnionF32 { + a: f32, +} // CHECK: define {{(dso_local )?}}float @test_UnionF32(float %_1) #[no_mangle] -pub fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} } +pub fn test_UnionF32(_: UnionF32) -> UnionF32 { + loop {} +} -pub union UnionF32F32{a:f32, b:f32} +pub union UnionF32F32 { + a: f32, + b: f32, +} // CHECK: define {{(dso_local )?}}float @test_UnionF32F32(float %_1) #[no_mangle] -pub fn test_UnionF32F32(_: UnionF32F32) -> UnionF32F32 { loop {} } +pub fn test_UnionF32F32(_: UnionF32F32) -> UnionF32F32 { + loop {} +} -pub union UnionF32U32{a:f32, b:u32} +pub union UnionF32U32 { + a: f32, + b: u32, +} // CHECK: define {{(dso_local )?}}i32 @test_UnionF32U32(i32{{( %0)?}}) #[no_mangle] -pub fn test_UnionF32U32(_: UnionF32U32) -> UnionF32U32 { loop {} } +pub fn test_UnionF32U32(_: UnionF32U32) -> UnionF32U32 { + loop {} +} -pub union UnionU128{a:u128} +pub union UnionU128 { + a: u128, +} // CHECK: define {{(dso_local )?}}i128 @test_UnionU128(i128 %_1) #[no_mangle] -pub fn test_UnionU128(_: UnionU128) -> UnionU128 { loop {} } +pub fn test_UnionU128(_: UnionU128) -> UnionU128 { + loop {} +} #[repr(C)] -pub union CUnionU128{a:u128} +pub union CUnionU128 { + a: u128, +} // CHECK: define {{(dso_local )?}}void @test_CUnionU128(ptr {{.*}} %_1) #[no_mangle] -pub fn test_CUnionU128(_: CUnionU128) { loop {} } +pub fn test_CUnionU128(_: CUnionU128) { + loop {} +} -pub union UnionBool { b:bool } +pub union UnionBool { + b: bool, +} // CHECK: define {{(dso_local )?}}noundef zeroext i1 @test_UnionBool(i8 %b) #[no_mangle] -pub fn test_UnionBool(b: UnionBool) -> bool { unsafe { b.b } } +pub fn test_UnionBool(b: UnionBool) -> bool { + unsafe { b.b } +} // CHECK: %_0 = trunc i8 %b to i1 diff --git a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs index 484af78105f1..48c7ecf78242 100644 --- a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs +++ b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs @@ -2,8 +2,8 @@ //@ compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items, c_unwind)] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} // Test that `nounwind` attributes are correctly applied to exported `aapcs` and // `aapcs-unwind` extern functions. `aapcs-unwind` functions MUST NOT have this attribute. We @@ -11,13 +11,11 @@ trait Sized { } // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] -pub extern "aapcs" fn rust_item_that_cannot_unwind() { -} +pub extern "aapcs" fn rust_item_that_cannot_unwind() {} // CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { #[no_mangle] -pub extern "aapcs-unwind" fn rust_item_that_can_unwind() { -} +pub extern "aapcs-unwind" fn rust_item_that_can_unwind() {} // Now, make some assertions that the LLVM attributes for these functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: diff --git a/tests/codegen/unwind-abis/c-unwind-abi.rs b/tests/codegen/unwind-abis/c-unwind-abi.rs index 140c18e6bb33..99763943a6ac 100644 --- a/tests/codegen/unwind-abis/c-unwind-abi.rs +++ b/tests/codegen/unwind-abis/c-unwind-abi.rs @@ -10,13 +10,11 @@ // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] -pub extern "C" fn rust_item_that_cannot_unwind() { -} +pub extern "C" fn rust_item_that_cannot_unwind() {} // CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { #[no_mangle] -pub extern "C-unwind" fn rust_item_that_can_unwind() { -} +pub extern "C-unwind" fn rust_item_that_can_unwind() {} // Now, make some assertions that the LLVM attributes for these functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: diff --git a/tests/codegen/unwind-abis/cdecl-unwind-abi.rs b/tests/codegen/unwind-abis/cdecl-unwind-abi.rs index 5604b8d5765a..78dbb55b35a2 100644 --- a/tests/codegen/unwind-abis/cdecl-unwind-abi.rs +++ b/tests/codegen/unwind-abis/cdecl-unwind-abi.rs @@ -10,13 +10,11 @@ // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] -pub extern "cdecl" fn rust_item_that_cannot_unwind() { -} +pub extern "cdecl" fn rust_item_that_cannot_unwind() {} // CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { #[no_mangle] -pub extern "cdecl-unwind" fn rust_item_that_can_unwind() { -} +pub extern "cdecl-unwind" fn rust_item_that_can_unwind() {} // Now, make some assertions that the LLVM attributes for these functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: diff --git a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs index 18e2cd22c8aa..3cbeaf51d960 100644 --- a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs @@ -2,8 +2,8 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items, c_unwind)] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} // Test that `nounwind` attributes are correctly applied to exported `fastcall` and // `fastcall-unwind` extern functions. `fastcall-unwind` functions MUST NOT have this attribute. We @@ -11,13 +11,11 @@ trait Sized { } // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] -pub extern "fastcall" fn rust_item_that_cannot_unwind() { -} +pub extern "fastcall" fn rust_item_that_cannot_unwind() {} // CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { #[no_mangle] -pub extern "fastcall-unwind" fn rust_item_that_can_unwind() { -} +pub extern "fastcall-unwind" fn rust_item_that_can_unwind() {} // Now, make some assertions that the LLVM attributes for these functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: diff --git a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs index a5e600fe076f..ffb235cd1168 100644 --- a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs @@ -2,8 +2,8 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items, c_unwind)] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} // Test that `nounwind` attributes are correctly applied to exported `stdcall` and `stdcall-unwind` // extern functions. `stdcall-unwind` functions MUST NOT have this attribute. We disable @@ -11,13 +11,11 @@ trait Sized { } // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] -pub extern "stdcall" fn rust_item_that_cannot_unwind() { -} +pub extern "stdcall" fn rust_item_that_cannot_unwind() {} // CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { #[no_mangle] -pub extern "stdcall-unwind" fn rust_item_that_can_unwind() { -} +pub extern "stdcall-unwind" fn rust_item_that_can_unwind() {} // Now, make some assertions that the LLVM attributes for these functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: diff --git a/tests/codegen/unwind-abis/system-unwind-abi.rs b/tests/codegen/unwind-abis/system-unwind-abi.rs index b001c1f951c4..1dd0e9bbbec7 100644 --- a/tests/codegen/unwind-abis/system-unwind-abi.rs +++ b/tests/codegen/unwind-abis/system-unwind-abi.rs @@ -10,13 +10,11 @@ // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] -pub extern "system" fn rust_item_that_cannot_unwind() { -} +pub extern "system" fn rust_item_that_cannot_unwind() {} // CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { #[no_mangle] -pub extern "system-unwind" fn rust_item_that_can_unwind() { -} +pub extern "system-unwind" fn rust_item_that_can_unwind() {} // Now, make some assertions that the LLVM attributes for these functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: diff --git a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs index 49407f748bc3..9824009dc559 100644 --- a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs @@ -2,8 +2,8 @@ //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items, c_unwind)] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} // Test that `nounwind` attributes are correctly applied to exported `sysv64` and // `sysv64-unwind` extern functions. `sysv64-unwind` functions MUST NOT have this attribute. We @@ -11,13 +11,11 @@ trait Sized { } // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] -pub extern "sysv64" fn rust_item_that_cannot_unwind() { -} +pub extern "sysv64" fn rust_item_that_cannot_unwind() {} // CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { #[no_mangle] -pub extern "sysv64-unwind" fn rust_item_that_can_unwind() { -} +pub extern "sysv64-unwind" fn rust_item_that_can_unwind() {} // Now, make some assertions that the LLVM attributes for these functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: diff --git a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs index d07e9b81d783..a96f4d5a350c 100644 --- a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs @@ -2,8 +2,8 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items, c_unwind)] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} // Test that `nounwind` attributes are correctly applied to exported `thiscall` and // `thiscall-unwind` extern functions. `thiscall-unwind` functions MUST NOT have this attribute. We @@ -11,13 +11,11 @@ trait Sized { } // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] -pub extern "thiscall" fn rust_item_that_cannot_unwind() { -} +pub extern "thiscall" fn rust_item_that_cannot_unwind() {} // CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { #[no_mangle] -pub extern "thiscall-unwind" fn rust_item_that_can_unwind() { -} +pub extern "thiscall-unwind" fn rust_item_that_can_unwind() {} // Now, make some assertions that the LLVM attributes for these functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: diff --git a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs index a89794fbf6e3..9929e3e3703d 100644 --- a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs @@ -2,8 +2,8 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items, c_unwind, abi_vectorcall)] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} // Test that `nounwind` attributes are correctly applied to exported `vectorcall` and // `vectorcall-unwind` extern functions. `vectorcall-unwind` functions MUST NOT have this attribute. @@ -11,13 +11,11 @@ trait Sized { } // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] -pub extern "vectorcall" fn rust_item_that_cannot_unwind() { -} +pub extern "vectorcall" fn rust_item_that_cannot_unwind() {} // CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { #[no_mangle] -pub extern "vectorcall-unwind" fn rust_item_that_can_unwind() { -} +pub extern "vectorcall-unwind" fn rust_item_that_can_unwind() {} // Now, make some assertions that the LLVM attributes for these functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: diff --git a/tests/codegen/unwind-abis/win64-unwind-abi.rs b/tests/codegen/unwind-abis/win64-unwind-abi.rs index aa466469c4de..a45a94f628d1 100644 --- a/tests/codegen/unwind-abis/win64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/win64-unwind-abi.rs @@ -2,8 +2,8 @@ //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items, c_unwind)] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} // Test that `nounwind` attributes are correctly applied to exported `win64` and // `win64-unwind` extern functions. `win64-unwind` functions MUST NOT have this attribute. We @@ -11,13 +11,11 @@ trait Sized { } // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] -pub extern "win64" fn rust_item_that_cannot_unwind() { -} +pub extern "win64" fn rust_item_that_cannot_unwind() {} // CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { #[no_mangle] -pub extern "win64-unwind" fn rust_item_that_can_unwind() { -} +pub extern "win64-unwind" fn rust_item_that_can_unwind() {} // Now, make some assertions that the LLVM attributes for these functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: diff --git a/tests/codegen/vec-iter-collect-len.rs b/tests/codegen/vec-iter-collect-len.rs index e4242c574023..8c5d2f6f9a74 100644 --- a/tests/codegen/vec-iter-collect-len.rs +++ b/tests/codegen/vec-iter-collect-len.rs @@ -1,5 +1,5 @@ //@ compile-flags: -O -#![crate_type="lib"] +#![crate_type = "lib"] #[no_mangle] pub fn get_len() -> usize { diff --git a/tests/codegen/vtable-upcast.rs b/tests/codegen/vtable-upcast.rs index 41a4be26cb44..ae7b4bf7aee9 100644 --- a/tests/codegen/vtable-upcast.rs +++ b/tests/codegen/vtable-upcast.rs @@ -8,15 +8,15 @@ pub trait Base { fn base(&self); } -pub trait A : Base { +pub trait A: Base { fn a(&self); } -pub trait B : Base { +pub trait B: Base { fn b(&self); } -pub trait Diamond : A + B { +pub trait Diamond: A + B { fn diamond(&self); } diff --git a/tests/codegen/wasm_exceptions.rs b/tests/codegen/wasm_exceptions.rs index a53722f834c5..3910850e03a0 100644 --- a/tests/codegen/wasm_exceptions.rs +++ b/tests/codegen/wasm_exceptions.rs @@ -5,7 +5,7 @@ #![feature(core_intrinsics)] #![feature(rustc_attrs)] -extern { +extern "C" { fn may_panic(); #[rustc_nounwind] @@ -16,7 +16,9 @@ struct LogOnDrop; impl Drop for LogOnDrop { fn drop(&mut self) { - unsafe { log_number(0); } + unsafe { + log_number(0); + } } } @@ -24,7 +26,9 @@ impl Drop for LogOnDrop { #[no_mangle] pub fn test_cleanup() { let _log_on_drop = LogOnDrop; - unsafe { may_panic(); } + unsafe { + may_panic(); + } // CHECK-NOT: call // CHECK: invoke void @may_panic() @@ -35,12 +39,16 @@ pub fn test_cleanup() { #[no_mangle] pub fn test_rtry() { unsafe { - core::intrinsics::catch_unwind(|_| { - may_panic(); - }, core::ptr::null_mut(), |data, exception| { - log_number(data as usize); - log_number(exception as usize); - }); + core::intrinsics::catch_unwind( + |_| { + may_panic(); + }, + core::ptr::null_mut(), + |data, exception| { + log_number(data as usize); + log_number(exception as usize); + }, + ); } // CHECK-NOT: call diff --git a/tests/codegen/zip.rs b/tests/codegen/zip.rs index 5db0a93b78ef..ea8caba61f39 100644 --- a/tests/codegen/zip.rs +++ b/tests/codegen/zip.rs @@ -5,7 +5,7 @@ // CHECK-LABEL: @zip_copy #[no_mangle] pub fn zip_copy(xs: &[u8], ys: &mut [u8]) { -// CHECK: memcpy + // CHECK: memcpy for (x, y) in xs.iter().zip(ys) { *y = *x; } @@ -14,7 +14,7 @@ pub fn zip_copy(xs: &[u8], ys: &mut [u8]) { // CHECK-LABEL: @zip_copy_mapped #[no_mangle] pub fn zip_copy_mapped(xs: &[u8], ys: &mut [u8]) { -// CHECK: memcpy + // CHECK: memcpy for (x, y) in xs.iter().map(|&x| x).zip(ys) { *y = x; } diff --git a/tests/codegen/zst-offset.rs b/tests/codegen/zst-offset.rs index b623d492d9d6..14e97fd26ddf 100644 --- a/tests/codegen/zst-offset.rs +++ b/tests/codegen/zst-offset.rs @@ -6,14 +6,13 @@ // Hack to get the correct size for the length part in slices // CHECK: @helper([[USIZE:i[0-9]+]] %_1) #[no_mangle] -pub fn helper(_: usize) { -} +pub fn helper(_: usize) {} // Check that we correctly generate a GEP for a ZST that is not included in Scalar layout // CHECK-LABEL: @scalar_layout #[no_mangle] pub fn scalar_layout(s: &(u64, ())) { -// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 8 + // CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 8 let x = &s.1; witness(&x); // keep variable in an alloca } @@ -22,7 +21,7 @@ pub fn scalar_layout(s: &(u64, ())) { // CHECK-LABEL: @scalarpair_layout #[no_mangle] pub fn scalarpair_layout(s: &(u64, u32, ())) { -// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 12 + // CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 12 let x = &s.2; witness(&x); // keep variable in an alloca } @@ -34,7 +33,7 @@ pub struct U64x4(u64, u64, u64, u64); // CHECK-LABEL: @vector_layout #[no_mangle] pub fn vector_layout(s: &(U64x4, ())) { -// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 32 + // CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 32 let x = &s.1; witness(&x); // keep variable in an alloca } diff --git a/tests/crashes/119830.rs b/tests/crashes/119830.rs deleted file mode 100644 index 71becc04e169..000000000000 --- a/tests/crashes/119830.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #119830 -#![feature(effects)] -#![feature(min_specialization)] - -trait Specialize {} - -trait Foo {} - -impl const Foo for T {} - -impl const Foo for T where T: const Specialize {} diff --git a/tests/crashes/121126.rs b/tests/crashes/121126.rs deleted file mode 100644 index 2ebe91f02ded..000000000000 --- a/tests/crashes/121126.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #121126 -fn main() { - let _n = 1i64 >> [64][4_294_967_295]; -} diff --git a/tests/crashes/121134.rs b/tests/crashes/121134.rs deleted file mode 100644 index 36397d4ec3c0..000000000000 --- a/tests/crashes/121134.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ known-bug: #121134 -trait Output<'a> { - type Type; -} - -struct Wrapper; - -impl Wrapper { - fn do_something_wrapper(&mut self, do_something_wrapper: F) - where - FnOnce:, - F: for<'a> FnOnce(>::Type), - { - } -} - -fn main() { - let mut wrapper = Wrapper; - wrapper.do_something_wrapper::(|value| ()); -} diff --git a/tests/ui/consts/eval_type_mismatch.rs b/tests/crashes/121858.rs similarity index 53% rename from tests/ui/consts/eval_type_mismatch.rs rename to tests/crashes/121858.rs index 3d821ab538ec..7d5bae37f846 100644 --- a/tests/ui/consts/eval_type_mismatch.rs +++ b/tests/crashes/121858.rs @@ -1,17 +1,14 @@ +//@ known-bug: #121858 #![feature(generic_const_exprs)] -#![allow(incomplete_features)] struct Outer(); impl Outer -//~^ ERROR: `A` is not of type `i64` -//~| ERROR: mismatched types where [(); A + (B * 2)]:, { - fn o() {} + fn o() -> Union {} } fn main() { Outer::<1, 1>::o(); - //~^ ERROR: no function or associated item named `o` found } diff --git a/tests/crashes/122638.rs b/tests/crashes/122638.rs deleted file mode 100644 index af0fc5bbd503..000000000000 --- a/tests/crashes/122638.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #122638 -#![feature(min_specialization)] - -impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, { N }> { - fn next(&mut self) -> Option {} -} - -struct ConstChunksExact<'a, T: '_, const assert: usize> {} - -impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}> { - type Item = &'a [T; N]; -} diff --git a/tests/crashes/123141-2.rs b/tests/crashes/123141-2.rs deleted file mode 100644 index 74f961c2a337..000000000000 --- a/tests/crashes/123141-2.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ known-bug: #123141 - -trait ConstChunksExactTrait { - fn const_chunks_exact(&self) -> ConstChunksExact<'_, T, {N}>; -} - -impl ConstChunksExactTrait for [T] {} - -struct ConstChunksExact<'a, T: 'a, const N: usize> {} - -impl <'a, T: , const N: usize> Iterator for ConstChunksExact<'a, T, {rem}> { - type Item = &'a [T; N]; -} - -fn main() { - let slice = &[1i32, 2, 3, 4, 5, 6, 7, 7, 9, 1i32]; - - let mut iter = [[1, 2, 3], [4, 5, 6], [7, 8 ,9]].iter(); - - for a in slice.const_chunks_exact::<3>() { - assert_eq!(a, iter.next().unwrap()); - } -} diff --git a/tests/crashes/123141.rs b/tests/crashes/123141.rs index 99dfee7670ef..07181387e045 100644 --- a/tests/crashes/123141.rs +++ b/tests/crashes/123141.rs @@ -1,22 +1,23 @@ //@ known-bug: #123141 -trait ConstChunksExactTrait { - fn const_chunks_exact(&self) -> ConstChunksExact<'_, T, { N }>; + +trait Trait { + fn next(self) -> Self::Item; + type Item; } -impl ConstChunksExactTrait for [T] {} +struct Foo(T); -struct ConstChunksExact<'a, T: 'a, const N: usize> {} +impl Trait for Foo { + type Item = Foo; + fn next(self) -> Self::Item { + loop {} + } +} -impl<'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, { rem }> { - type Item = &'a [T; N]; +fn opaque() -> impl Trait { + Foo::<_>(10_u32) } fn main() { - let slice = &[1i32, 2, 3, 4, 5, 6, 7, 7, 9, 1i32]; - - let mut iter = [[1, 2, 3], [4, 5, 6], [7, 8, 9]].iter(); - - for a in slice.const_chunks_exact::<3>() { - assert_eq!(a, iter.next().unwrap()); - } + opaque().next(); } diff --git a/tests/crashes/123917.rs b/tests/crashes/123917.rs deleted file mode 100644 index 66e754606622..000000000000 --- a/tests/crashes/123917.rs +++ /dev/null @@ -1,41 +0,0 @@ -//@ known-bug: #123917 -//@ compile-flags: -Zmir-opt-level=5 -Zpolymorphize=on - -use std::marker::PhantomData; - -pub struct Id<'id>(); - -pub struct Item<'life, T> { - data: T, -} - -pub struct Token<'life, 'borrow, 'compact, 'reborrow, T> -where - 'life: 'reborrow, - T: Tokenize, -{ - ptr: *mut ::Tokenized, - ptr: core::ptr::NonNull, - _phantom: PhantomData>, -} - -impl<'life> Arena<'life> { - pub fn tokenize<'before, 'compact, 'borrow, 'reborrow, T, U>( - item: Item<'life, &'before mut T>, - ) -> Token<'life, 'borrow, 'compact, 'reborrow, U> - where - T: Tokenize<'life, 'borrow, 'compact, 'reborrow, Untokenized = U>, - T::Untokenized: Tokenize<'life, 'borrow, 'compact, 'reborrow>, - { - let dst = item.data as *mut T as *mut T::Tokenized; - Token { - ptr: core::ptr::NonNull::new(dst as *mut _).unwrap(), - _phantom: PhantomData, - } - } -} - -pub trait Tokenize { - type Tokenized; - type Untokenized; -} diff --git a/tests/debuginfo/unsized.rs b/tests/debuginfo/unsized.rs index f76376de3836..982ab003a2a1 100644 --- a/tests/debuginfo/unsized.rs +++ b/tests/debuginfo/unsized.rs @@ -46,13 +46,13 @@ // cdb-command:dx c // cdb-check:c [Type: ref$ > >] // cdb-check: [+0x000] pointer : 0x[...] [Type: unsized::Foo > *] -// cdb-check: [...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[3]] +// cdb-check: [...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[4]] // cdb-command:dx _box // cdb-check: // cdb-check:_box [Type: alloc::boxed::Box >,alloc::alloc::Global>] // cdb-check:[+0x000] pointer : 0x[...] [Type: unsized::Foo > *] -// cdb-check:[...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[3]] +// cdb-check:[...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[4]] // cdb-command:dx tuple_slice // cdb-check:tuple_slice [Type: ref$ > >] @@ -62,7 +62,7 @@ // cdb-command:dx tuple_dyn // cdb-check:tuple_dyn [Type: ref$ > >] // cdb-check: [+0x000] pointer : 0x[...] [Type: tuple$ > *] -// cdb-check: [...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[3]] +// cdb-check: [...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[4]] #![feature(unsized_tuple_coercion)] #![feature(omit_gdb_pretty_printer_section)] diff --git a/tests/mir-opt/address_of.rs b/tests/mir-opt/address_of.rs index 57a317a4a90b..164ab38ebe75 100644 --- a/tests/mir-opt/address_of.rs +++ b/tests/mir-opt/address_of.rs @@ -9,7 +9,7 @@ fn address_of_reborrow() { y as *const [i32; 10]; y as *const dyn Send; y as *const [i32]; - y as *const i32; // This is a cast, not a coercion + y as *const i32; // This is a cast, not a coercion let p: *const _ = y; let p: *const [i32; 10] = y; diff --git a/tests/mir-opt/array_index_is_temporary.rs b/tests/mir-opt/array_index_is_temporary.rs index cd44c31d0004..771fb3771b5c 100644 --- a/tests/mir-opt/array_index_is_temporary.rs +++ b/tests/mir-opt/array_index_is_temporary.rs @@ -9,7 +9,6 @@ unsafe fn foo(z: *mut usize) -> u32 { 99 } - // EMIT_MIR array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.mir fn main() { // CHECK-LABEL: fn main( diff --git a/tests/mir-opt/building/custom/aggregate_exprs.rs b/tests/mir-opt/building/custom/aggregate_exprs.rs index d581886247ff..8985f106817b 100644 --- a/tests/mir-opt/building/custom/aggregate_exprs.rs +++ b/tests/mir-opt/building/custom/aggregate_exprs.rs @@ -7,18 +7,18 @@ use core::intrinsics::mir::*; // EMIT_MIR aggregate_exprs.tuple.built.after.mir #[custom_mir(dialect = "built")] fn tuple() -> (i32, bool) { - mir!( + mir! { { RET = (1, true); Return() } - ) + } } // EMIT_MIR aggregate_exprs.array.built.after.mir #[custom_mir(dialect = "built")] fn array() -> [i32; 2] { - mir!( + mir! { let x: [i32; 2]; let one: i32; { @@ -28,7 +28,7 @@ fn array() -> [i32; 2] { RET = Move(x); Return() } - ) + } } struct Foo { @@ -48,7 +48,7 @@ union Onion { // EMIT_MIR aggregate_exprs.adt.built.after.mir #[custom_mir(dialect = "built")] fn adt() -> Onion { - mir!( + mir! { let one: i32; let x: Foo; let y: Bar; @@ -62,7 +62,7 @@ fn adt() -> Onion { RET = Onion { neon: Field(Variant(y, 0), 1) }; Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/building/custom/arbitrary_let.rs b/tests/mir-opt/building/custom/arbitrary_let.rs index f8ee8504e322..3f251cd81bce 100644 --- a/tests/mir-opt/building/custom/arbitrary_let.rs +++ b/tests/mir-opt/building/custom/arbitrary_let.rs @@ -8,7 +8,7 @@ use core::ptr::{addr_of, addr_of_mut}; // EMIT_MIR arbitrary_let.arbitrary_let.built.after.mir #[custom_mir(dialect = "built")] fn arbitrary_let(x: i32) -> i32 { - mir!( + mir! { { let y = x; Goto(second) @@ -21,7 +21,7 @@ fn arbitrary_let(x: i32) -> i32 { let z = y; Goto(third) } - ) + } } fn main() { diff --git a/tests/mir-opt/building/custom/arrays.rs b/tests/mir-opt/building/custom/arrays.rs index e9a53b7aacb7..4bd6f93e1134 100644 --- a/tests/mir-opt/building/custom/arrays.rs +++ b/tests/mir-opt/building/custom/arrays.rs @@ -7,12 +7,14 @@ use core::intrinsics::mir::*; // EMIT_MIR arrays.arrays.built.after.mir #[custom_mir(dialect = "built")] fn arrays() -> usize { - mir!({ - let x = [5_i32; C]; - let c = Len(x); - RET = c; - Return() - }) + mir! { + { + let x = [5_i32; C]; + let c = Len(x); + RET = c; + Return() + } + } } fn main() { diff --git a/tests/mir-opt/building/custom/as_cast.rs b/tests/mir-opt/building/custom/as_cast.rs index 92aea64db07f..908d378771d5 100644 --- a/tests/mir-opt/building/custom/as_cast.rs +++ b/tests/mir-opt/building/custom/as_cast.rs @@ -7,34 +7,34 @@ use core::intrinsics::mir::*; // EMIT_MIR as_cast.int_to_int.built.after.mir #[custom_mir(dialect = "built")] fn int_to_int(x: u32) -> i32 { - mir!( + mir! { { RET = x as i32; Return() } - ) + } } // EMIT_MIR as_cast.float_to_int.built.after.mir #[custom_mir(dialect = "built")] fn float_to_int(x: f32) -> i32 { - mir!( + mir! { { RET = x as i32; Return() } - ) + } } // EMIT_MIR as_cast.int_to_ptr.built.after.mir #[custom_mir(dialect = "built")] fn int_to_ptr(x: usize) -> *const i32 { - mir!( + mir! { { RET = x as *const i32; Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/building/custom/assume.rs b/tests/mir-opt/building/custom/assume.rs index a477e12f0e03..4a55617136a1 100644 --- a/tests/mir-opt/building/custom/assume.rs +++ b/tests/mir-opt/building/custom/assume.rs @@ -7,34 +7,34 @@ use core::intrinsics::mir::*; // EMIT_MIR assume.assume_local.built.after.mir #[custom_mir(dialect = "built")] fn assume_local(x: bool) { - mir!( + mir! { { Assume(x); Return() } - ) + } } // EMIT_MIR assume.assume_place.built.after.mir #[custom_mir(dialect = "built")] fn assume_place(p: (bool, u8)) { - mir!( + mir! { { Assume(p.0); Return() } - ) + } } // EMIT_MIR assume.assume_constant.built.after.mir #[custom_mir(dialect = "built")] fn assume_constant() { - mir!( + mir! { { Assume(true); Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/building/custom/composite_return.rs b/tests/mir-opt/building/custom/composite_return.rs index 33c903fa0f89..0cf2cc8d1890 100644 --- a/tests/mir-opt/building/custom/composite_return.rs +++ b/tests/mir-opt/building/custom/composite_return.rs @@ -7,14 +7,14 @@ use core::intrinsics::mir::*; // EMIT_MIR composite_return.tuple.built.after.mir #[custom_mir(dialect = "runtime", phase = "optimized")] fn tuple() -> (i32, bool) { - mir!( + mir! { type RET = (i32, bool); { RET.0 = 1; RET.1 = true; Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/building/custom/consts.rs b/tests/mir-opt/building/custom/consts.rs index 1a410177fa54..c64709082dc3 100644 --- a/tests/mir-opt/building/custom/consts.rs +++ b/tests/mir-opt/building/custom/consts.rs @@ -9,14 +9,16 @@ const D: i32 = 5; // EMIT_MIR consts.consts.built.after.mir #[custom_mir(dialect = "built")] fn consts() { - mir!({ - let _a = 5_u8; - let _b = const { 5_i8 }; - let _c = C; - let _d = D; - let _e = consts::<10>; - Return() - }) + mir! { + { + let _a = 5_u8; + let _b = const { 5_i8 }; + let _c = C; + let _d = D; + let _e = consts::<10>; + Return() + } + } } static S: i32 = 0x05050505; @@ -24,11 +26,13 @@ static mut T: i32 = 0x0a0a0a0a; // EMIT_MIR consts.statics.built.after.mir #[custom_mir(dialect = "built")] fn statics() { - mir!({ - let _a: &i32 = Static(S); - let _b: *mut i32 = StaticMut(T); - Return() - }) + mir! { + { + let _a: &i32 = Static(S); + let _b: *mut i32 = StaticMut(T); + Return() + } + } } fn main() { diff --git a/tests/mir-opt/building/custom/debuginfo.rs b/tests/mir-opt/building/custom/debuginfo.rs index 3671a1ef0619..5ab83fd4214b 100644 --- a/tests/mir-opt/building/custom/debuginfo.rs +++ b/tests/mir-opt/building/custom/debuginfo.rs @@ -7,60 +7,62 @@ use core::intrinsics::mir::*; // EMIT_MIR debuginfo.pointee.built.after.mir #[custom_mir(dialect = "built")] fn pointee(opt: &mut Option) { - mir!( + mir! { debug foo => Field::(Variant(*opt, 1), 0); { Return() } - ) + } } // EMIT_MIR debuginfo.numbered.built.after.mir #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn numbered(i: (u32, i32)) { - mir!( + mir! { debug first => i.0; debug second => i.0; { Return() } - ) + } } -struct S { x: f32 } +struct S { + x: f32, +} // EMIT_MIR debuginfo.structured.built.after.mir #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn structured(i: S) { - mir!( + mir! { debug x => i.x; { Return() } - ) + } } // EMIT_MIR debuginfo.variant.built.after.mir #[custom_mir(dialect = "built")] fn variant(opt: Option) { - mir!( + mir! { debug inner => Field::(Variant(opt, 1), 0); { Return() } - ) + } } // EMIT_MIR debuginfo.variant_deref.built.after.mir #[custom_mir(dialect = "built")] fn variant_deref(opt: Option<&i32>) { - mir!( + mir! { debug pointer => Field::<&i32>(Variant(opt, 1), 0); debug deref => *Field::<&i32>(Variant(opt, 1), 0); { Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/building/custom/enums.rs b/tests/mir-opt/building/custom/enums.rs index 6aab1503c0a3..88ec228986ab 100644 --- a/tests/mir-opt/building/custom/enums.rs +++ b/tests/mir-opt/building/custom/enums.rs @@ -7,7 +7,7 @@ use core::intrinsics::mir::*; // EMIT_MIR enums.switch_bool.built.after.mir #[custom_mir(dialect = "built")] pub fn switch_bool(b: bool) -> u32 { - mir!( + mir! { { match b { true => t, @@ -25,13 +25,13 @@ pub fn switch_bool(b: bool) -> u32 { RET = 10; Return() } - ) + } } // EMIT_MIR enums.switch_option.built.after.mir #[custom_mir(dialect = "built")] pub fn switch_option(option: Option<()>) -> bool { - mir!( + mir! { { let discr = Discriminant(option); match discr { @@ -50,7 +50,7 @@ pub fn switch_option(option: Option<()>) -> bool { RET = true; Return() } - ) + } } #[repr(u8)] @@ -62,7 +62,7 @@ enum Bool { // EMIT_MIR enums.switch_option_repr.built.after.mir #[custom_mir(dialect = "built")] fn switch_option_repr(option: Bool) -> bool { - mir!( + mir! { { let discr = Discriminant(option); match discr { @@ -80,26 +80,30 @@ fn switch_option_repr(option: Bool) -> bool { RET = false; Return() } - ) + } } // EMIT_MIR enums.set_discr.built.after.mir #[custom_mir(dialect = "runtime", phase = "initial")] fn set_discr(option: &mut Option<()>) { - mir!({ - Deinit(*option); - SetDiscriminant(*option, 0); - Return() - }) + mir! { + { + Deinit(*option); + SetDiscriminant(*option, 0); + Return() + } + } } // EMIT_MIR enums.set_discr_repr.built.after.mir #[custom_mir(dialect = "runtime", phase = "initial")] fn set_discr_repr(b: &mut Bool) { - mir!({ - SetDiscriminant(*b, 0); - Return() - }) + mir! { + { + SetDiscriminant(*b, 0); + Return() + } + } } fn main() { diff --git a/tests/mir-opt/building/custom/operators.rs b/tests/mir-opt/building/custom/operators.rs index ff0e8dcbb415..07abf2d96517 100644 --- a/tests/mir-opt/building/custom/operators.rs +++ b/tests/mir-opt/building/custom/operators.rs @@ -6,37 +6,41 @@ use std::intrinsics::mir::*; // EMIT_MIR operators.f.built.after.mir #[custom_mir(dialect = "built")] pub fn f(a: i32, b: bool) -> i32 { - mir!({ - a = -a; - b = !b; - a = a + a; - a = a - a; - a = a * a; - a = a / a; - a = a % a; - a = a ^ a; - a = a & a; - a = a << a; - a = a >> a; - b = a == a; - b = a < a; - b = a <= a; - b = a >= a; - b = a > a; - let res = Checked(a + a); - b = res.1; - a = res.0; - RET = a; - Return() - }) + mir! { + { + a = -a; + b = !b; + a = a + a; + a = a - a; + a = a * a; + a = a / a; + a = a % a; + a = a ^ a; + a = a & a; + a = a << a; + a = a >> a; + b = a == a; + b = a < a; + b = a <= a; + b = a >= a; + b = a > a; + let res = Checked(a + a); + b = res.1; + a = res.0; + RET = a; + Return() + } + } } // EMIT_MIR operators.g.runtime.after.mir #[custom_mir(dialect = "runtime")] pub fn g(p: *const i32, q: *const [i32]) { - mir!({ - let a = PtrMetadata(p); - let b = PtrMetadata(q); - Return() - }) + mir! { + { + let a = PtrMetadata(p); + let b = PtrMetadata(q); + Return() + } + } } diff --git a/tests/mir-opt/building/custom/projections.rs b/tests/mir-opt/building/custom/projections.rs index ac23fe59097f..0250b9b84b62 100644 --- a/tests/mir-opt/building/custom/projections.rs +++ b/tests/mir-opt/building/custom/projections.rs @@ -12,74 +12,84 @@ union U { // EMIT_MIR projections.unions.built.after.mir #[custom_mir(dialect = "built")] fn unions(u: U) -> i32 { - mir!({ - RET = u.a; - Return() - }) + mir! { + { + RET = u.a; + Return() + } + } } // EMIT_MIR projections.tuples.built.after.mir #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn tuples(i: (u32, i32)) -> (u32, i32) { - mir!( + mir! { type RET = (u32, i32); { RET.0 = i.0; RET.1 = i.1; Return() } - ) + } } // EMIT_MIR projections.unwrap.built.after.mir #[custom_mir(dialect = "built")] fn unwrap(opt: Option) -> i32 { - mir!({ - RET = Field(Variant(opt, 1), 0); - Return() - }) + mir! { + { + RET = Field(Variant(opt, 1), 0); + Return() + } + } } // EMIT_MIR projections.unwrap_deref.built.after.mir #[custom_mir(dialect = "built")] fn unwrap_deref(opt: Option<&i32>) -> i32 { - mir!({ - RET = *Field::<&i32>(Variant(opt, 1), 0); - Return() - }) + mir! { + { + RET = *Field::<&i32>(Variant(opt, 1), 0); + Return() + } + } } // EMIT_MIR projections.set.built.after.mir #[custom_mir(dialect = "built")] fn set(opt: &mut Option) { - mir!({ - place!(Field(Variant(*opt, 1), 0)) = 10; - Return() - }) + mir! { + { + place!(Field(Variant(*opt, 1), 0)) = 10; + Return() + } + } } // EMIT_MIR projections.simple_index.built.after.mir #[custom_mir(dialect = "built")] fn simple_index(a: [i32; 10], b: &[i32]) -> i32 { - mir!({ - let temp = 3; - RET = a[temp]; - RET = (*b)[temp]; - Return() - }) + mir! { + { + let temp = 3; + RET = a[temp]; + RET = (*b)[temp]; + Return() + } + } } // EMIT_MIR projections.copy_for_deref.built.after.mir #[custom_mir(dialect = "runtime", phase = "initial")] fn copy_for_deref(x: (&i32, i32)) -> i32 { - mir!( + mir! { let temp: &i32; { temp = CopyForDeref(x.0); RET = *temp; Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/building/custom/references.rs b/tests/mir-opt/building/custom/references.rs index 04afe6e6494b..7ea8f8b4c156 100644 --- a/tests/mir-opt/building/custom/references.rs +++ b/tests/mir-opt/building/custom/references.rs @@ -8,31 +8,29 @@ use core::ptr::{addr_of, addr_of_mut}; // EMIT_MIR references.mut_ref.built.after.mir #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn mut_ref(x: &mut i32) -> &mut i32 { - mir!( + mir! { let t: *mut i32; - { t = addr_of_mut!(*x); RET = &mut *t; Retag(RET); Return() } - ) + } } // EMIT_MIR references.immut_ref.built.after.mir #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn immut_ref(x: &i32) -> &i32 { - mir!( + mir! { let t: *const i32; - { t = addr_of!(*x); RET = & *t; Retag(RET); Return() } - ) + } } // EMIT_MIR references.raw_pointer.built.after.mir @@ -40,19 +38,23 @@ pub fn immut_ref(x: &i32) -> &i32 { pub fn raw_pointer(x: *const i32) -> *const i32 { // Regression test for a bug in which unsafetyck was not correctly turned off for // `dialect = "built"` - mir!({ - RET = addr_of!(*x); - Return() - }) + mir! { + { + RET = addr_of!(*x); + Return() + } + } } // EMIT_MIR references.raw_pointer_offset.built.after.mir #[custom_mir(dialect = "built")] pub fn raw_pointer_offset(x: *const i32) -> *const i32 { - mir!({ - RET = Offset(x, 1_isize); - Return() - }) + mir! { + { + RET = Offset(x, 1_isize); + Return() + } + } } fn main() { diff --git a/tests/mir-opt/building/custom/simple_assign.rs b/tests/mir-opt/building/custom/simple_assign.rs index 8442272291e1..d6d054ab5a38 100644 --- a/tests/mir-opt/building/custom/simple_assign.rs +++ b/tests/mir-opt/building/custom/simple_assign.rs @@ -7,32 +7,32 @@ use core::intrinsics::mir::*; // EMIT_MIR simple_assign.simple.built.after.mir #[custom_mir(dialect = "built")] pub fn simple(x: i32) -> i32 { - mir!( + mir! { let temp1: i32; let temp2: _; - { StorageLive(temp1); temp1 = x; Goto(exit) } - exit = { temp2 = Move(temp1); StorageDead(temp1); RET = temp2; Return() } - ) + } } // EMIT_MIR simple_assign.simple_ref.built.after.mir #[custom_mir(dialect = "built")] pub fn simple_ref(x: &mut i32) -> &mut i32 { - mir!({ - RET = Move(x); - Return() - }) + mir! { + { + RET = Move(x); + Return() + } + } } fn main() { diff --git a/tests/mir-opt/building/custom/terminators.rs b/tests/mir-opt/building/custom/terminators.rs index 01c132cf3e77..a8e0b4b35bf4 100644 --- a/tests/mir-opt/building/custom/terminators.rs +++ b/tests/mir-opt/building/custom/terminators.rs @@ -11,7 +11,7 @@ fn ident(t: T) -> T { // EMIT_MIR terminators.direct_call.built.after.mir #[custom_mir(dialect = "built")] fn direct_call(x: i32) -> i32 { - mir!( + mir! { { Call(RET = ident(x), ReturnTo(retblock), UnwindContinue()) } @@ -19,21 +19,20 @@ fn direct_call(x: i32) -> i32 { retblock = { Return() } - ) + } } // EMIT_MIR terminators.indirect_call.built.after.mir #[custom_mir(dialect = "built")] fn indirect_call(x: i32, f: fn(i32) -> i32) -> i32 { - mir!( + mir! { { Call(RET = f(x), ReturnTo(retblock), UnwindContinue()) } - retblock = { Return() } - ) + } } struct WriteOnDrop<'a>(&'a mut i32, i32); @@ -47,51 +46,47 @@ impl<'a> Drop for WriteOnDrop<'a> { // EMIT_MIR terminators.drop_first.built.after.mir #[custom_mir(dialect = "built")] fn drop_first<'a>(a: WriteOnDrop<'a>, b: WriteOnDrop<'a>) { - mir!( + mir! { { Drop(a, ReturnTo(retblock), UnwindContinue()) } - retblock = { a = Move(b); Return() } - ) + } } // EMIT_MIR terminators.drop_second.built.after.mir #[custom_mir(dialect = "built")] fn drop_second<'a>(a: WriteOnDrop<'a>, b: WriteOnDrop<'a>) { - mir!( + mir! { { Drop(b, ReturnTo(retblock), UnwindContinue()) } - retblock = { Return() } - ) + } } // EMIT_MIR terminators.assert_nonzero.built.after.mir #[custom_mir(dialect = "built")] fn assert_nonzero(a: i32) { - mir!( + mir! { { match a { 0 => unreachable, _ => retblock } } - unreachable = { Unreachable() } - retblock = { Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/building/custom/unwind_action.rs b/tests/mir-opt/building/custom/unwind_action.rs index e3d54c721457..87aab1ea70c6 100644 --- a/tests/mir-opt/building/custom/unwind_action.rs +++ b/tests/mir-opt/building/custom/unwind_action.rs @@ -9,14 +9,14 @@ use core::intrinsics::mir::*; // CHECK-NEXT: a() -> [return: bb1, unwind unreachable]; #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn a() { - mir!( + mir! { { Call(RET = a(), ReturnTo(bb1), UnwindUnreachable()) } bb1 = { Return() } - ) + } } // CHECK-LABEL: fn b() @@ -24,14 +24,14 @@ pub fn a() { // CHECK-NEXT: b() -> [return: bb1, unwind continue]; #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn b() { - mir!( + mir! { { Call(RET = b(), ReturnTo(bb1), UnwindContinue()) } bb1 = { Return() } - ) + } } // CHECK-LABEL: fn c() @@ -39,14 +39,14 @@ pub fn b() { // CHECK-NEXT: c() -> [return: bb1, unwind terminate(abi)]; #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn c() { - mir!( + mir! { { Call(RET = c(), ReturnTo(bb1), UnwindTerminate(ReasonAbi)) } bb1 = { Return() } - ) + } } // CHECK-LABEL: fn d() @@ -54,7 +54,7 @@ pub fn c() { // CHECK-NEXT: d() -> [return: bb1, unwind: bb2]; #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn d() { - mir!( + mir! { { Call(RET = d(), ReturnTo(bb1), UnwindCleanup(bb2)) } @@ -64,5 +64,5 @@ pub fn d() { bb2 (cleanup) = { UnwindResume() } - ) + } } diff --git a/tests/mir-opt/building/custom/unwind_terminate.rs b/tests/mir-opt/building/custom/unwind_terminate.rs index c5374fa7b690..9b495d52387d 100644 --- a/tests/mir-opt/building/custom/unwind_terminate.rs +++ b/tests/mir-opt/building/custom/unwind_terminate.rs @@ -8,14 +8,14 @@ use core::intrinsics::mir::*; // CHECK-NEXT: terminate(abi); #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn f() { - mir!( + mir! { { Return() } bb1(cleanup) = { UnwindTerminate(ReasonAbi) } - ) + } } // CHECK-LABEL: fn g() @@ -23,12 +23,12 @@ pub fn f() { // CHECK-NEXT: terminate(cleanup); #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn g() { - mir!( + mir! { { Return() } bb1(cleanup) = { UnwindTerminate(ReasonInCleanup) } - ) + } } diff --git a/tests/mir-opt/building/enum_cast.rs b/tests/mir-opt/building/enum_cast.rs index df8e397c8fec..7ff0cdbfe8df 100644 --- a/tests/mir-opt/building/enum_cast.rs +++ b/tests/mir-opt/building/enum_cast.rs @@ -5,21 +5,24 @@ // EMIT_MIR enum_cast.far.built.after.mir enum Foo { - A + A, } enum Bar { - A, B + A, + B, } #[repr(u8)] enum Boo { - A, B + A, + B, } #[repr(i16)] enum Far { - A, B + A, + B, } fn foo(foo: Foo) -> usize { @@ -40,7 +43,9 @@ fn far(far: Far) -> isize { // EMIT_MIR enum_cast.droppy.built.after.mir enum Droppy { - A, B, C + A, + B, + C, } impl Drop for Droppy { @@ -82,12 +87,15 @@ fn unsigny(x: UnsignedAroundZero) -> u16 { x as u16 } -enum NotStartingAtZero { A = 4, B = 6, C = 8 } +enum NotStartingAtZero { + A = 4, + B = 6, + C = 8, +} // EMIT_MIR enum_cast.offsetty.built.after.mir fn offsetty(x: NotStartingAtZero) -> u32 { x as u32 } -fn main() { -} +fn main() {} diff --git a/tests/mir-opt/building/logical_or_in_conditional.rs b/tests/mir-opt/building/logical_or_in_conditional.rs index deb841f2b0d5..e6872e6f2ec8 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.rs +++ b/tests/mir-opt/building/logical_or_in_conditional.rs @@ -30,9 +30,13 @@ fn test_or() { // EMIT_MIR logical_or_in_conditional.test_complex.built.after.mir fn test_complex() { - if let E::A(_) = E::f() && ((always_true() && Droppy(0).0 > 0) || Droppy(1).0 > 1) {} + if let E::A(_) = E::f() + && ((always_true() && Droppy(0).0 > 0) || Droppy(1).0 > 1) + {} - if !always_true() && let E::B = E::f() {} + if !always_true() + && let E::B = E::f() + {} } fn main() { diff --git a/tests/mir-opt/building/match/simple_match.rs b/tests/mir-opt/building/match/simple_match.rs index 4f0a3046a061..61c337822c85 100644 --- a/tests/mir-opt/building/match/simple_match.rs +++ b/tests/mir-opt/building/match/simple_match.rs @@ -1,7 +1,6 @@ // skip-filecheck // Test that we don't generate unnecessarily large MIR for very simple matches - // EMIT_MIR simple_match.match_bool.built.after.mir fn match_bool(x: bool) -> usize { match x { diff --git a/tests/mir-opt/building/shifts.rs b/tests/mir-opt/building/shifts.rs index 849d7b55f3a0..d7747bb2f784 100644 --- a/tests/mir-opt/building/shifts.rs +++ b/tests/mir-opt/building/shifts.rs @@ -3,19 +3,12 @@ // EMIT_MIR shifts.shift_signed.built.after.mir fn shift_signed(small: i8, big: u128, a: i8, b: i32, c: i128) -> ([i8; 3], [u128; 3]) { - ( - [small >> a, small >> b, small >> c], - [big << a, big << b, big << c], - ) + ([small >> a, small >> b, small >> c], [big << a, big << b, big << c]) } // EMIT_MIR shifts.shift_unsigned.built.after.mir fn shift_unsigned(small: u8, big: i128, a: u8, b: u32, c: u128) -> ([u8; 3], [i128; 3]) { - ( - [small >> a, small >> b, small >> c], - [big << a, big << b, big << c], - ) + ([small >> a, small >> b, small >> c], [big << a, big << b, big << c]) } -fn main() { -} +fn main() {} diff --git a/tests/mir-opt/building/storage_live_dead_in_statics.rs b/tests/mir-opt/building/storage_live_dead_in_statics.rs index 1f5692118545..7cb74acbf060 100644 --- a/tests/mir-opt/building/storage_live_dead_in_statics.rs +++ b/tests/mir-opt/building/storage_live_dead_in_statics.rs @@ -3,6 +3,7 @@ // generate `StorageStart` or `StorageEnd` statements. // EMIT_MIR storage_live_dead_in_statics.XXX.built.after.mir +#[rustfmt::skip] static XXX: &'static Foo = &Foo { tup: "hi", data: &[ @@ -20,13 +21,13 @@ static XXX: &'static Foo = &Foo { (0, 1), (0, 2), (0, 3), (0, 1), (0, 2), (0, 3), (0, 1), (0, 2), (0, 3), - ] + ], }; #[derive(Debug)] struct Foo { tup: &'static str, - data: &'static [(u32, u32)] + data: &'static [(u32, u32)], } fn main() { diff --git a/tests/mir-opt/const_prop/control_flow_simplification.rs b/tests/mir-opt/const_prop/control_flow_simplification.rs index 39b5f2898306..64605ca11c2c 100644 --- a/tests/mir-opt/const_prop/control_flow_simplification.rs +++ b/tests/mir-opt/const_prop/control_flow_simplification.rs @@ -11,7 +11,7 @@ impl NeedsDrop for This {} // EMIT_MIR control_flow_simplification.hello.GVN.diff // EMIT_MIR control_flow_simplification.hello.PreCodegen.before.mir -fn hello(){ +fn hello() { if ::NEEDS { panic!() } diff --git a/tests/mir-opt/const_prop/invalid_constant.rs b/tests/mir-opt/const_prop/invalid_constant.rs index 2b7271f63ff2..91ee36ae2c54 100644 --- a/tests/mir-opt/const_prop/invalid_constant.rs +++ b/tests/mir-opt/const_prop/invalid_constant.rs @@ -8,7 +8,11 @@ #[derive(Copy, Clone)] #[repr(u32)] -enum E { A, B, C } +enum E { + A, + B, + C, +} #[derive(Copy, Clone)] enum Empty {} @@ -39,7 +43,5 @@ fn main() { // A non-UTF-8 string slice. Regression test for #75763 and #78520. struct Str; - let _non_utf8_str: Str::<{ - unsafe { std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) } - }>; + let _non_utf8_str: Str<{ unsafe { std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) } }>; } diff --git a/tests/mir-opt/const_prop/offset_of.rs b/tests/mir-opt/const_prop/offset_of.rs index 105cbfb53dd0..264c8a3d21cd 100644 --- a/tests/mir-opt/const_prop/offset_of.rs +++ b/tests/mir-opt/const_prop/offset_of.rs @@ -31,7 +31,7 @@ struct Delta { enum Epsilon { A(u8, u16), B, - C { c: u32 } + C { c: u32 }, } enum Zeta { diff --git a/tests/mir-opt/const_prop/pointer_expose_provenance.rs b/tests/mir-opt/const_prop/pointer_expose_provenance.rs index f148a5b6542e..a76fead98594 100644 --- a/tests/mir-opt/const_prop/pointer_expose_provenance.rs +++ b/tests/mir-opt/const_prop/pointer_expose_provenance.rs @@ -2,7 +2,7 @@ //@ test-mir-pass: GVN #[inline(never)] -fn read(_: usize) { } +fn read(_: usize) {} // EMIT_MIR pointer_expose_provenance.main.GVN.diff fn main() { diff --git a/tests/mir-opt/const_prop/scalar_literal_propagation.rs b/tests/mir-opt/const_prop/scalar_literal_propagation.rs index 9d02f24e76bd..15e32490de49 100644 --- a/tests/mir-opt/const_prop/scalar_literal_propagation.rs +++ b/tests/mir-opt/const_prop/scalar_literal_propagation.rs @@ -10,4 +10,4 @@ fn main() { } #[inline(never)] -fn consume(_: u32) { } +fn consume(_: u32) {} diff --git a/tests/mir-opt/const_prop/switch_int.rs b/tests/mir-opt/const_prop/switch_int.rs index 114380e316de..4ee4182caf6a 100644 --- a/tests/mir-opt/const_prop/switch_int.rs +++ b/tests/mir-opt/const_prop/switch_int.rs @@ -3,7 +3,7 @@ // EMIT_MIR_FOR_EACH_PANIC_STRATEGY #[inline(never)] -fn foo(_: i32) { } +fn foo(_: i32) {} // EMIT_MIR switch_int.main.GVN.diff // EMIT_MIR switch_int.main.SimplifyConstCondition-after-const-prop.diff diff --git a/tests/mir-opt/const_prop/transmute.rs b/tests/mir-opt/const_prop/transmute.rs index 9cbf8928753b..892b91a5414c 100644 --- a/tests/mir-opt/const_prop/transmute.rs +++ b/tests/mir-opt/const_prop/transmute.rs @@ -45,7 +45,10 @@ pub unsafe fn undef_union_as_integer() -> u32 { // CHECK-LABEL: fn undef_union_as_integer( // CHECK: _1 = Union32 { // CHECK: _0 = move _1 as u32 (Transmute); - union Union32 { value: u32, unit: () } + union Union32 { + value: u32, + unit: (), + } unsafe { transmute(Union32 { unit: () }) } } diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.rs b/tests/mir-opt/const_prop/tuple_literal_propagation.rs index 582411c7b59e..e42a62cb6fdf 100644 --- a/tests/mir-opt/const_prop/tuple_literal_propagation.rs +++ b/tests/mir-opt/const_prop/tuple_literal_propagation.rs @@ -10,4 +10,4 @@ fn main() { } #[inline(never)] -fn consume(_: (u32, u32)) { } +fn consume(_: (u32, u32)) {} diff --git a/tests/mir-opt/copy-prop/borrowed_local.rs b/tests/mir-opt/copy-prop/borrowed_local.rs index 512287dd1767..dd1679513f6c 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.rs +++ b/tests/mir-opt/copy-prop/borrowed_local.rs @@ -4,10 +4,12 @@ #![feature(custom_mir, core_intrinsics, freeze)] #![allow(unused_assignments)] extern crate core; -use core::marker::Freeze; use core::intrinsics::mir::*; +use core::marker::Freeze; -fn opaque(_: impl Sized) -> bool { true } +fn opaque(_: impl Sized) -> bool { + true +} fn cmp_ref(a: &u8, b: &u8) -> bool { std::ptr::eq(a as *const u8, b as *const u8) @@ -24,7 +26,7 @@ fn compare_address() -> bool { // CHECK-NEXT: _0 = cmp_ref(_2, _4) // CHECK: bb1: { // CHECK-NEXT: _0 = opaque::(_3) - mir!( + mir! { { let a = 5_u8; let r1 = &a; @@ -40,7 +42,7 @@ fn compare_address() -> bool { ret = { Return() } - ) + } } /// Generic type `T` is `Freeze`, so shared borrows are immutable. @@ -52,7 +54,7 @@ fn borrowed(x: T) -> bool { // CHECK-NEXT: _0 = opaque::<&T>(_3) // CHECK: bb1: { // CHECK-NEXT: _0 = opaque::(_1) - mir!( + mir! { { let a = x; let r1 = &x; @@ -64,7 +66,7 @@ fn borrowed(x: T) -> bool { ret = { Return() } - ) + } } /// Generic type `T` is not known to be `Freeze`, so shared borrows may be mutable. @@ -77,7 +79,7 @@ fn non_freeze(x: T) -> bool { // CHECK-NEXT: _0 = opaque::<&T>(_3) // CHECK: bb1: { // CHECK-NEXT: _0 = opaque::(_2) - mir!( + mir! { { let a = x; let r1 = &x; @@ -89,7 +91,7 @@ fn non_freeze(x: T) -> bool { ret = { Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/copy-prop/custom_move_arg.rs b/tests/mir-opt/copy-prop/custom_move_arg.rs index a82d4618e68c..3dce7807b347 100644 --- a/tests/mir-opt/copy-prop/custom_move_arg.rs +++ b/tests/mir-opt/copy-prop/custom_move_arg.rs @@ -12,17 +12,19 @@ struct NotCopy(bool); // EMIT_MIR custom_move_arg.f.CopyProp.diff #[custom_mir(dialect = "runtime")] fn f(_1: NotCopy) { - mir!({ - let _2 = _1; - Call(RET = opaque(Move(_1)), ReturnTo(bb1), UnwindUnreachable()) + mir! { + { + let _2 = _1; + Call(RET = opaque(Move(_1)), ReturnTo(bb1), UnwindUnreachable()) + } + bb1 = { + let _3 = Move(_2); + Call(RET = opaque(_3), ReturnTo(bb2), UnwindUnreachable()) + } + bb2 = { + Return() + } } - bb1 = { - let _3 = Move(_2); - Call(RET = opaque(_3), ReturnTo(bb2), UnwindUnreachable()) - } - bb2 = { - Return() - }) } #[inline(never)] diff --git a/tests/mir-opt/copy-prop/move_projection.rs b/tests/mir-opt/copy-prop/move_projection.rs index 231e4082e33b..0ac1c4e0ba26 100644 --- a/tests/mir-opt/copy-prop/move_projection.rs +++ b/tests/mir-opt/copy-prop/move_projection.rs @@ -7,13 +7,15 @@ extern crate core; use core::intrinsics::mir::*; -fn opaque(_: impl Sized) -> bool { true } +fn opaque(_: impl Sized) -> bool { + true +} struct Foo(u8); #[custom_mir(dialect = "runtime")] fn f(a: Foo) -> bool { - mir!( + mir! { { let b = a; // This is a move out of a copy, so must become a copy of `a.0`. @@ -26,7 +28,7 @@ fn f(a: Foo) -> bool { ret = { Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/copy-prop/mutate_through_pointer.rs b/tests/mir-opt/copy-prop/mutate_through_pointer.rs index 14ca513c6927..53cca045248d 100644 --- a/tests/mir-opt/copy-prop/mutate_through_pointer.rs +++ b/tests/mir-opt/copy-prop/mutate_through_pointer.rs @@ -18,14 +18,16 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn f(c: bool) -> bool { - mir!({ - let a = c; - let p = core::ptr::addr_of!(a); - let p2 = core::ptr::addr_of_mut!(*p); - *p2 = false; - RET = c; - Return() - }) + mir! { + { + let a = c; + let p = core::ptr::addr_of!(a); + let p2 = core::ptr::addr_of_mut!(*p); + *p2 = false; + RET = c; + Return() + } + } } fn main() { diff --git a/tests/mir-opt/copy-prop/non_dominate.rs b/tests/mir-opt/copy-prop/non_dominate.rs index 34e7eabc81a2..c01275370ea7 100644 --- a/tests/mir-opt/copy-prop/non_dominate.rs +++ b/tests/mir-opt/copy-prop/non_dominate.rs @@ -8,16 +8,28 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn f(c: bool) -> bool { - mir!( + mir! { let a: bool; let b: bool; - { Goto(bb1) } - bb1 = { b = c; match b { false => bb3, _ => bb2 }} + { + Goto(bb1) + } + bb1 = { + b = c; + match b { false => bb3, _ => bb2 } + } // This assignment to `a` does not dominate the use in `bb3`. // It should not be replaced by `b`. - bb2 = { a = b; c = false; Goto(bb1) } - bb3 = { RET = a; Return() } - ) + bb2 = { + a = b; + c = false; + Goto(bb1) + } + bb3 = { + RET = a; + Return() + } + } } fn main() { diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index 5c52f92cd8f1..946cfa4c76c0 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -8,7 +8,7 @@ use std::intrinsics::mir::*; #[derive(Copy, Clone)] enum E { V1(i32), - V2(i32) + V2(i32), } // EMIT_MIR enum.simple.DataflowConstProp.diff @@ -23,7 +23,10 @@ fn simple() { // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb2, otherwise: bb1]; // CHECK: [[target_bb]]: { // CHECK: [[x]] = const 0_i32; - let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 }; + let x = match e { + E::V1(x1) => x1, + E::V2(x2) => x2, + }; } // EMIT_MIR enum.constant.DataflowConstProp.diff @@ -39,7 +42,10 @@ fn constant() { // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb2, otherwise: bb1]; // CHECK: [[target_bb]]: { // CHECK: [[x]] = const 0_i32; - let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 }; + let x = match e { + E::V1(x1) => x1, + E::V2(x2) => x2, + }; } // EMIT_MIR enum.statics.DataflowConstProp.diff @@ -58,7 +64,10 @@ fn statics() { // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb2, otherwise: bb1]; // CHECK: [[target_bb]]: { // CHECK: [[x1]] = const 0_i32; - let x1 = match e1 { E::V1(x11) => x11, E::V2(x12) => x12 }; + let x1 = match e1 { + E::V1(x11) => x11, + E::V2(x12) => x12, + }; static RC: &E = &E::V2(4); @@ -72,7 +81,10 @@ fn statics() { // One is `_9 = &(*_12) and another is `_9 = _11`. It is different from what we can // get by printing MIR directly. It is better to check if there are any bugs in the // MIR passes around this stage. - let x2 = match e2 { E::V1(x21) => x21, E::V2(x22) => x22 }; + let x2 = match e2 { + E::V1(x21) => x21, + E::V2(x22) => x22, + }; } #[rustc_layout_scalar_valid_range_start(1)] @@ -84,7 +96,7 @@ struct NonZeroUsize(usize); // CHECK-LABEL: fn mutate_discriminant( #[custom_mir(dialect = "runtime", phase = "post-cleanup")] fn mutate_discriminant() -> u8 { - mir!( + mir! { let x: Option; { SetDiscriminant(x, 1); @@ -109,7 +121,7 @@ fn mutate_discriminant() -> u8 { RET = 2; Unreachable() } - ) + } } // EMIT_MIR enum.multiple.DataflowConstProp.diff @@ -132,7 +144,10 @@ fn multiple(x: bool, i: u8) { // CHECK: [[x2]] = const 0_u8; // CHECK: [[some:_.*]] = (({{_.*}} as Some).0: u8) // CHECK: [[x2]] = [[some]]; - let x2 = match e { Some(i) => i, None => 0 }; + let x2 = match e { + Some(i) => i, + None => 0, + }; // Therefore, `x2` should be `Top` here, and no replacement shall happen. diff --git a/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs b/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs index 3cd0b715a521..26f79c8c0e48 100644 --- a/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs +++ b/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs @@ -2,9 +2,9 @@ // EMIT_MIR mult_by_zero.test.DataflowConstProp.diff // CHECK-LABEL: fn test( -fn test(x : i32) -> i32 { - x * 0 - // CHECK: _0 = const 0_i32; +fn test(x: i32) -> i32 { + x * 0 + // CHECK: _0 = const 0_i32; } fn main() { diff --git a/tests/mir-opt/dataflow-const-prop/transmute.rs b/tests/mir-opt/dataflow-const-prop/transmute.rs index e7f93f421cf8..d0391f6974b4 100644 --- a/tests/mir-opt/dataflow-const-prop/transmute.rs +++ b/tests/mir-opt/dataflow-const-prop/transmute.rs @@ -45,7 +45,10 @@ pub unsafe fn undef_union_as_integer() -> u32 { // CHECK-LABEL: fn undef_union_as_integer( // CHECK: _1 = Union32 { // CHECK: _0 = move _1 as u32 (Transmute); - union Union32 { value: u32, unit: () } + union Union32 { + value: u32, + unit: (), + } unsafe { transmute(Union32 { unit: () }) } } diff --git a/tests/mir-opt/dead-store-elimination/call_arg_copy.rs b/tests/mir-opt/dead-store-elimination/call_arg_copy.rs index edb35061cc65..2556848ec462 100644 --- a/tests/mir-opt/dead-store-elimination/call_arg_copy.rs +++ b/tests/mir-opt/dead-store-elimination/call_arg_copy.rs @@ -29,7 +29,7 @@ struct Packed { fn move_packed(packed: Packed) { // CHECK-LABEL: fn move_packed( // CHECK: = use_both(const 0_i32, (_1.1: i32)) - mir!( + mir! { { // We have a packed struct, verify that the copy is not turned into a move. Call(RET = use_both(0, packed.y), ReturnTo(ret), UnwindContinue()) @@ -37,7 +37,7 @@ fn move_packed(packed: Packed) { ret = { Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/dead-store-elimination/cycle.rs b/tests/mir-opt/dead-store-elimination/cycle.rs index 795d57d36f52..c8f0c2644ab3 100644 --- a/tests/mir-opt/dead-store-elimination/cycle.rs +++ b/tests/mir-opt/dead-store-elimination/cycle.rs @@ -20,7 +20,7 @@ fn cycle(mut x: i32, mut y: i32, mut z: i32) { // CHECK-NOT: {{_.*}} = move {{_.*}}; // We use custom MIR to avoid generating debuginfo, that would force to preserve writes. - mir!( + mir! { let condition: bool; { Call(condition = cond(), ReturnTo(bb1), UnwindContinue()) @@ -38,7 +38,7 @@ fn cycle(mut x: i32, mut y: i32, mut z: i32) { ret = { Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/derefer_complex_case.rs b/tests/mir-opt/derefer_complex_case.rs index b1fa2c8733ef..96034522b9fe 100644 --- a/tests/mir-opt/derefer_complex_case.rs +++ b/tests/mir-opt/derefer_complex_case.rs @@ -4,5 +4,7 @@ // EMIT_MIR_FOR_EACH_PANIC_STRATEGY fn main() { - for &foo in &[42, 43] { drop(foo) } + for &foo in &[42, 43] { + drop(foo) + } } diff --git a/tests/mir-opt/derefer_terminator_test.rs b/tests/mir-opt/derefer_terminator_test.rs index 5de6a61eaf2c..fd16c6c2045e 100644 --- a/tests/mir-opt/derefer_terminator_test.rs +++ b/tests/mir-opt/derefer_terminator_test.rs @@ -7,7 +7,9 @@ fn main() { let b = foo(); let d = foo(); match ****(&&&&b) { - true => {let x = 5;}, + true => { + let x = 5; + } false => {} } let y = 42; diff --git a/tests/mir-opt/derefer_test.rs b/tests/mir-opt/derefer_test.rs index 3ca2144e4fc4..5676fa657fe9 100644 --- a/tests/mir-opt/derefer_test.rs +++ b/tests/mir-opt/derefer_test.rs @@ -2,7 +2,7 @@ //@ test-mir-pass: Derefer // EMIT_MIR derefer_test.main.Derefer.diff fn main() { - let mut a = (42,43); + let mut a = (42, 43); let mut b = (99, &mut a); let x = &mut (*b.1).0; let y = &mut (*b.1).1; diff --git a/tests/mir-opt/derefer_test_multiple.rs b/tests/mir-opt/derefer_test_multiple.rs index 145a19ee6a3c..7c03af00e1e6 100644 --- a/tests/mir-opt/derefer_test_multiple.rs +++ b/tests/mir-opt/derefer_test_multiple.rs @@ -1,7 +1,7 @@ // skip-filecheck //@ test-mir-pass: Derefer // EMIT_MIR derefer_test_multiple.main.Derefer.diff -fn main () { +fn main() { let mut a = (42, 43); let mut b = (99, &mut a); let mut c = (11, &mut b); diff --git a/tests/mir-opt/enum_opt.rs b/tests/mir-opt/enum_opt.rs index cacc7301f122..2cc5df84d6b5 100644 --- a/tests/mir-opt/enum_opt.rs +++ b/tests/mir-opt/enum_opt.rs @@ -7,22 +7,22 @@ // Tests that an enum with a variant with no data gets correctly transformed. pub enum NoData { - Large([u8; 8196]), - None, + Large([u8; 8196]), + None, } // Tests that an enum with a variant with data that is a valid candidate gets transformed. pub enum Candidate { - Small(u8), - Large([u8; 8196]), + Small(u8), + Large([u8; 8196]), } // Tests that an enum which has a discriminant much higher than the variant does not get // tformed. #[repr(u32)] pub enum InvalidIdxs { - A = 302, - Large([u64; 1024]), + A = 302, + Large([u64; 1024]), } // Tests that an enum with too high of a discriminant index (not in bounds of usize) does not @@ -37,51 +37,51 @@ pub enum NotTrunctable { // Tests that an enum with discriminants in random order still gets tformed correctly. #[repr(u32)] pub enum RandOrderDiscr { - A = 13, - B([u8; 1024]) = 5, - C = 7, + A = 13, + B([u8; 1024]) = 5, + C = 7, } // EMIT_MIR enum_opt.unin.EnumSizeOpt.diff pub fn unin() -> NoData { - let mut a = NoData::None; - a = NoData::Large([1; 8196]); - a + let mut a = NoData::None; + a = NoData::Large([1; 8196]); + a } // EMIT_MIR enum_opt.cand.EnumSizeOpt.diff pub fn cand() -> Candidate { - let mut a = Candidate::Small(1); - a = Candidate::Large([1; 8196]); - a + let mut a = Candidate::Small(1); + a = Candidate::Large([1; 8196]); + a } // EMIT_MIR enum_opt.invalid.EnumSizeOpt.diff pub fn invalid() -> InvalidIdxs { - let mut a = InvalidIdxs::A; - a = InvalidIdxs::Large([0; 1024]); - a + let mut a = InvalidIdxs::A; + a = InvalidIdxs::Large([0; 1024]); + a } // EMIT_MIR enum_opt.trunc.EnumSizeOpt.diff pub fn trunc() -> NotTrunctable { - let mut a = NotTrunctable::A; - a = NotTrunctable::B([0; 1024]); - a = NotTrunctable::C([0; 4096]); - a + let mut a = NotTrunctable::A; + a = NotTrunctable::B([0; 1024]); + a = NotTrunctable::C([0; 4096]); + a } pub fn rand_order() -> RandOrderDiscr { - let mut a = RandOrderDiscr::A; - a = RandOrderDiscr::B([0; 1024]); - a = RandOrderDiscr::C; - a + let mut a = RandOrderDiscr::A; + a = RandOrderDiscr::B([0; 1024]); + a = RandOrderDiscr::C; + a } pub fn main() { - unin(); - cand(); - invalid(); - trunc(); - rand_order(); + unin(); + cand(); + invalid(); + trunc(); + rand_order(); } diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 9be305152835..315377e4356f 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -539,7 +539,7 @@ fn slices() { #[custom_mir(dialect = "analysis")] fn duplicate_slice() -> (bool, bool) { // CHECK-LABEL: fn duplicate_slice( - mir!( + mir! { let au: u128; let bu: u128; let cu: u128; @@ -585,7 +585,7 @@ fn duplicate_slice() -> (bool, bool) { RET = (direct, indirect); Return() } - ) + } } fn repeat() { @@ -623,11 +623,13 @@ fn fn_pointers() { fn indirect_static() { static A: Option = None; - mir!({ - let ptr = Static(A); - let out = Field::(Variant(*ptr, 1), 0); - Return() - }) + mir! { + { + let ptr = Static(A); + let out = Field::(Variant(*ptr, 1), 0); + Return() + } + } } /// Verify that having constant index `u64::MAX` does not yield to an overflow in rustc. @@ -733,7 +735,7 @@ fn borrowed(x: T) { // CHECK-NEXT: _0 = opaque::(_1) // CHECK: bb2: { // CHECK-NEXT: _0 = opaque::(_1) - mir!( + mir! { { let a = x; let r1 = &x; @@ -748,7 +750,7 @@ fn borrowed(x: T) { ret = { Return() } - ) + } } /// Generic type `T` is not known to be `Freeze`, so shared borrows may be mutable. @@ -763,7 +765,7 @@ fn non_freeze(x: T) { // CHECK-NEXT: _0 = opaque::(_2) // CHECK: bb2: { // CHECK-NEXT: _0 = opaque::((*_3)) - mir!( + mir! { { let a = x; let r1 = &x; @@ -778,7 +780,7 @@ fn non_freeze(x: T) { ret = { Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/inline/inline_cycle.rs b/tests/mir-opt/inline/inline_cycle.rs index 1826e38f894d..651112ccfd7f 100644 --- a/tests/mir-opt/inline/inline_cycle.rs +++ b/tests/mir-opt/inline/inline_cycle.rs @@ -32,7 +32,6 @@ impl Call for A { } } - impl Call for B { #[inline] fn call() { diff --git a/tests/mir-opt/inline/inline_cycle_generic.rs b/tests/mir-opt/inline/inline_cycle_generic.rs index 667bf7f9254d..64f208b1c70b 100644 --- a/tests/mir-opt/inline/inline_cycle_generic.rs +++ b/tests/mir-opt/inline/inline_cycle_generic.rs @@ -26,7 +26,6 @@ impl Call for A { } } - impl Call for B { #[inline] fn call() { diff --git a/tests/mir-opt/inline/inline_options.rs b/tests/mir-opt/inline/inline_options.rs index 7d7c4f718bd7..bd9e0e2d2074 100644 --- a/tests/mir-opt/inline/inline_options.rs +++ b/tests/mir-opt/inline/inline_options.rs @@ -16,8 +16,16 @@ fn main() { // Cost is approximately 3 * 25 + 5 = 80. #[inline] -pub fn not_inlined() { g(); g(); g(); } -pub fn inlined() { g(); g(); g(); } +pub fn not_inlined() { + g(); + g(); + g(); +} +pub fn inlined() { + g(); + g(); + g(); +} #[inline(never)] fn g() {} diff --git a/tests/mir-opt/inline/inline_specialization.rs b/tests/mir-opt/inline/inline_specialization.rs index 6453abc00812..b9d40aca3a43 100644 --- a/tests/mir-opt/inline/inline_specialization.rs +++ b/tests/mir-opt/inline/inline_specialization.rs @@ -5,7 +5,7 @@ fn main() { // CHECK-LABEL: fn main( // CHECK: (inlined as Foo>::bar) - let x = as Foo>::bar(); + let x = as Foo>::bar(); } trait Foo { @@ -14,5 +14,7 @@ trait Foo { impl Foo for Vec { #[inline(always)] - default fn bar() -> u32 { 123 } + default fn bar() -> u32 { + 123 + } } diff --git a/tests/mir-opt/inline/issue_106141.rs b/tests/mir-opt/inline/issue_106141.rs index 1cca7d76b25a..d311ad4527f2 100644 --- a/tests/mir-opt/inline/issue_106141.rs +++ b/tests/mir-opt/inline/issue_106141.rs @@ -19,11 +19,7 @@ fn inner() -> usize { // CHECK: = {{.*}}[_0]; let buffer = &[true]; let index = index(); - if buffer[index] { - index - } else { - 0 - } + if buffer[index] { index } else { 0 } } fn main() { diff --git a/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs index 75772c161277..021af7f81bb2 100644 --- a/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs +++ b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs @@ -13,6 +13,9 @@ fn main() { // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: } - let f = |x| { let y = x; y }; + let f = |x| { + let y = x; + y + }; f(()) } diff --git a/tests/mir-opt/instsimplify/combine_array_len.rs b/tests/mir-opt/instsimplify/combine_array_len.rs index 86455e8b52d5..f12284f64821 100644 --- a/tests/mir-opt/instsimplify/combine_array_len.rs +++ b/tests/mir-opt/instsimplify/combine_array_len.rs @@ -7,9 +7,9 @@ fn norm2(x: [f32; 2]) -> f32 { // CHECK-NOT: Len( let a = x[0]; let b = x[1]; - a*a + b*b + a * a + b * b } fn main() { - assert_eq!(norm2([3.0, 4.0]), 5.0*5.0); + assert_eq!(norm2([3.0, 4.0]), 5.0 * 5.0); } diff --git a/tests/mir-opt/instsimplify/combine_transmutes.rs b/tests/mir-opt/instsimplify/combine_transmutes.rs index 0be7466001fe..c3622c20697a 100644 --- a/tests/mir-opt/instsimplify/combine_transmutes.rs +++ b/tests/mir-opt/instsimplify/combine_transmutes.rs @@ -5,7 +5,7 @@ #![feature(custom_mir)] use std::intrinsics::mir::*; -use std::mem::{MaybeUninit, ManuallyDrop, transmute}; +use std::mem::{transmute, ManuallyDrop, MaybeUninit}; // EMIT_MIR combine_transmutes.identity_transmutes.InstSimplify.diff pub unsafe fn identity_transmutes() { @@ -61,4 +61,7 @@ pub unsafe fn adt_transmutes() { let _a: ManuallyDrop = transmute(MaybeUninit::::uninit()); } -pub union Union32 { u32: u32, i32: i32 } +pub union Union32 { + u32: u32, + i32: i32, +} diff --git a/tests/mir-opt/instsimplify/duplicate_switch_targets.rs b/tests/mir-opt/instsimplify/duplicate_switch_targets.rs index 454728249b1a..a47d9d5a71d7 100644 --- a/tests/mir-opt/instsimplify/duplicate_switch_targets.rs +++ b/tests/mir-opt/instsimplify/duplicate_switch_targets.rs @@ -10,7 +10,7 @@ use std::intrinsics::mir::*; pub unsafe fn assert_zero(x: u8) -> u8 { // CHECK-LABEL: fn assert_zero( // CHECK: switchInt({{.*}}) -> [0: {{bb.*}}, otherwise: {{bb.*}}] - mir!( + mir! { { match x { 0 => retblock, @@ -25,5 +25,5 @@ pub unsafe fn assert_zero(x: u8) -> u8 { RET = x; Return() } - ) + } } diff --git a/tests/mir-opt/instsimplify/ref_of_deref.pointers.InstSimplify.diff b/tests/mir-opt/instsimplify/ref_of_deref.pointers.InstSimplify.diff new file mode 100644 index 000000000000..52b3d1e1d40b --- /dev/null +++ b/tests/mir-opt/instsimplify/ref_of_deref.pointers.InstSimplify.diff @@ -0,0 +1,58 @@ +- // MIR for `pointers` before InstSimplify ++ // MIR for `pointers` after InstSimplify + + fn pointers(_1: *const [i32], _2: *mut i32) -> () { + debug const_ptr => _1; + debug mut_ptr => _2; + let mut _0: (); + let _3: &[i32]; + scope 1 { + debug _a => _3; + let _4: &i32; + scope 2 { + debug _b => _4; + let _5: &mut i32; + scope 3 { + debug _c => _5; + let _6: *const [i32]; + scope 4 { + debug _d => _6; + let _7: *const i32; + scope 5 { + debug _e => _7; + let _8: *mut i32; + scope 6 { + debug _f => _8; + } + } + } + } + } + } + + bb0: { + StorageLive(_3); + _3 = &(*_1); + StorageLive(_4); + _4 = &(*_2); + StorageLive(_5); + _5 = &mut (*_2); + StorageLive(_6); +- _6 = &raw const (*_1); ++ _6 = _1; + StorageLive(_7); + _7 = &raw const (*_2); + StorageLive(_8); +- _8 = &raw mut (*_2); ++ _8 = _2; + _0 = const (); + StorageDead(_8); + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + return; + } + } + diff --git a/tests/mir-opt/instsimplify/ref_of_deref.references.InstSimplify.diff b/tests/mir-opt/instsimplify/ref_of_deref.references.InstSimplify.diff new file mode 100644 index 000000000000..ca0828a225a0 --- /dev/null +++ b/tests/mir-opt/instsimplify/ref_of_deref.references.InstSimplify.diff @@ -0,0 +1,58 @@ +- // MIR for `references` before InstSimplify ++ // MIR for `references` after InstSimplify + + fn references(_1: &i32, _2: &mut [i32]) -> () { + debug const_ref => _1; + debug mut_ref => _2; + let mut _0: (); + let _3: &i32; + scope 1 { + debug _a => _3; + let _4: &[i32]; + scope 2 { + debug _b => _4; + let _5: &mut [i32]; + scope 3 { + debug _c => _5; + let _6: *const i32; + scope 4 { + debug _d => _6; + let _7: *const [i32]; + scope 5 { + debug _e => _7; + let _8: *mut [i32]; + scope 6 { + debug _f => _8; + } + } + } + } + } + } + + bb0: { + StorageLive(_3); +- _3 = &(*_1); ++ _3 = _1; + StorageLive(_4); + _4 = &(*_2); + StorageLive(_5); +- _5 = &mut (*_2); ++ _5 = _2; + StorageLive(_6); + _6 = &raw const (*_1); + StorageLive(_7); + _7 = &raw const (*_2); + StorageLive(_8); + _8 = &raw mut (*_2); + _0 = const (); + StorageDead(_8); + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + return; + } + } + diff --git a/tests/mir-opt/instsimplify/ref_of_deref.rs b/tests/mir-opt/instsimplify/ref_of_deref.rs new file mode 100644 index 000000000000..37e164bc17f1 --- /dev/null +++ b/tests/mir-opt/instsimplify/ref_of_deref.rs @@ -0,0 +1,40 @@ +//@ test-mir-pass: InstSimplify +#![crate_type = "lib"] +#![feature(raw_ref_op)] + +// For each of these, only 2 of the 6 should simplify, +// as the others have the wrong types. + +// EMIT_MIR ref_of_deref.references.InstSimplify.diff +// CHECK-LABEL: references +pub fn references(const_ref: &i32, mut_ref: &mut [i32]) { + // CHECK: _3 = _1; + let _a = &*const_ref; + // CHECK: _4 = &(*_2); + let _b = &*mut_ref; + // CHECK: _5 = _2; + let _c = &mut *mut_ref; + // CHECK: _6 = &raw const (*_1); + let _d = &raw const *const_ref; + // CHECK: _7 = &raw const (*_2); + let _e = &raw const *mut_ref; + // CHECK: _8 = &raw mut (*_2); + let _f = &raw mut *mut_ref; +} + +// EMIT_MIR ref_of_deref.pointers.InstSimplify.diff +// CHECK-LABEL: pointers +pub unsafe fn pointers(const_ptr: *const [i32], mut_ptr: *mut i32) { + // CHECK: _3 = &(*_1); + let _a = &*const_ptr; + // CHECK: _4 = &(*_2); + let _b = &*mut_ptr; + // CHECK: _5 = &mut (*_2); + let _c = &mut *mut_ptr; + // CHECK: _6 = _1; + let _d = &raw const *const_ptr; + // CHECK: _7 = &raw const (*_2); + let _e = &raw const *mut_ptr; + // CHECK: _8 = _2; + let _f = &raw mut *mut_ptr; +} diff --git a/tests/mir-opt/issue_104451_unwindable_intrinsics.rs b/tests/mir-opt/issue_104451_unwindable_intrinsics.rs index cd068f122367..80655a583c34 100644 --- a/tests/mir-opt/issue_104451_unwindable_intrinsics.rs +++ b/tests/mir-opt/issue_104451_unwindable_intrinsics.rs @@ -5,9 +5,7 @@ // EMIT_MIR issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.mir fn main() { - unsafe { - core::intrinsics::const_eval_select((), ow_ct, ow_ct) - } + unsafe { core::intrinsics::const_eval_select((), ow_ct, ow_ct) } } const fn ow_ct() -> ! { diff --git a/tests/mir-opt/issue_41110.rs b/tests/mir-opt/issue_41110.rs index 38602d5eaef4..5d042815f3b4 100644 --- a/tests/mir-opt/issue_41110.rs +++ b/tests/mir-opt/issue_41110.rs @@ -3,7 +3,6 @@ // check that we don't emit multiple drop flags when they are not needed. - // EMIT_MIR issue_41110.main.ElaborateDrops.diff fn main() { let x = S.other(S.id()); @@ -21,11 +20,12 @@ pub fn test() { struct S; impl Drop for S { - fn drop(&mut self) { - } + fn drop(&mut self) {} } impl S { - fn id(self) -> Self { self } + fn id(self) -> Self { + self + } fn other(self, s: Self) {} } diff --git a/tests/mir-opt/issue_41697.rs b/tests/mir-opt/issue_41697.rs index 92d382c39407..b031f1dc7201 100644 --- a/tests/mir-opt/issue_41697.rs +++ b/tests/mir-opt/issue_41697.rs @@ -14,9 +14,8 @@ trait Foo { fn get(&self) -> [u8; 2]; } - // EMIT_MIR issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir -impl Foo for [u8; 1+1] { +impl Foo for [u8; 1 + 1] { fn get(&self) -> [u8; 2] { *self } @@ -33,7 +32,7 @@ fn unsize_nested_fat_ptr(x: Arc) -> Arc { } fn main() { - let x: Box> = Box::new(Bar([1,2])); + let x: Box> = Box::new(Bar([1, 2])); assert_eq!(unsize_fat_ptr(&*x).0.get(), [1, 2]); let x: Arc = Arc::new([3, 4]); diff --git a/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir b/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir index 7d2e97f8d564..27a5a8dd5526 100644 --- a/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir +++ b/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir @@ -1,6 +1,6 @@ -// MIR for `::{constant#0}` after SimplifyCfg-promote-consts +// MIR for `::{constant#0}` after SimplifyCfg-promote-consts -::{constant#0}: usize = { +::{constant#0}: usize = { let mut _0: usize; let mut _1: (usize, bool); diff --git a/tests/mir-opt/issue_41888.rs b/tests/mir-opt/issue_41888.rs index 70b202186336..1744d9f85701 100644 --- a/tests/mir-opt/issue_41888.rs +++ b/tests/mir-opt/issue_41888.rs @@ -15,11 +15,13 @@ fn main() { } } -fn cond() -> bool { false } +fn cond() -> bool { + false +} struct K; enum E { F(K), - G(Box) + G(Box), } diff --git a/tests/mir-opt/issue_72181.rs b/tests/mir-opt/issue_72181.rs index 3748c2af83d2..dea8ecbd3ec7 100644 --- a/tests/mir-opt/issue_72181.rs +++ b/tests/mir-opt/issue_72181.rs @@ -9,16 +9,18 @@ enum Never {} union Foo { a: u64, - b: Never + b: Never, } - // EMIT_MIR issue_72181.foo.built.after.mir -fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 } +fn foo(xs: [(Never, u32); 1]) -> u32 { + xs[0].1 +} // EMIT_MIR issue_72181.bar.built.after.mir -fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x } - +fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { + x +} // EMIT_MIR issue_72181.main.built.after.mir fn main() { diff --git a/tests/mir-opt/issue_72181_1.rs b/tests/mir-opt/issue_72181_1.rs index 32e946559d77..5c8346166aec 100644 --- a/tests/mir-opt/issue_72181_1.rs +++ b/tests/mir-opt/issue_72181_1.rs @@ -14,9 +14,7 @@ fn f(v: Void) -> ! { // EMIT_MIR issue_72181_1.main.built.after.mir fn main() { - let v: Void = unsafe { - std::mem::transmute::<(), Void>(()) - }; + let v: Void = unsafe { std::mem::transmute::<(), Void>(()) }; f(v); } diff --git a/tests/mir-opt/issue_91633.rs b/tests/mir-opt/issue_91633.rs index f7d59f5adfb6..d24c2e19aa73 100644 --- a/tests/mir-opt/issue_91633.rs +++ b/tests/mir-opt/issue_91633.rs @@ -1,32 +1,30 @@ // skip-filecheck //@ compile-flags: -Z mir-opt-level=0 // EMIT_MIR issue_91633.hey.built.after.mir -fn hey (it: &[T]) - where - [T] : std::ops::Index, - { - let _ = &it[0]; - } +fn hey(it: &[T]) +where + [T]: std::ops::Index, +{ + let _ = &it[0]; +} // EMIT_MIR issue_91633.bar.built.after.mir -fn bar (it: Box<[T]>) - where - [T] : std::ops::Index, - { - let _ = it[0]; - } +fn bar(it: Box<[T]>) +where + [T]: std::ops::Index, +{ + let _ = it[0]; +} // EMIT_MIR issue_91633.fun.built.after.mir -fn fun (it: &[T]) -> &T - { - let f = &it[0]; - f - } +fn fun(it: &[T]) -> &T { + let f = &it[0]; + f +} // EMIT_MIR issue_91633.foo.built.after.mir -fn foo (it: Box<[T]>) -> T - { - let f = it[0].clone(); - f - } - fn main(){} +fn foo(it: Box<[T]>) -> T { + let f = it[0].clone(); + f +} +fn main() {} diff --git a/tests/mir-opt/issues/issue_75439.rs b/tests/mir-opt/issues/issue_75439.rs index 8c710a33aa8e..ea763dd1b10d 100644 --- a/tests/mir-opt/issues/issue_75439.rs +++ b/tests/mir-opt/issues/issue_75439.rs @@ -8,11 +8,7 @@ pub fn foo(bytes: [u8; 16]) -> Option<[u8; 4]> { // big endian `u32`s let dwords: [u32; 4] = unsafe { transmute(bytes) }; const FF: u32 = 0x0000_ffff_u32.to_be(); - if let [0, 0, 0 | FF, ip] = dwords { - Some(unsafe { transmute(ip) }) - } else { - None - } + if let [0, 0, 0 | FF, ip] = dwords { Some(unsafe { transmute(ip) }) } else { None } } fn main() { diff --git a/tests/mir-opt/jump_threading.rs b/tests/mir-opt/jump_threading.rs index 57f4e4a2654f..b4c133716800 100644 --- a/tests/mir-opt/jump_threading.rs +++ b/tests/mir-opt/jump_threading.rs @@ -157,7 +157,7 @@ fn custom_discr(x: bool) -> u8 { #[custom_mir(dialect = "runtime", phase = "post-cleanup")] fn multiple_match(x: u8) -> u8 { // CHECK-LABEL: fn multiple_match( - mir!( + mir! { { // CHECK: bb0: { // CHECK: switchInt([[x:_.*]]) -> [3: bb1, otherwise: bb2]; @@ -220,7 +220,7 @@ fn multiple_match(x: u8) -> u8 { RET = 11; Return() } - ) + } } /// Both 1-3-4 and 2-3-4 are threadable. As 1 and 2 are the only predecessors of 3, @@ -228,7 +228,7 @@ fn multiple_match(x: u8) -> u8 { #[custom_mir(dialect = "runtime", phase = "post-cleanup")] fn duplicate_chain(x: bool) -> u8 { // CHECK-LABEL: fn duplicate_chain( - mir!( + mir! { let a: u8; { // CHECK: bb0: { @@ -278,7 +278,7 @@ fn duplicate_chain(x: bool) -> u8 { RET = 9; Return() } - ) + } } #[rustc_layout_scalar_valid_range_start(1)] @@ -292,7 +292,7 @@ fn mutate_discriminant() -> u8 { // CHECK-NOT: goto -> {{bb.*}}; // CHECK: switchInt( // CHECK-NOT: goto -> {{bb.*}}; - mir!( + mir! { let x: Option; { SetDiscriminant(x, 1); @@ -313,7 +313,7 @@ fn mutate_discriminant() -> u8 { RET = 2; Unreachable() } - ) + } } /// Verify that we do not try to reason when there are mutable pointers involved. @@ -330,11 +330,7 @@ fn mutable_ref() -> bool { let a = std::ptr::addr_of_mut!(x); x = 7; unsafe { *a = 8 }; - if x == 7 { - true - } else { - false - } + if x == 7 { true } else { false } } /// This function has 2 TOs: 1-3-4 and 0-1-3-4-6. @@ -342,7 +338,7 @@ fn mutable_ref() -> bool { #[custom_mir(dialect = "runtime", phase = "post-cleanup")] fn renumbered_bb(x: bool) -> u8 { // CHECK-LABEL: fn renumbered_bb( - mir!( + mir! { let a: bool; let b: bool; { @@ -398,7 +394,7 @@ fn renumbered_bb(x: bool) -> u8 { // Duplicate of bb4. // CHECK: bb9: { // CHECK-NEXT: goto -> bb6; - ) + } } /// This function has 3 TOs: 1-4-5, 0-1-4-7-5-8 and 3-4-7-5-6 @@ -408,7 +404,7 @@ fn renumbered_bb(x: bool) -> u8 { #[custom_mir(dialect = "runtime", phase = "post-cleanup")] fn disappearing_bb(x: u8) -> u8 { // CHECK-LABEL: fn disappearing_bb( - mir!( + mir! { let a: bool; let b: bool; { @@ -450,7 +446,7 @@ fn disappearing_bb(x: u8) -> u8 { // CHECK: goto -> bb5; // CHECK: bb10: { // CHECK: goto -> bb6; - ) + } } /// Verify that we can thread jumps when we assign from an aggregate constant. @@ -461,18 +457,14 @@ fn aggregate(x: u8) -> u8 { const FOO: (u8, u8) = (5, 13); let (a, b) = FOO; - if a == 7 { - b - } else { - a - } + if a == 7 { b } else { a } } /// Verify that we can leverage the existence of an `Assume` terminator. #[custom_mir(dialect = "runtime", phase = "post-cleanup")] fn assume(a: u8, b: bool) -> u8 { // CHECK-LABEL: fn assume( - mir!( + mir! { { // CHECK: bb0: { // CHECK-NEXT: switchInt(_1) -> [7: bb1, otherwise: bb2] @@ -511,7 +503,7 @@ fn assume(a: u8, b: bool) -> u8 { } // CHECK: bb6: { // CHECK-NEXT: goto -> bb5; - ) + } } fn main() { diff --git a/tests/mir-opt/lower_array_len.rs b/tests/mir-opt/lower_array_len.rs index 1c30c4c89b96..62fc9ef67d66 100644 --- a/tests/mir-opt/lower_array_len.rs +++ b/tests/mir-opt/lower_array_len.rs @@ -7,11 +7,7 @@ pub fn array_bound(index: usize, slice: &[u8; N]) -> u8 { // CHECK-LABEL: fn array_bound( // CHECK: [[len:_.*]] = const N; // CHECK: Lt(move {{_.*}}, move [[len]]); - if index < slice.len() { - slice[index] - } else { - 42 - } + if index < slice.len() { slice[index] } else { 42 } } // EMIT_MIR lower_array_len.array_bound_mut.NormalizeArrayLen.diff diff --git a/tests/mir-opt/lower_slice_len.rs b/tests/mir-opt/lower_slice_len.rs index b82094dc18f9..6fd7e4bf72cd 100644 --- a/tests/mir-opt/lower_slice_len.rs +++ b/tests/mir-opt/lower_slice_len.rs @@ -5,11 +5,7 @@ pub fn bound(index: usize, slice: &[u8]) -> u8 { // CHECK-LABEL: fn bound( // CHECK-NOT: ::len( - if index < slice.len() { - slice[index] - } else { - 42 - } + if index < slice.len() { slice[index] } else { 42 } } fn main() { diff --git a/tests/mir-opt/matches_reduce_branches.rs b/tests/mir-opt/matches_reduce_branches.rs index fa466220b653..176d68bcd401 100644 --- a/tests/mir-opt/matches_reduce_branches.rs +++ b/tests/mir-opt/matches_reduce_branches.rs @@ -88,7 +88,7 @@ fn match_u8_i16(i: EnumAu8) -> i16 { fn match_u8_i16_2(i: EnumAu8) -> i16 { // CHECK-LABEL: fn match_u8_i16_2( // CHECK: switchInt - mir!( + mir! { { let a = Discriminant(i); match a { @@ -110,7 +110,7 @@ fn match_u8_i16_2(i: EnumAu8) -> i16 { ret = { Return() } - ) + } } // EMIT_MIR matches_reduce_branches.match_u8_i16_failed.MatchBranchSimplification.diff @@ -158,7 +158,7 @@ fn match_u8_u16(i: EnumBu8) -> u16 { fn match_u8_u16_2(i: EnumBu8) -> i16 { // CHECK-LABEL: fn match_u8_u16_2( // CHECK: switchInt - mir!( + mir! { { let a = Discriminant(i); match a { @@ -187,7 +187,7 @@ fn match_u8_u16_2(i: EnumBu8) -> i16 { ret = { Return() } - ) + } } #[repr(i8)] diff --git a/tests/mir-opt/matches_u8.rs b/tests/mir-opt/matches_u8.rs index f0be82d02571..86d646256742 100644 --- a/tests/mir-opt/matches_u8.rs +++ b/tests/mir-opt/matches_u8.rs @@ -1,7 +1,6 @@ // skip-filecheck //@ test-mir-pass: MatchBranchSimplification - // EMIT_MIR matches_u8.exhaustive_match.MatchBranchSimplification.diff // EMIT_MIR matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff @@ -27,9 +26,9 @@ pub fn exhaustive_match_i8(e: E) -> i8 { } fn main() { - assert_eq!(exhaustive_match(E::A), 0); - assert_eq!(exhaustive_match(E::B), 1); + assert_eq!(exhaustive_match(E::A), 0); + assert_eq!(exhaustive_match(E::B), 1); - assert_eq!(exhaustive_match_i8(E::A), 0); - assert_eq!(exhaustive_match_i8(E::B), 1); + assert_eq!(exhaustive_match_i8(E::A), 0); + assert_eq!(exhaustive_match_i8(E::B), 1); } diff --git a/tests/mir-opt/nll/named_lifetimes_basic.rs b/tests/mir-opt/nll/named_lifetimes_basic.rs index cc8385370038..93f4a8bfd598 100644 --- a/tests/mir-opt/nll/named_lifetimes_basic.rs +++ b/tests/mir-opt/nll/named_lifetimes_basic.rs @@ -10,7 +10,8 @@ #![allow(warnings)] // EMIT_MIR named_lifetimes_basic.use_x.nll.0.mir -fn use_x<'a, 'b: 'a, 'c>(w: &'a mut i32, x: &'b u32, y: &'a u32, z: &'c u32) -> bool { true } - -fn main() { +fn use_x<'a, 'b: 'a, 'c>(w: &'a mut i32, x: &'b u32, y: &'a u32, z: &'c u32) -> bool { + true } + +fn main() {} diff --git a/tests/mir-opt/nrvo_miscompile_111005.rs b/tests/mir-opt/nrvo_miscompile_111005.rs index 18814b0678fe..03008fa81915 100644 --- a/tests/mir-opt/nrvo_miscompile_111005.rs +++ b/tests/mir-opt/nrvo_miscompile_111005.rs @@ -10,12 +10,14 @@ use core::intrinsics::mir::*; // EMIT_MIR nrvo_miscompile_111005.wrong.RenameReturnPlace.diff #[custom_mir(dialect = "runtime", phase = "initial")] pub fn wrong(arg: char) -> char { - mir!({ - let temp = arg; - RET = temp; - temp = 'b'; - Return() - }) + mir! { + { + let temp = arg; + RET = temp; + temp = 'b'; + Return() + } + } } fn main() { diff --git a/tests/mir-opt/nrvo_simple.rs b/tests/mir-opt/nrvo_simple.rs index 5d2894a704a5..df540472e1cc 100644 --- a/tests/mir-opt/nrvo_simple.rs +++ b/tests/mir-opt/nrvo_simple.rs @@ -10,5 +10,7 @@ fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] { } fn main() { - let _ = nrvo(|buf| { buf[4] = 4; }); + let _ = nrvo(|buf| { + buf[4] = 4; + }); } diff --git a/tests/mir-opt/packed_struct_drop_aligned.rs b/tests/mir-opt/packed_struct_drop_aligned.rs index dff941c4fa0c..3abc6426e7f0 100644 --- a/tests/mir-opt/packed_struct_drop_aligned.rs +++ b/tests/mir-opt/packed_struct_drop_aligned.rs @@ -1,7 +1,6 @@ // skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY - // EMIT_MIR packed_struct_drop_aligned.main.SimplifyCfg-pre-optimizations.after.mir fn main() { let mut x = Packed(Aligned(Droppy(0))); diff --git a/tests/mir-opt/pre-codegen/intrinsics.rs b/tests/mir-opt/pre-codegen/intrinsics.rs index e5c059cda12e..0482b85e95f8 100644 --- a/tests/mir-opt/pre-codegen/intrinsics.rs +++ b/tests/mir-opt/pre-codegen/intrinsics.rs @@ -12,7 +12,6 @@ pub fn f_unit() { f_dispatch(()); } - // EMIT_MIR intrinsics.f_u64.PreCodegen.after.mir pub fn f_u64() { f_dispatch(0u64); @@ -28,8 +27,7 @@ pub fn f_dispatch(t: T) { } #[inline(never)] -pub fn f_zst(_t: T) { -} +pub fn f_zst(_t: T) {} #[inline(never)] pub fn f_non_zst(_t: T) {} diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.rs b/tests/mir-opt/pre-codegen/optimizes_into_variable.rs index 7a1fb1e76c03..de5e2d5c3121 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.rs +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.rs @@ -15,5 +15,5 @@ struct Point { fn main() { let x = 2 + 2; let y = [0, 1, 2, 3, 4, 5][3]; - let z = (Point { x: 12, y: 42}).y; + let z = (Point { x: 12, y: 42 }).y; } diff --git a/tests/mir-opt/pre-codegen/try_identity.rs b/tests/mir-opt/pre-codegen/try_identity.rs index 2e17a3ae6e7e..264b303e381d 100644 --- a/tests/mir-opt/pre-codegen/try_identity.rs +++ b/tests/mir-opt/pre-codegen/try_identity.rs @@ -17,18 +17,16 @@ fn new(x: Result) -> Result { } { ControlFlow::Continue(v) => v, ControlFlow::Break(e) => return Err(e), - } + }, ) } // EMIT_MIR try_identity.old.PreCodegen.after.mir fn old(x: Result) -> Result { - Ok( - match x { - Ok(v) => v, - Err(e) => return Err(e), - } - ) + Ok(match x { + Ok(v) => v, + Err(e) => return Err(e), + }) } fn main() { diff --git a/tests/mir-opt/reference_prop.rs b/tests/mir-opt/reference_prop.rs index e0b0d6994206..58d8b524ad64 100644 --- a/tests/mir-opt/reference_prop.rs +++ b/tests/mir-opt/reference_prop.rs @@ -658,7 +658,7 @@ fn read_through_raw(x: &mut usize) -> usize { // CHECK-NEXT: return; use std::intrinsics::mir::*; - mir!( + mir! { let r1: &mut usize; let r2: &mut usize; let p1: *mut usize; @@ -674,7 +674,7 @@ fn read_through_raw(x: &mut usize) -> usize { RET = *p2; Return() } - ) + } } #[custom_mir(dialect = "runtime", phase = "post-cleanup")] @@ -683,7 +683,7 @@ fn multiple_storage() { // CHECK: _3 = (*_2); use std::intrinsics::mir::*; - mir!( + mir! { let x: i32; { StorageLive(x); @@ -700,7 +700,7 @@ fn multiple_storage() { retblock = { Return() } - ) + } } #[custom_mir(dialect = "runtime", phase = "post-cleanup")] @@ -709,7 +709,7 @@ fn dominate_storage() { // CHECK: _5 = (*_2); use std::intrinsics::mir::*; - mir!( + mir! { let x: i32; let r: &i32; let c: i32; @@ -730,7 +730,7 @@ fn dominate_storage() { let d = true; match d { false => bb2, _ => bb0 } } - ) + } } #[custom_mir(dialect = "runtime", phase = "post-cleanup")] @@ -739,7 +739,7 @@ fn maybe_dead(m: bool) { // CHECK: (*_5) = const 7_i32; use std::intrinsics::mir::*; - mir!( + mir! { let x: i32; let y: i32; { @@ -774,7 +774,7 @@ fn maybe_dead(m: bool) { retblock = { Return() } - ) + } } fn mut_raw_then_mut_shr() -> (i32, i32) { @@ -787,7 +787,9 @@ fn mut_raw_then_mut_shr() -> (i32, i32) { let xshr = &*xref; // Verify that we completely replace with `x` in both cases. let a = *xshr; - unsafe { *xraw = 4; } + unsafe { + *xraw = 4; + } (a, x) } @@ -842,8 +844,7 @@ fn debuginfo() { // `constant_index_from_end` and `subslice` should not be promoted, as their value depends // on the slice length. - if let [_, ref constant_index, subslice @ .., ref constant_index_from_end] = &[6; 10][..] { - } + if let [_, ref constant_index, subslice @ .., ref constant_index_from_end] = &[6; 10][..] {} let multiple_borrow = &&&mut T(6).0; } diff --git a/tests/mir-opt/retag.rs b/tests/mir-opt/retag.rs index 43d74aa5726f..001c55991383 100644 --- a/tests/mir-opt/retag.rs +++ b/tests/mir-opt/retag.rs @@ -59,7 +59,9 @@ pub fn main() { fn array_casts() { let mut x: [usize; 2] = [0, 0]; let p = &mut x as *mut usize; - unsafe { *p.add(1) = 1; } + unsafe { + *p.add(1) = 1; + } let x: [usize; 2] = [0, 1]; let p = &x as *const usize; diff --git a/tests/mir-opt/return_an_array.rs b/tests/mir-opt/return_an_array.rs index 09146a824fcd..673b5df7d730 100644 --- a/tests/mir-opt/return_an_array.rs +++ b/tests/mir-opt/return_an_array.rs @@ -2,8 +2,8 @@ // this tests move up progration, which is not yet implemented fn foo() -> [u8; 1024] { - let x = [0; 1024]; - return x; + let x = [0; 1024]; + return x; } -fn main() { } +fn main() {} diff --git a/tests/mir-opt/set_no_discriminant.rs b/tests/mir-opt/set_no_discriminant.rs index 0c29d1faf02a..586e28ae426a 100644 --- a/tests/mir-opt/set_no_discriminant.rs +++ b/tests/mir-opt/set_no_discriminant.rs @@ -19,7 +19,7 @@ pub fn f() -> usize { // CHECK-NOT: goto // CHECK: switchInt( // CHECK-NOT: goto - mir!( + mir! { let a: isize; let e: E; { @@ -39,7 +39,7 @@ pub fn f() -> usize { RET = 1; Return() } - ) + } } // EMIT_MIR set_no_discriminant.generic.JumpThreading.diff @@ -49,7 +49,7 @@ pub fn generic() -> usize { // CHECK-NOT: goto // CHECK: switchInt( // CHECK-NOT: goto - mir!( + mir! { let a: isize; let e: E; { @@ -69,7 +69,7 @@ pub fn generic() -> usize { RET = 1; Return() } - ) + } } fn main() { diff --git a/tests/mir-opt/simplify_dead_blocks.rs b/tests/mir-opt/simplify_dead_blocks.rs index 686eac582364..b9a404fd35c8 100644 --- a/tests/mir-opt/simplify_dead_blocks.rs +++ b/tests/mir-opt/simplify_dead_blocks.rs @@ -24,7 +24,7 @@ pub unsafe fn assert_nonzero_nonmax(x: u8) -> u8 { // CHECK-NEXT: _0 = _1; // CHECK-NEXT: return; // CHECK-NEXT: } - mir!( + mir! { { match x { 0 => unreachable, @@ -48,5 +48,5 @@ pub unsafe fn assert_nonzero_nonmax(x: u8) -> u8 { RET = x; Return() } - ) + } } diff --git a/tests/mir-opt/simplify_locals.rs b/tests/mir-opt/simplify_locals.rs index f57611111cfc..6511b5e87e47 100644 --- a/tests/mir-opt/simplify_locals.rs +++ b/tests/mir-opt/simplify_locals.rs @@ -1,13 +1,12 @@ // skip-filecheck //@ test-mir-pass: SimplifyLocals-before-const-prop - #![feature(thread_local)] #[derive(Copy, Clone)] enum E { - A, - B, + A, + B, } // EMIT_MIR simplify_locals.c.SimplifyLocals-before-const-prop.diff @@ -26,7 +25,7 @@ fn d1() { // EMIT_MIR simplify_locals.d2.SimplifyLocals-before-const-prop.diff fn d2() { // Unused set discriminant - {(10, E::A)}.1 = E::B; + { (10, E::A) }.1 = E::B; } // EMIT_MIR simplify_locals.r.SimplifyLocals-before-const-prop.diff @@ -37,7 +36,8 @@ fn r() { let _ = &mut a; } -#[thread_local] static mut X: u32 = 0; +#[thread_local] +static mut X: u32 = 0; // EMIT_MIR simplify_locals.t1.SimplifyLocals-before-const-prop.diff fn t1() { diff --git a/tests/mir-opt/simplify_locals_fixedpoint.rs b/tests/mir-opt/simplify_locals_fixedpoint.rs index 6947d31dc3e1..0b6c95630c0a 100644 --- a/tests/mir-opt/simplify_locals_fixedpoint.rs +++ b/tests/mir-opt/simplify_locals_fixedpoint.rs @@ -4,9 +4,7 @@ fn foo() { if let (Some(a), None) = (Option::::None, Option::::None) { - if a > 42u8 { - - } + if a > 42u8 {} } } diff --git a/tests/mir-opt/simplify_match.rs b/tests/mir-opt/simplify_match.rs index 2eac93edbb8e..b035b6339fae 100644 --- a/tests/mir-opt/simplify_match.rs +++ b/tests/mir-opt/simplify_match.rs @@ -5,8 +5,11 @@ fn noop() {} // EMIT_MIR simplify_match.main.GVN.diff fn main() { - match { let x = false; x } { + match { + let x = false; + x + } { true => noop(), - false => {}, + false => {} } } diff --git a/tests/mir-opt/sroa/lifetimes.rs b/tests/mir-opt/sroa/lifetimes.rs index 6c18dbaf5a23..90aa2a10938e 100644 --- a/tests/mir-opt/sroa/lifetimes.rs +++ b/tests/mir-opt/sroa/lifetimes.rs @@ -19,10 +19,7 @@ fn foo() { // CHECK-NOT: [foo:_.*]: Foo // CHECK-NOT: Box - let foo: Foo = Foo { - x: Ok(Box::new(5_u32)), - y: 7_u32, - }; + let foo: Foo = Foo { x: Ok(Box::new(5_u32)), y: 7_u32 }; let x = foo.x; let y = foo.y; diff --git a/tests/mir-opt/switch_to_self.rs b/tests/mir-opt/switch_to_self.rs index fc270fd33cf8..51a7c13494fb 100644 --- a/tests/mir-opt/switch_to_self.rs +++ b/tests/mir-opt/switch_to_self.rs @@ -8,7 +8,7 @@ use std::intrinsics::mir::*; // EMIT_MIR switch_to_self.test.MatchBranchSimplification.diff #[custom_mir(dialect = "runtime", phase = "post-cleanup")] pub fn test(x: bool) { - mir!( + mir! { { Goto(bb0) } @@ -18,5 +18,5 @@ pub fn test(x: bool) { bb1 = { match x { false => bb0, _ => bb1 } } - ) + } } diff --git a/tests/mir-opt/uninhabited_enum.rs b/tests/mir-opt/uninhabited_enum.rs index 8816f31f9dfa..859535852cf0 100644 --- a/tests/mir-opt/uninhabited_enum.rs +++ b/tests/mir-opt/uninhabited_enum.rs @@ -6,15 +6,15 @@ pub enum Void {} // EMIT_MIR uninhabited_enum.process_never.SimplifyLocals-final.after.mir #[no_mangle] pub fn process_never(input: *const !) { - let _input = unsafe { &*input }; + let _input = unsafe { &*input }; } // EMIT_MIR uninhabited_enum.process_void.SimplifyLocals-final.after.mir #[no_mangle] pub fn process_void(input: *const Void) { - let _input = unsafe { &*input }; - // In the future, this should end with `unreachable`, but we currently only do - // unreachability analysis for `!`. + let _input = unsafe { &*input }; + // In the future, this should end with `unreachable`, but we currently only do + // unreachability analysis for `!`. } fn main() {} diff --git a/tests/mir-opt/unnamed-fields/field_access.rs b/tests/mir-opt/unnamed-fields/field_access.rs index 5badfa1646bc..cc0ac9a34274 100644 --- a/tests/mir-opt/unnamed-fields/field_access.rs +++ b/tests/mir-opt/unnamed-fields/field_access.rs @@ -17,7 +17,7 @@ struct Foo { _: struct { d: [u8; 1], } - } + }, } #[repr(C)] @@ -31,10 +31,9 @@ union Bar { _: union { d: [u8; 1], } - } + }, } - fn access(_: T) {} // CHECK-LABEL: fn foo( @@ -71,5 +70,4 @@ fn bar(bar: Bar) { } } - fn main() {} diff --git a/tests/mir-opt/unreachable.rs b/tests/mir-opt/unreachable.rs index 5838b35a553a..881e3542f0ac 100644 --- a/tests/mir-opt/unreachable.rs +++ b/tests/mir-opt/unreachable.rs @@ -35,7 +35,7 @@ fn if_let() { _y = 42; } - match _x { } + match _x {} } } @@ -56,7 +56,7 @@ fn as_match() { // CHECK: return; match empty() { None => {} - Some(_x) => match _x {} + Some(_x) => match _x {}, } } diff --git a/tests/mir-opt/unusual_item_types.rs b/tests/mir-opt/unusual_item_types.rs index 788475431044..2f05981e812e 100644 --- a/tests/mir-opt/unusual_item_types.rs +++ b/tests/mir-opt/unusual_item_types.rs @@ -3,7 +3,6 @@ // that we don't create filenames containing `<` and `>` //@ compile-flags: -Zmir-opt-level=0 - struct A; // EMIT_MIR unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir @@ -23,8 +22,8 @@ enum E { V = 5, } +// EMIT_MIR core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir pub fn main() { let f = Test::X as fn(usize) -> Test; -// EMIT_MIR core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir let v = Vec::::new(); } diff --git a/tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir b/tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir index a5121ae550d6..e2edbfcd4fa3 100644 --- a/tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir +++ b/tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir @@ -1,6 +1,6 @@ -// MIR for `::ASSOCIATED_CONSTANT` after built +// MIR for `::ASSOCIATED_CONSTANT` after built -const ::ASSOCIATED_CONSTANT: i32 = { +const ::ASSOCIATED_CONSTANT: i32 = { let mut _0: i32; bb0: { diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 28a1e27ccccc..07466440aabf 100644 --- a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -27,7 +27,9 @@ use std::any::Any; struct TheBackend; impl CodegenBackend for TheBackend { - fn locale_resource(&self) -> &'static str { "" } + fn locale_resource(&self) -> &'static str { + "" + } fn codegen_crate<'a, 'tcx>( &self, @@ -62,7 +64,10 @@ impl CodegenBackend for TheBackend { codegen_results: CodegenResults, outputs: &OutputFilenames, ) -> Result<(), ErrorGuaranteed> { - use rustc_session::{config::{CrateType, OutFileName}, output::out_filename}; + use rustc_session::{ + config::{CrateType, OutFileName}, + output::out_filename, + }; use std::io::Write; let crate_name = codegen_results.crate_info.local_crate_name; for &crate_type in sess.opts.crate_types.iter() { diff --git a/tests/run-make-fulldeps/pretty-expanded/input.rs b/tests/run-make-fulldeps/pretty-expanded/input.rs index 02b235068a1d..64ed97572ee9 100644 --- a/tests/run-make-fulldeps/pretty-expanded/input.rs +++ b/tests/run-make-fulldeps/pretty-expanded/input.rs @@ -1,8 +1,25 @@ // #13544 -#[derive(Debug)] pub struct A; -#[derive(Debug)] pub struct B(isize); -#[derive(Debug)] pub struct C { x: isize } -#[derive(Debug)] pub enum D {} -#[derive(Debug)] pub enum E { y } -#[derive(Debug)] pub enum F { z(isize) } +#[derive(Debug)] +pub struct A; + +#[derive(Debug)] +pub struct B(isize); + +#[derive(Debug)] +pub struct C { + x: isize, +} + +#[derive(Debug)] +pub enum D {} + +#[derive(Debug)] +pub enum E { + y, +} + +#[derive(Debug)] +pub enum F { + z(isize), +} diff --git a/tests/run-make/a-b-a-linker-guard/a.rs b/tests/run-make/a-b-a-linker-guard/a.rs index aa07b1e71607..22686760f1aa 100644 --- a/tests/run-make/a-b-a-linker-guard/a.rs +++ b/tests/run-make/a-b-a-linker-guard/a.rs @@ -2,7 +2,7 @@ #![crate_type = "dylib"] #[cfg(x)] -pub fn foo(x: u32) { } +pub fn foo(x: u32) {} #[cfg(y)] -pub fn foo(x: i32) { } +pub fn foo(x: i32) {} diff --git a/tests/run-make/allow-non-lint-warnings-cmdline/foo.rs b/tests/run-make/allow-non-lint-warnings-cmdline/foo.rs index 46e72da2de9f..02e8ccabf792 100644 --- a/tests/run-make/allow-non-lint-warnings-cmdline/foo.rs +++ b/tests/run-make/allow-non-lint-warnings-cmdline/foo.rs @@ -2,4 +2,4 @@ #[derive(Copy, Clone)] pub struct Foo; -pub fn main() { } +pub fn main() {} diff --git a/tests/run-make/allow-warnings-cmdline-stability/foo.rs b/tests/run-make/allow-warnings-cmdline-stability/foo.rs index 869b54354168..0b91b63c1185 100644 --- a/tests/run-make/allow-warnings-cmdline-stability/foo.rs +++ b/tests/run-make/allow-warnings-cmdline-stability/foo.rs @@ -2,4 +2,6 @@ extern crate bar; -pub fn main() { bar::baz() } +pub fn main() { + bar::baz() +} diff --git a/tests/run-make/atomic-lock-free/atomic_lock_free.rs b/tests/run-make/atomic-lock-free/atomic_lock_free.rs index 47d90b1856be..1f1116b9bfd1 100644 --- a/tests/run-make/atomic-lock-free/atomic_lock_free.rs +++ b/tests/run-make/atomic-lock-free/atomic_lock_free.rs @@ -1,5 +1,5 @@ #![feature(no_core, intrinsics, lang_items)] -#![crate_type="rlib"] +#![crate_type = "rlib"] #![no_core] extern "rust-intrinsic" { diff --git a/tests/run-make/bare-outfile/Makefile b/tests/run-make/bare-outfile/Makefile deleted file mode 100644 index ad6fe4bd167c..000000000000 --- a/tests/run-make/bare-outfile/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# This test checks that manually setting the output file as a bare file with no file extension still results in successful compilation. - -# ignore-cross-compile -include ../tools.mk - -all: - cp foo.rs $(TMPDIR) - cd $(TMPDIR) && $(RUSTC) -o foo foo.rs - $(call RUN,foo) diff --git a/tests/run-make/bare-outfile/foo.rs b/tests/run-make/bare-outfile/foo.rs index f79c691f0853..f328e4d9d04c 100644 --- a/tests/run-make/bare-outfile/foo.rs +++ b/tests/run-make/bare-outfile/foo.rs @@ -1,2 +1 @@ -fn main() { -} +fn main() {} diff --git a/tests/run-make/bare-outfile/rmake.rs b/tests/run-make/bare-outfile/rmake.rs new file mode 100644 index 000000000000..82d0fab5073b --- /dev/null +++ b/tests/run-make/bare-outfile/rmake.rs @@ -0,0 +1,15 @@ +// This test checks that manually setting the output file as a bare file with no file extension +// still results in successful compilation. + +//@ ignore-cross-compile + +use run_make_support::{run, rustc, tmp_dir}; +use std::env; +use std::fs; + +fn main() { + fs::copy("foo.rs", tmp_dir().join("foo.rs")).unwrap(); + env::set_current_dir(tmp_dir()); + rustc().output("foo").input("foo.rs").run(); + run("foo"); +} diff --git a/tests/run-make/box-struct-no-segfault/foo.rs b/tests/run-make/box-struct-no-segfault/foo.rs index 1dcabe42dc11..0897b74b3567 100644 --- a/tests/run-make/box-struct-no-segfault/foo.rs +++ b/tests/run-make/box-struct-no-segfault/foo.rs @@ -1,8 +1,8 @@ -#![crate_type="lib"] +#![crate_type = "lib"] pub struct Foo(()); impl Foo { - pub fn new() -> Foo { - Foo(()) - } + pub fn new() -> Foo { + Foo(()) + } } diff --git a/tests/run-make/box-struct-no-segfault/main.rs b/tests/run-make/box-struct-no-segfault/main.rs index de12b1fd9dc3..1a456af48e8d 100644 --- a/tests/run-make/box-struct-no-segfault/main.rs +++ b/tests/run-make/box-struct-no-segfault/main.rs @@ -1,7 +1,7 @@ -#![crate_type="lib"] +#![crate_type = "lib"] extern crate foo; use foo::Foo; pub fn crash() -> Box { - Box::new(Foo::new()) + Box::new(Foo::new()) } diff --git a/tests/run-make/c-link-to-rust-dylib/Makefile b/tests/run-make/c-link-to-rust-dylib/Makefile deleted file mode 100644 index 201f717ece49..000000000000 --- a/tests/run-make/c-link-to-rust-dylib/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# This test checks that C linking with Rust does not encounter any errors, with dynamic libraries. -# See https://github.com/rust-lang/rust/issues/10434 - -# ignore-cross-compile -include ../tools.mk - -all: $(TMPDIR)/$(call BIN,bar) - $(call RUN,bar) - $(call REMOVE_DYLIBS,foo) - $(call FAIL,bar) - -ifdef IS_MSVC -$(TMPDIR)/$(call BIN,bar): $(call DYLIB,foo) - $(CC) bar.c $(TMPDIR)/foo.dll.lib $(call OUT_EXE,bar) -else -$(TMPDIR)/$(call BIN,bar): $(call DYLIB,foo) - $(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) -L $(TMPDIR) -endif - -$(call DYLIB,foo): foo.rs - $(RUSTC) foo.rs diff --git a/tests/run-make/c-link-to-rust-dylib/rmake.rs b/tests/run-make/c-link-to-rust-dylib/rmake.rs new file mode 100644 index 000000000000..5c4b6d786496 --- /dev/null +++ b/tests/run-make/c-link-to-rust-dylib/rmake.rs @@ -0,0 +1,41 @@ +// This test checks that C linking with Rust does not encounter any errors, with dynamic libraries. +// See . + +//@ ignore-cross-compile + +use std::fs::remove_file; + +use run_make_support::{ + cc, dynamic_lib_extension, is_msvc, read_dir, run, run_fail, rustc, tmp_dir, +}; + +fn main() { + rustc().input("foo.rs").run(); + + if is_msvc() { + let lib = tmp_dir().join("foo.dll.lib"); + + cc().input("bar.c").arg(lib).out_exe("bar").run(); + } else { + cc().input("bar.c") + .arg("-lfoo") + .output(tmp_dir().join("bar")) + .library_search_path(tmp_dir()) + .run(); + } + + run("bar"); + + let expected_extension = dynamic_lib_extension(); + read_dir(tmp_dir(), |path| { + if path.is_file() + && path.extension().is_some_and(|ext| ext == expected_extension) + && path.file_name().and_then(|name| name.to_str()).is_some_and(|name| { + name.ends_with(".so") || name.ends_with(".dll") || name.ends_with(".dylib") + }) + { + remove_file(path).unwrap(); + } + }); + run_fail("bar"); +} diff --git a/tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs b/tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs index e518579b906a..196c6440747a 100644 --- a/tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs +++ b/tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs @@ -1,16 +1,16 @@ #![crate_type = "staticlib"] #![feature(c_variadic)] -use std::ffi::{c_char, c_double, c_int, c_long, c_longlong}; use std::ffi::VaList; -use std::ffi::{CString, CStr}; +use std::ffi::{c_char, c_double, c_int, c_long, c_longlong}; +use std::ffi::{CStr, CString}; macro_rules! continue_if { ($cond:expr) => { if !($cond) { return 0xff; } - } + }; } unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool { @@ -59,13 +59,11 @@ pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize { continue_if!(ap.arg::() == 16); continue_if!(ap.arg::() == 'A' as c_char); continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!")); - ap.with_copy(|mut ap| { - if compare_c_str(ap.arg::<*const c_char>(), "Correct") { - 0 - } else { - 0xff - } - }) + ap.with_copy( + |mut ap| { + if compare_c_str(ap.arg::<*const c_char>(), "Correct") { 0 } else { 0xff } + }, + ) } #[no_mangle] diff --git a/tests/run-make/cdylib/Makefile b/tests/run-make/cdylib/Makefile deleted file mode 100644 index 2c6414c32553..000000000000 --- a/tests/run-make/cdylib/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# When the cdylib crate type was added as a variation of dylib, it needed a test to check its function. -# See https://github.com/rust-lang/rust/pull/33553 - -# ignore-cross-compile -include ../tools.mk - -all: $(call RUN_BINFILE,foo) - $(call RUN,foo) - rm $(call DYLIB,foo) - $(RUSTC) foo.rs -C lto - $(call RUN,foo) - -ifdef IS_MSVC -$(call RUN_BINFILE,foo): $(call DYLIB,foo) - $(CC) $(CFLAGS) foo.c $(TMPDIR)/foo.dll.lib $(call OUT_EXE,foo) -else -$(call RUN_BINFILE,foo): $(call DYLIB,foo) - $(CC) $(CFLAGS) foo.c -lfoo -o $(call RUN_BINFILE,foo) -L $(TMPDIR) -endif - -$(call DYLIB,foo): - $(RUSTC) bar.rs - $(RUSTC) foo.rs diff --git a/tests/run-make/cdylib/rmake.rs b/tests/run-make/cdylib/rmake.rs new file mode 100644 index 000000000000..fcb4f56621f6 --- /dev/null +++ b/tests/run-make/cdylib/rmake.rs @@ -0,0 +1,36 @@ +// This test tries to check that basic cdylib libraries can be compiled and linked successfully +// with C code, that the cdylib itself can depend on another rlib, and that the library can be built +// with LTO. +// +// - `bar.rs` is a rlib +// - `foo.rs` is a cdylib that relies on an extern crate `bar` and defines two `extern "C"` +// functions: +// - `foo()` which calls `bar::bar()`. +// - `bar()` which implements basic addition. + +//@ ignore-cross-compile + +use std::fs::remove_file; + +use run_make_support::{cc, dynamic_lib, is_msvc, run, rustc, tmp_dir}; + +fn main() { + rustc().input("bar.rs").run(); + rustc().input("foo.rs").run(); + + if is_msvc() { + cc().input("foo.c").arg(tmp_dir().join("foo.dll.lib")).out_exe("foo").run(); + } else { + cc().input("foo.c") + .arg("-lfoo") + .output(tmp_dir().join("foo")) + .library_search_path(tmp_dir()) + .run(); + } + + run("foo"); + remove_file(dynamic_lib("foo")).unwrap(); + + rustc().input("foo.rs").arg("-Clto").run(); + run("foo"); +} diff --git a/tests/run-make/compiler-lookup-paths-2/c.rs b/tests/run-make/compiler-lookup-paths-2/c.rs index e37bc2e1dcef..1326edb575ed 100644 --- a/tests/run-make/compiler-lookup-paths-2/c.rs +++ b/tests/run-make/compiler-lookup-paths-2/c.rs @@ -1,3 +1,3 @@ #![crate_type = "lib"] -extern crate b; extern crate a; +extern crate b; diff --git a/tests/run-make/crate-data-smoke/rmake.rs b/tests/run-make/crate-data-smoke/rmake.rs index 80d43903a532..86fe5593e661 100644 --- a/tests/run-make/crate-data-smoke/rmake.rs +++ b/tests/run-make/crate-data-smoke/rmake.rs @@ -3,41 +3,20 @@ use std::process::Output; use run_make_support::{bin_name, rust_lib_name, rustc}; fn compare_stdout>(output: Output, expected: S) { - assert_eq!( - String::from_utf8(output.stdout).unwrap().trim(), - expected.as_ref() - ); + assert_eq!(String::from_utf8(output.stdout).unwrap().trim(), expected.as_ref()); } fn main() { compare_stdout(rustc().print("crate-name").input("crate.rs").run(), "foo"); + compare_stdout(rustc().print("file-names").input("crate.rs").run(), bin_name("foo")); compare_stdout( - rustc().print("file-names").input("crate.rs").run(), + rustc().print("file-names").crate_type("lib").arg("--test").input("crate.rs").run(), bin_name("foo"), ); compare_stdout( - rustc() - .print("file-names") - .crate_type("lib") - .arg("--test") - .input("crate.rs") - .run(), - bin_name("foo"), - ); - compare_stdout( - rustc() - .print("file-names") - .arg("--test") - .input("lib.rs") - .run(), + rustc().print("file-names").arg("--test").input("lib.rs").run(), bin_name("mylib"), ); - compare_stdout( - rustc().print("file-names").input("lib.rs").run(), - rust_lib_name("mylib"), - ); - compare_stdout( - rustc().print("file-names").input("rlib.rs").run(), - rust_lib_name("mylib"), - ); + compare_stdout(rustc().print("file-names").input("lib.rs").run(), rust_lib_name("mylib")); + compare_stdout(rustc().print("file-names").input("rlib.rs").run(), rust_lib_name("mylib")); } diff --git a/tests/run-make/cross-lang-lto-clang/rustlib.rs b/tests/run-make/cross-lang-lto-clang/rustlib.rs index 8a74d74a420b..9aff29ef9bb6 100644 --- a/tests/run-make/cross-lang-lto-clang/rustlib.rs +++ b/tests/run-make/cross-lang-lto-clang/rustlib.rs @@ -1,4 +1,4 @@ -#![crate_type="staticlib"] +#![crate_type = "staticlib"] #[no_mangle] pub extern "C" fn rust_always_inlined() -> u32 { diff --git a/tests/run-make/cross-lang-lto-pgo-smoketest/rustlib.rs b/tests/run-make/cross-lang-lto-pgo-smoketest/rustlib.rs index 8a74d74a420b..9aff29ef9bb6 100644 --- a/tests/run-make/cross-lang-lto-pgo-smoketest/rustlib.rs +++ b/tests/run-make/cross-lang-lto-pgo-smoketest/rustlib.rs @@ -1,4 +1,4 @@ -#![crate_type="staticlib"] +#![crate_type = "staticlib"] #[no_mangle] pub extern "C" fn rust_always_inlined() -> u32 { diff --git a/tests/run-make/cross-lang-lto-upstream-rlibs/staticlib.rs b/tests/run-make/cross-lang-lto-upstream-rlibs/staticlib.rs index 34951dda3b6e..76c24df78987 100644 --- a/tests/run-make/cross-lang-lto-upstream-rlibs/staticlib.rs +++ b/tests/run-make/cross-lang-lto-upstream-rlibs/staticlib.rs @@ -1,4 +1,4 @@ -#![crate_type="staticlib"] +#![crate_type = "staticlib"] extern crate upstream; diff --git a/tests/run-make/debug-assertions/debug.rs b/tests/run-make/debug-assertions/debug.rs index 76ca60a71c88..9eebf60ded09 100644 --- a/tests/run-make/debug-assertions/debug.rs +++ b/tests/run-make/debug-assertions/debug.rs @@ -15,19 +15,33 @@ fn main() { fn debug_assert_eq() { let mut hit1 = false; let mut hit2 = false; - debug_assert_eq!({ hit1 = true; 1 }, { hit2 = true; 2 }); + debug_assert_eq!( + { + hit1 = true; + 1 + }, + { + hit2 = true; + 2 + } + ); assert!(!hit1); assert!(!hit2); } fn debug_assert() { let mut hit = false; - debug_assert!({ hit = true; false }); + debug_assert!({ + hit = true; + false + }); assert!(!hit); } fn overflow() { - fn add(a: u8, b: u8) -> u8 { a + b } + fn add(a: u8, b: u8) -> u8 { + a + b + } add(200u8, 200u8); } diff --git a/tests/run-make/dep-info-spaces/lib.rs b/tests/run-make/dep-info-spaces/lib.rs index 6264e7b67ec6..4e061892cf7a 100644 --- a/tests/run-make/dep-info-spaces/lib.rs +++ b/tests/run-make/dep-info-spaces/lib.rs @@ -1,4 +1,4 @@ -#[path="foo foo.rs"] +#[path = "foo foo.rs"] pub mod foo; pub mod bar; diff --git a/tests/run-make/dep-info/lib.rs b/tests/run-make/dep-info/lib.rs index eb8631259d43..6e2781cd4b20 100644 --- a/tests/run-make/dep-info/lib.rs +++ b/tests/run-make/dep-info/lib.rs @@ -1,4 +1,4 @@ #![crate_name = "foo"] -pub mod foo; pub mod bar; +pub mod foo; diff --git a/tests/run-make/deref-impl-rustdoc-ice/baz.rs b/tests/run-make/deref-impl-rustdoc-ice/baz.rs index cd2425f9b692..f606ef9bd6b6 100644 --- a/tests/run-make/deref-impl-rustdoc-ice/baz.rs +++ b/tests/run-make/deref-impl-rustdoc-ice/baz.rs @@ -1,8 +1,10 @@ -extern crate foo; extern crate bar; +extern crate foo; pub struct Bar; impl ::std::ops::Deref for Bar { type Target = bar::S; - fn deref(&self) -> &Self::Target { unimplemented!() } + fn deref(&self) -> &Self::Target { + unimplemented!() + } } diff --git a/tests/run-make/deref-impl-rustdoc-ice/foo.rs b/tests/run-make/deref-impl-rustdoc-ice/foo.rs index a106e4fde5cc..df00ed4b9e0b 100644 --- a/tests/run-make/deref-impl-rustdoc-ice/foo.rs +++ b/tests/run-make/deref-impl-rustdoc-ice/foo.rs @@ -3,7 +3,9 @@ extern crate proc_macro; #[proc_macro_derive(A)] -pub fn derive(ts: proc_macro::TokenStream) -> proc_macro::TokenStream { ts } +pub fn derive(ts: proc_macro::TokenStream) -> proc_macro::TokenStream { + ts +} #[derive(Debug)] struct S; diff --git a/tests/run-make/dylib-chain/m2.rs b/tests/run-make/dylib-chain/m2.rs index 62176ddc9f35..92950a919154 100644 --- a/tests/run-make/dylib-chain/m2.rs +++ b/tests/run-make/dylib-chain/m2.rs @@ -1,4 +1,6 @@ #![crate_type = "dylib"] extern crate m1; -pub fn m2() { m1::m1() } +pub fn m2() { + m1::m1() +} diff --git a/tests/run-make/dylib-chain/m3.rs b/tests/run-make/dylib-chain/m3.rs index d213aeda9ac1..28a8ca9d7dde 100644 --- a/tests/run-make/dylib-chain/m3.rs +++ b/tests/run-make/dylib-chain/m3.rs @@ -1,4 +1,6 @@ #![crate_type = "dylib"] extern crate m2; -pub fn m3() { m2::m2() } +pub fn m3() { + m2::m2() +} diff --git a/tests/run-make/dylib-chain/m4.rs b/tests/run-make/dylib-chain/m4.rs index fa8ec6079dea..c732512af9fc 100644 --- a/tests/run-make/dylib-chain/m4.rs +++ b/tests/run-make/dylib-chain/m4.rs @@ -1,3 +1,5 @@ extern crate m3; -fn main() { m3::m3() } +fn main() { + m3::m3() +} diff --git a/tests/run-make/emit-named-files/Makefile b/tests/run-make/emit-named-files/Makefile deleted file mode 100644 index 2b97b841fc00..000000000000 --- a/tests/run-make/emit-named-files/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -include ../tools.mk - -OUT=$(TMPDIR)/emit - -all: asm llvm-bc llvm-ir obj metadata link dep-info mir - -asm: $(OUT) - $(RUSTC) --emit asm=$(OUT)/libfoo.s foo.rs - test -f $(OUT)/libfoo.s -llvm-bc: $(OUT) - $(RUSTC) --emit llvm-bc=$(OUT)/libfoo.bc foo.rs - test -f $(OUT)/libfoo.bc -llvm-ir: $(OUT) - $(RUSTC) --emit llvm-ir=$(OUT)/libfoo.ll foo.rs - test -f $(OUT)/libfoo.ll -obj: $(OUT) - $(RUSTC) --emit obj=$(OUT)/libfoo.o foo.rs - test -f $(OUT)/libfoo.o -metadata: $(OUT) - $(RUSTC) --emit metadata=$(OUT)/libfoo.rmeta foo.rs - test -f $(OUT)/libfoo.rmeta -link: $(OUT) - $(RUSTC) --emit link=$(OUT)/libfoo.rlib foo.rs - test -f $(OUT)/libfoo.rlib -dep-info: $(OUT) - $(RUSTC) --emit dep-info=$(OUT)/libfoo.d foo.rs - test -f $(OUT)/libfoo.d -mir: $(OUT) - $(RUSTC) --emit mir=$(OUT)/libfoo.mir foo.rs - test -f $(OUT)/libfoo.mir - -$(OUT): - mkdir -p $(OUT) diff --git a/tests/run-make/emit-named-files/rmake.rs b/tests/run-make/emit-named-files/rmake.rs new file mode 100644 index 000000000000..068f9796d0e9 --- /dev/null +++ b/tests/run-make/emit-named-files/rmake.rs @@ -0,0 +1,25 @@ +use std::fs::create_dir; +use std::path::Path; + +use run_make_support::{rustc, tmp_dir}; + +fn emit_and_check(out_dir: &Path, out_file: &str, format: &str) { + let out_file = out_dir.join(out_file); + rustc().input("foo.rs").emit(&format!("{format}={}", out_file.display())).run(); + assert!(out_file.is_file()); +} + +fn main() { + let out_dir = tmp_dir().join("emit"); + + create_dir(&out_dir).unwrap(); + + emit_and_check(&out_dir, "libfoo.s", "asm"); + emit_and_check(&out_dir, "libfoo.bc", "llvm-bc"); + emit_and_check(&out_dir, "libfoo.ll", "llvm-ir"); + emit_and_check(&out_dir, "libfoo.o", "obj"); + emit_and_check(&out_dir, "libfoo.rmeta", "metadata"); + emit_and_check(&out_dir, "libfoo.rlib", "link"); + emit_and_check(&out_dir, "libfoo.d", "dep-info"); + emit_and_check(&out_dir, "libfoo.mir", "mir"); +} diff --git a/tests/run-make/emit/Makefile b/tests/run-make/emit/Makefile deleted file mode 100644 index b3ca0b79fb0c..000000000000 --- a/tests/run-make/emit/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) -Copt-level=0 --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs - $(RUSTC) -Copt-level=1 --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs - $(RUSTC) -Copt-level=2 --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs - $(RUSTC) -Copt-level=3 --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs - $(RUSTC) -Copt-level=s --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs - $(RUSTC) -Copt-level=z --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs - $(RUSTC) -Copt-level=0 --emit=llvm-bc,llvm-ir,asm,obj,link test-26235.rs - $(call RUN,test-26235) || exit 1 - $(RUSTC) -Copt-level=1 --emit=llvm-bc,llvm-ir,asm,obj,link test-26235.rs - $(call RUN,test-26235) || exit 1 - $(RUSTC) -Copt-level=2 --emit=llvm-bc,llvm-ir,asm,obj,link test-26235.rs - $(call RUN,test-26235) || exit 1 - $(RUSTC) -Copt-level=3 --emit=llvm-bc,llvm-ir,asm,obj,link test-26235.rs - $(call RUN,test-26235) || exit 1 - $(RUSTC) -Copt-level=s --emit=llvm-bc,llvm-ir,asm,obj,link test-26235.rs - $(call RUN,test-26235) || exit 1 - $(RUSTC) -Copt-level=z --emit=llvm-bc,llvm-ir,asm,obj,link test-26235.rs - $(call RUN,test-26235) || exit 1 diff --git a/tests/run-make/emit/rmake.rs b/tests/run-make/emit/rmake.rs new file mode 100644 index 000000000000..8b3ddb66f923 --- /dev/null +++ b/tests/run-make/emit/rmake.rs @@ -0,0 +1,19 @@ +// A bug from 2015 would cause errors when emitting multiple types of files +// in the same rustc call. A fix was created in #30452. This test checks that rustc still compiles +// a source file successfully when emission of multiple output artifacts are requested. +// See https://github.com/rust-lang/rust/pull/30452 + +//@ ignore-cross-compile + +use run_make_support::{run, rustc}; + +fn main() { + let opt_levels = ["0", "1", "2", "3", "s", "z"]; + for level in opt_levels { + rustc().opt_level(level).emit("llvm-bc,llvm-ir,asm,obj,link").input("test-24876.rs").run(); + } + for level in opt_levels { + rustc().opt_level(level).emit("llvm-bc,llvm-ir,asm,obj,link").input("test-26235.rs").run(); + run("test-26235"); + } +} diff --git a/tests/run-make/emit/test-26235.rs b/tests/run-make/emit/test-26235.rs index 07d975f3317c..d91c46d2dec8 100644 --- a/tests/run-make/emit/test-26235.rs +++ b/tests/run-make/emit/test-26235.rs @@ -6,16 +6,22 @@ fn main() { type Key = u32; const NUM_THREADS: usize = 2; - #[derive(Clone,Copy)] + #[derive(Clone, Copy)] struct Stats { upsert: S, delete: S, insert: S, - update: S + update: S, }; - impl Stats where S: Copy { - fn dot(self, s: Stats, f: F) -> Stats where F: Fn(S, T) -> B { + impl Stats + where + S: Copy, + { + fn dot(self, s: Stats, f: F) -> Stats + where + F: Fn(S, T) -> B, + { let Stats { upsert: u1, delete: d1, insert: i1, update: p1 } = self; let Stats { upsert: u2, delete: d2, insert: i2, update: p2 } = s; Stats { upsert: f(u1, u2), delete: f(d1, d2), insert: f(i1, i2), update: f(p1, p2) } @@ -38,9 +44,12 @@ fn main() { make_threads(); { - let Stats { ref upsert, ref delete, ref insert, ref update } = stats.iter().fold( - Stats::new(0), |res, &s| res.dot(s, |x: Key, y: Key| x.wrapping_add(y))); - println!("upserts: {}, deletes: {}, inserts: {}, updates: {}", - upsert, delete, insert, update); + let Stats { ref upsert, ref delete, ref insert, ref update } = stats + .iter() + .fold(Stats::new(0), |res, &s| res.dot(s, |x: Key, y: Key| x.wrapping_add(y))); + println!( + "upserts: {}, deletes: {}, inserts: {}, updates: {}", + upsert, delete, insert, update + ); } } diff --git a/tests/run-make/extern-diff-internal-name/test.rs b/tests/run-make/extern-diff-internal-name/test.rs index 4c53dc28a80e..d210f8833165 100644 --- a/tests/run-make/extern-diff-internal-name/test.rs +++ b/tests/run-make/extern-diff-internal-name/test.rs @@ -1,5 +1,4 @@ #[macro_use] extern crate foo; -fn main() { -} +fn main() {} diff --git a/tests/run-make/extern-flag-disambiguates/a.rs b/tests/run-make/extern-flag-disambiguates/a.rs index 2b1a3190150f..fe4bb5ccac40 100644 --- a/tests/run-make/extern-flag-disambiguates/a.rs +++ b/tests/run-make/extern-flag-disambiguates/a.rs @@ -3,4 +3,6 @@ static FOO: usize = 3; -pub fn token() -> &'static usize { &FOO } +pub fn token() -> &'static usize { + &FOO +} diff --git a/tests/run-make/extern-flag-disambiguates/b.rs b/tests/run-make/extern-flag-disambiguates/b.rs index 1d7a7339ce27..fc3303e5ef8a 100644 --- a/tests/run-make/extern-flag-disambiguates/b.rs +++ b/tests/run-make/extern-flag-disambiguates/b.rs @@ -5,5 +5,9 @@ extern crate a; static FOO: usize = 3; -pub fn token() -> &'static usize { &FOO } -pub fn a_token() -> &'static usize { a::token() } +pub fn token() -> &'static usize { + &FOO +} +pub fn a_token() -> &'static usize { + a::token() +} diff --git a/tests/run-make/extern-flag-disambiguates/c.rs b/tests/run-make/extern-flag-disambiguates/c.rs index 3f9d143ed2dc..26ac787e74d1 100644 --- a/tests/run-make/extern-flag-disambiguates/c.rs +++ b/tests/run-make/extern-flag-disambiguates/c.rs @@ -5,5 +5,9 @@ extern crate a; static FOO: usize = 3; -pub fn token() -> &'static usize { &FOO } -pub fn a_token() -> &'static usize { a::token() } +pub fn token() -> &'static usize { + &FOO +} +pub fn a_token() -> &'static usize { + a::token() +} diff --git a/tests/run-make/extern-flag-disambiguates/d.rs b/tests/run-make/extern-flag-disambiguates/d.rs index 249c6a107ff3..f0ab2b063e11 100644 --- a/tests/run-make/extern-flag-disambiguates/d.rs +++ b/tests/run-make/extern-flag-disambiguates/d.rs @@ -1,9 +1,13 @@ -#[cfg(before)] extern crate a; +#[cfg(before)] +extern crate a; +#[cfg(after)] +extern crate a; extern crate b; extern crate c; -#[cfg(after)] extern crate a; -fn t(a: &'static usize) -> usize { a as *const _ as usize } +fn t(a: &'static usize) -> usize { + a as *const _ as usize +} fn main() { assert_eq!(t(a::token()), t(b::a_token())); diff --git a/tests/run-make/extern-fn-explicit-align/test.rs b/tests/run-make/extern-fn-explicit-align/test.rs index 846622de3cd1..81991b5919ce 100644 --- a/tests/run-make/extern-fn-explicit-align/test.rs +++ b/tests/run-make/extern-fn-explicit-align/test.rs @@ -1,6 +1,6 @@ // Issue #80127: Passing structs via FFI should work with explicit alignment. -use std::ffi::{CStr, c_char}; +use std::ffi::{c_char, CStr}; use std::ptr::null_mut; #[repr(C)] @@ -18,7 +18,7 @@ pub struct TwoU64s { #[repr(C)] pub struct WrappedU64s { - pub a: TwoU64s + pub a: TwoU64s, } #[repr(C)] diff --git a/tests/run-make/extern-fn-reachable/dylib.rs b/tests/run-make/extern-fn-reachable/dylib.rs index cd0179348705..fe0c7023b27b 100644 --- a/tests/run-make/extern-fn-reachable/dylib.rs +++ b/tests/run-make/extern-fn-reachable/dylib.rs @@ -1,14 +1,19 @@ #![crate_type = "dylib"] #![allow(dead_code)] -#[no_mangle] pub extern "C" fn fun1() {} -#[no_mangle] extern "C" fn fun2() {} +#[no_mangle] +pub extern "C" fn fun1() {} +#[no_mangle] +extern "C" fn fun2() {} mod foo { - #[no_mangle] pub extern "C" fn fun3() {} + #[no_mangle] + pub extern "C" fn fun3() {} } pub mod bar { - #[no_mangle] pub extern "C" fn fun4() {} + #[no_mangle] + pub extern "C" fn fun4() {} } -#[no_mangle] pub fn fun5() {} +#[no_mangle] +pub fn fun5() {} diff --git a/tests/run-make/extern-fn-struct-passing-abi/test.rs b/tests/run-make/extern-fn-struct-passing-abi/test.rs index 99e079f98a87..f898592fce98 100644 --- a/tests/run-make/extern-fn-struct-passing-abi/test.rs +++ b/tests/run-make/extern-fn-struct-passing-abi/test.rs @@ -90,8 +90,12 @@ extern "C" { fn byval_rect_with_many_huge(a: Huge, b: Huge, c: Huge, d: Huge, e: Huge, f: Huge, g: Rect); fn byval_rect_with_many_huge64( - a: Huge64, b: Huge64, c: Huge64, - d: Huge64, e: Huge64, f: Huge64, + a: Huge64, + b: Huge64, + c: Huge64, + d: Huge64, + e: Huge64, + f: Huge64, g: Rect, ); diff --git a/tests/run-make/extern-multiple-copies/bar.rs b/tests/run-make/extern-multiple-copies/bar.rs index c6b3595f6775..aa0bee77cb29 100644 --- a/tests/run-make/extern-multiple-copies/bar.rs +++ b/tests/run-make/extern-multiple-copies/bar.rs @@ -1,5 +1,5 @@ -extern crate foo2; // foo2 first to exhibit the bug extern crate foo1; +extern crate foo2; // foo2 first to exhibit the bug fn main() { /* ... */ diff --git a/tests/run-make/external-crate-panic-handle-no-lint/app.rs b/tests/run-make/external-crate-panic-handle-no-lint/app.rs index 8127b9578bfe..e0168579ccab 100644 --- a/tests/run-make/external-crate-panic-handle-no-lint/app.rs +++ b/tests/run-make/external-crate-panic-handle-no-lint/app.rs @@ -1,7 +1,6 @@ #![crate_type = "bin"] #![no_main] #![no_std] - #![deny(unused_extern_crates)] // `panic` provides a `panic_handler` so it shouldn't trip the `unused_extern_crates` lint diff --git a/tests/run-make/incr-prev-body-beyond-eof/a.rs b/tests/run-make/incr-prev-body-beyond-eof/a.rs index ca70fb563349..59ac25444000 100644 --- a/tests/run-make/incr-prev-body-beyond-eof/a.rs +++ b/tests/run-make/incr-prev-body-beyond-eof/a.rs @@ -9,8 +9,4 @@ fn main() { // Basically, avoid modifying this file, including adding or removing whitespace! fn foo() { assert_eq!(1, 1); - - - - } diff --git a/tests/run-make/incr-prev-body-beyond-eof/b.rs b/tests/run-make/incr-prev-body-beyond-eof/b.rs index a272e44a6326..2f26a1ffe97a 100644 --- a/tests/run-make/incr-prev-body-beyond-eof/b.rs +++ b/tests/run-make/incr-prev-body-beyond-eof/b.rs @@ -8,5 +8,5 @@ fn main() { // a.rs, the body must end on a line number which does not exist in b.rs. // Basically, avoid modifying this file, including adding or removing whitespace! fn foo() { - assert_eq!(1, 1);//// + assert_eq!(1, 1); //// } diff --git a/tests/run-make/inline-always-many-cgu/foo.rs b/tests/run-make/inline-always-many-cgu/foo.rs index 65fe69c16fe7..b7c5371ea49c 100644 --- a/tests/run-make/inline-always-many-cgu/foo.rs +++ b/tests/run-make/inline-always-many-cgu/foo.rs @@ -2,11 +2,9 @@ pub mod a { #[inline(always)] - pub fn foo() { - } + pub fn foo() {} - pub fn bar() { - } + pub fn bar() {} } #[no_mangle] diff --git a/tests/run-make/interdependent-c-libraries/main.rs b/tests/run-make/interdependent-c-libraries/main.rs index 2aba427df474..a429030d3a2b 100644 --- a/tests/run-make/interdependent-c-libraries/main.rs +++ b/tests/run-make/interdependent-c-libraries/main.rs @@ -1,5 +1,5 @@ -extern crate foo; extern crate bar; +extern crate foo; fn main() { bar::doit(); diff --git a/tests/run-make/intrinsic-unreachable/exit-ret.rs b/tests/run-make/intrinsic-unreachable/exit-ret.rs index c8ba5b4599f2..3653316b5c67 100644 --- a/tests/run-make/intrinsic-unreachable/exit-ret.rs +++ b/tests/run-make/intrinsic-unreachable/exit-ret.rs @@ -1,4 +1,4 @@ -#![crate_type="lib"] +#![crate_type = "lib"] use std::arch::asm; #[deny(unreachable_code)] diff --git a/tests/run-make/intrinsic-unreachable/exit-unreachable.rs b/tests/run-make/intrinsic-unreachable/exit-unreachable.rs index 75f893eb2df1..d0f193d49eef 100644 --- a/tests/run-make/intrinsic-unreachable/exit-unreachable.rs +++ b/tests/run-make/intrinsic-unreachable/exit-unreachable.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] -#![crate_type="lib"] +#![crate_type = "lib"] use std::arch::asm; use std::intrinsics; diff --git a/tests/run-make/issue-18943/foo.rs b/tests/run-make/issue-18943/foo.rs index d18400dd3a54..54daec8dd1ea 100644 --- a/tests/run-make/issue-18943/foo.rs +++ b/tests/run-make/issue-18943/foo.rs @@ -1,5 +1,5 @@ -trait Foo { } +trait Foo {} -trait Bar { } +trait Bar {} -impl<'a> Foo for Bar + 'a { } +impl<'a> Foo for Bar + 'a {} diff --git a/tests/run-make/issue-20626/foo.rs b/tests/run-make/issue-20626/foo.rs index a474e234e72d..1007686d9fe1 100644 --- a/tests/run-make/issue-20626/foo.rs +++ b/tests/run-make/issue-20626/foo.rs @@ -1,4 +1,6 @@ -fn identity(a: &u32) -> &u32 { a } +fn identity(a: &u32) -> &u32 { + a +} fn print_foo(f: &fn(&u32) -> &u32, x: &u32) { print!("{}", (*f)(x)); diff --git a/tests/run-make/issue-22131/foo.rs b/tests/run-make/issue-22131/foo.rs index 33255d76879f..7b955a07b979 100644 --- a/tests/run-make/issue-22131/foo.rs +++ b/tests/run-make/issue-22131/foo.rs @@ -2,4 +2,6 @@ /// assert_eq!(foo::foo(), 1); /// ``` #[cfg(feature = "bar")] -pub fn foo() -> i32 { 1 } +pub fn foo() -> i32 { + 1 +} diff --git a/tests/run-make/issue-26006/in/libc/lib.rs b/tests/run-make/issue-26006/in/libc/lib.rs index 23f2bf51800a..bad155a99bd6 100644 --- a/tests/run-make/issue-26006/in/libc/lib.rs +++ b/tests/run-make/issue-26006/in/libc/lib.rs @@ -1,3 +1,3 @@ -#![crate_type="rlib"] +#![crate_type = "rlib"] -pub fn something(){} +pub fn something() {} diff --git a/tests/run-make/issue-26006/in/time/lib.rs b/tests/run-make/issue-26006/in/time/lib.rs index 87f2f824a366..51ed27cd713f 100644 --- a/tests/run-make/issue-26006/in/time/lib.rs +++ b/tests/run-make/issue-26006/in/time/lib.rs @@ -1,4 +1,4 @@ #![feature(rustc_private)] extern crate libc; -fn main(){} +fn main() {} diff --git a/tests/run-make/issue-37839/b.rs b/tests/run-make/issue-37839/b.rs index 355d2b165274..067f47c1b7a1 100644 --- a/tests/run-make/issue-37839/b.rs +++ b/tests/run-make/issue-37839/b.rs @@ -1,2 +1,3 @@ #![crate_type = "lib"] -#[macro_use] extern crate a; +#[macro_use] +extern crate a; diff --git a/tests/run-make/issue-47551/eh_frame-terminator.rs b/tests/run-make/issue-47551/eh_frame-terminator.rs index 35db4bc7d1f7..0c90d8c791c7 100644 --- a/tests/run-make/issue-47551/eh_frame-terminator.rs +++ b/tests/run-make/issue-47551/eh_frame-terminator.rs @@ -7,9 +7,7 @@ struct Foo { impl Foo { const fn new() -> Self { - Self { - array: [0x1122_3344_5566_7788; 10240] - } + Self { array: [0x1122_3344_5566_7788; 10240] } } } diff --git a/tests/run-make/issue-69368/c.rs b/tests/run-make/issue-69368/c.rs index 729c4249a053..9d72657aa593 100644 --- a/tests/run-make/issue-69368/c.rs +++ b/tests/run-make/issue-69368/c.rs @@ -2,8 +2,8 @@ #![feature(start)] #![no_std] -extern crate alloc; extern crate a; +extern crate alloc; extern crate b; use alloc::vec::Vec; diff --git a/tests/run-make/link-arg/empty.rs b/tests/run-make/link-arg/empty.rs index 45590d86ba6c..f328e4d9d04c 100644 --- a/tests/run-make/link-arg/empty.rs +++ b/tests/run-make/link-arg/empty.rs @@ -1 +1 @@ -fn main() { } +fn main() {} diff --git a/tests/run-make/long-linker-command-lines-cmd-exe/foo.rs b/tests/run-make/long-linker-command-lines-cmd-exe/foo.rs index 74d7b9b07f69..1d5202dcdb49 100644 --- a/tests/run-make/long-linker-command-lines-cmd-exe/foo.rs +++ b/tests/run-make/long-linker-command-lines-cmd-exe/foo.rs @@ -13,13 +13,13 @@ use std::env; use std::fs::{self, File}; -use std::io::{BufWriter, Write, Read}; +use std::io::{BufWriter, Read, Write}; use std::path::PathBuf; use std::process::Command; fn main() { if !cfg!(windows) { - return + return; } let tmpdir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); @@ -31,16 +31,16 @@ fn main() { let file = file.to_str().unwrap(); fs::copy(&file[1..], &ok).unwrap(); } - None => { File::create(¬_ok).unwrap(); } + None => { + File::create(¬_ok).unwrap(); + } } - return + return; } let rustc = env::var_os("RUSTC").unwrap_or("rustc".into()); let me = env::current_exe().unwrap(); - let bat = me.parent() - .unwrap() - .join("foo.bat"); + let bat = me.parent().unwrap().join("foo.bat"); let bat_linker = format!("linker={}", bat.display()); for i in (1..).map(|i| i * 10) { println!("attempt: {}", i); @@ -61,8 +61,10 @@ fn main() { drop(fs::remove_file(¬_ok)); let status = Command::new(&rustc) .arg(&file) - .arg("-C").arg(&bat_linker) - .arg("--out-dir").arg(&tmpdir) + .arg("-C") + .arg(&bat_linker) + .arg("--out-dir") + .arg(&tmpdir) .env("YOU_ARE_A_LINKER", "1") .env("MY_LINKER", &me) .status() @@ -74,7 +76,7 @@ fn main() { if !ok.exists() { assert!(not_ok.exists()); - continue + continue; } let mut contents = Vec::new(); @@ -96,6 +98,6 @@ fn main() { assert!(contents.windows(exp.len()).any(|w| w == &exp[..])); } - break + break; } } diff --git a/tests/run-make/long-linker-command-lines/foo.rs b/tests/run-make/long-linker-command-lines/foo.rs index db238c0cf1a9..9d4a701ad876 100644 --- a/tests/run-make/long-linker-command-lines/foo.rs +++ b/tests/run-make/long-linker-command-lines/foo.rs @@ -34,9 +34,7 @@ fn write_test_case(file: &Path, n: usize) -> HashSet { fn read_linker_args(path: &Path) -> String { let contents = fs::read(path).unwrap(); if cfg!(target_env = "msvc") { - let mut i = contents.chunks(2).map(|c| { - c[0] as u16 | ((c[1] as u16) << 8) - }); + let mut i = contents.chunks(2).map(|c| c[0] as u16 | ((c[1] as u16) << 8)); assert_eq!(i.next(), Some(0xfeff), "Expected UTF-16 BOM"); String::from_utf16(&i.collect::>()).unwrap() } else { @@ -52,7 +50,7 @@ fn main() { let file = file.to_str().expect("non-utf8 file argument"); fs::copy(&file[1..], &ok).unwrap(); } - return + return; } let rustc = env::var_os("RUSTC").unwrap_or("rustc".into()); @@ -65,28 +63,35 @@ fn main() { drop(fs::remove_file(&ok)); let output = Command::new(&rustc) .arg(&file) - .arg("-C").arg(&me_as_linker) - .arg("--out-dir").arg(&tmpdir) + .arg("-C") + .arg(&me_as_linker) + .arg("--out-dir") + .arg(&tmpdir) .env("YOU_ARE_A_LINKER", "1") .output() .unwrap(); if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); - panic!("status: {}\nstdout:\n{}\nstderr:\n{}", - output.status, - String::from_utf8_lossy(&output.stdout), - stderr.lines().map(|l| { - if l.len() > 200 { - format!("{}...\n", &l[..200]) - } else { - format!("{}\n", l) - } - }).collect::()); + panic!( + "status: {}\nstdout:\n{}\nstderr:\n{}", + output.status, + String::from_utf8_lossy(&output.stdout), + stderr + .lines() + .map(|l| { + if l.len() > 200 { + format!("{}...\n", &l[..200]) + } else { + format!("{}\n", l) + } + }) + .collect::() + ); } if !ok.exists() { - continue + continue; } let linker_args = read_linker_args(&ok); @@ -101,6 +106,6 @@ fn main() { linker_args, ); - break + break; } } diff --git a/tests/run-make/many-crates-but-no-match/crateA1.rs b/tests/run-make/many-crates-but-no-match/crateA1.rs index 3fed5a38e2ca..f3025909b7de 100644 --- a/tests/run-make/many-crates-but-no-match/crateA1.rs +++ b/tests/run-make/many-crates-but-no-match/crateA1.rs @@ -1,4 +1,4 @@ -#![crate_name="crateA"] +#![crate_name = "crateA"] // Base crate pub fn func() {} diff --git a/tests/run-make/many-crates-but-no-match/crateA2.rs b/tests/run-make/many-crates-but-no-match/crateA2.rs index 8db07a015ff2..ff9f9d4d300b 100644 --- a/tests/run-make/many-crates-but-no-match/crateA2.rs +++ b/tests/run-make/many-crates-but-no-match/crateA2.rs @@ -1,4 +1,6 @@ -#![crate_name="crateA"] +#![crate_name = "crateA"] // Base crate -pub fn func() { println!("hello"); } +pub fn func() { + println!("hello"); +} diff --git a/tests/run-make/many-crates-but-no-match/crateA3.rs b/tests/run-make/many-crates-but-no-match/crateA3.rs index a1e8e40a38c2..dddf7f728eed 100644 --- a/tests/run-make/many-crates-but-no-match/crateA3.rs +++ b/tests/run-make/many-crates-but-no-match/crateA3.rs @@ -1,4 +1,6 @@ -#![crate_name="crateA"] +#![crate_name = "crateA"] // Base crate -pub fn foo() { println!("world!"); } +pub fn foo() { + println!("world!"); +} diff --git a/tests/run-make/metadata-flag-frobs-symbols/foo.rs b/tests/run-make/metadata-flag-frobs-symbols/foo.rs index 696aed2fa1db..cdc8433d8a40 100644 --- a/tests/run-make/metadata-flag-frobs-symbols/foo.rs +++ b/tests/run-make/metadata-flag-frobs-symbols/foo.rs @@ -3,4 +3,6 @@ static FOO: usize = 3; -pub fn foo() -> &'static usize { &FOO } +pub fn foo() -> &'static usize { + &FOO +} diff --git a/tests/run-make/mixing-deps/dylib.rs b/tests/run-make/mixing-deps/dylib.rs index 88976d5b663f..f3dd134249db 100644 --- a/tests/run-make/mixing-deps/dylib.rs +++ b/tests/run-make/mixing-deps/dylib.rs @@ -3,4 +3,6 @@ extern crate both; use std::mem; -pub fn addr() -> usize { unsafe { mem::transmute(&both::foo) } } +pub fn addr() -> usize { + unsafe { mem::transmute(&both::foo) } +} diff --git a/tests/run-make/mixing-deps/prog.rs b/tests/run-make/mixing-deps/prog.rs index 188981dc1a31..1e52ee16982d 100644 --- a/tests/run-make/mixing-deps/prog.rs +++ b/tests/run-make/mixing-deps/prog.rs @@ -1,9 +1,8 @@ -extern crate dylib; extern crate both; +extern crate dylib; use std::mem; fn main() { - assert_eq!(unsafe { mem::transmute::<&isize, usize>(&both::foo) }, - dylib::addr()); + assert_eq!(unsafe { mem::transmute::<&isize, usize>(&both::foo) }, dylib::addr()); } diff --git a/tests/run-make/mixing-formats/Makefile b/tests/run-make/mixing-formats/Makefile deleted file mode 100644 index d01978a15995..000000000000 --- a/tests/run-make/mixing-formats/Makefile +++ /dev/null @@ -1,75 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# Testing various mixings of rlibs and dylibs. Makes sure that it's possible to -# link an rlib to a dylib. The dependency tree among the file looks like: -# -# foo -# / \ -# bar1 bar2 -# / \ / -# baz baz2 -# -# This is generally testing the permutations of the foo/bar1/bar2 layer against -# the baz/baz2 layer - -all: - # Building just baz - $(RUSTC) --crate-type=rlib foo.rs - $(RUSTC) --crate-type=dylib bar1.rs -C prefer-dynamic - $(RUSTC) --crate-type=dylib,rlib baz.rs -C prefer-dynamic - $(RUSTC) --crate-type=bin baz.rs - rm $(TMPDIR)/* - $(RUSTC) --crate-type=dylib foo.rs -C prefer-dynamic - $(RUSTC) --crate-type=rlib bar1.rs - $(RUSTC) --crate-type=dylib,rlib baz.rs -C prefer-dynamic - $(RUSTC) --crate-type=bin baz.rs - rm $(TMPDIR)/* - # Building baz2 - $(RUSTC) --crate-type=rlib foo.rs - $(RUSTC) --crate-type=dylib bar1.rs -C prefer-dynamic - $(RUSTC) --crate-type=dylib bar2.rs -C prefer-dynamic - $(RUSTC) --crate-type=dylib baz2.rs && exit 1 || exit 0 - $(RUSTC) --crate-type=bin baz2.rs && exit 1 || exit 0 - rm $(TMPDIR)/* - $(RUSTC) --crate-type=rlib foo.rs - $(RUSTC) --crate-type=rlib bar1.rs - $(RUSTC) --crate-type=dylib bar2.rs -C prefer-dynamic - $(RUSTC) --crate-type=dylib,rlib baz2.rs - $(RUSTC) --crate-type=bin baz2.rs - rm $(TMPDIR)/* - $(RUSTC) --crate-type=rlib foo.rs - $(RUSTC) --crate-type=dylib bar1.rs -C prefer-dynamic - $(RUSTC) --crate-type=rlib bar2.rs - $(RUSTC) --crate-type=dylib,rlib baz2.rs -C prefer-dynamic - $(RUSTC) --crate-type=bin baz2.rs - rm $(TMPDIR)/* - $(RUSTC) --crate-type=rlib foo.rs - $(RUSTC) --crate-type=rlib bar1.rs - $(RUSTC) --crate-type=rlib bar2.rs - $(RUSTC) --crate-type=dylib,rlib baz2.rs -C prefer-dynamic - $(RUSTC) --crate-type=bin baz2.rs - rm $(TMPDIR)/* - $(RUSTC) --crate-type=dylib foo.rs -C prefer-dynamic - $(RUSTC) --crate-type=rlib bar1.rs - $(RUSTC) --crate-type=rlib bar2.rs - $(RUSTC) --crate-type=dylib,rlib baz2.rs -C prefer-dynamic - $(RUSTC) --crate-type=bin baz2.rs - rm $(TMPDIR)/* - $(RUSTC) --crate-type=dylib foo.rs -C prefer-dynamic - $(RUSTC) --crate-type=dylib bar1.rs -C prefer-dynamic - $(RUSTC) --crate-type=rlib bar2.rs - $(RUSTC) --crate-type=dylib,rlib baz2.rs - $(RUSTC) --crate-type=bin baz2.rs - rm $(TMPDIR)/* - $(RUSTC) --crate-type=dylib foo.rs -C prefer-dynamic - $(RUSTC) --crate-type=rlib bar1.rs - $(RUSTC) --crate-type=dylib bar2.rs -C prefer-dynamic - $(RUSTC) --crate-type=dylib,rlib baz2.rs - $(RUSTC) --crate-type=bin baz2.rs - rm $(TMPDIR)/* - $(RUSTC) --crate-type=dylib foo.rs -C prefer-dynamic - $(RUSTC) --crate-type=dylib bar1.rs -C prefer-dynamic - $(RUSTC) --crate-type=dylib bar2.rs -C prefer-dynamic - $(RUSTC) --crate-type=dylib,rlib baz2.rs - $(RUSTC) --crate-type=bin baz2.rs diff --git a/tests/run-make/mixing-formats/rmake.rs b/tests/run-make/mixing-formats/rmake.rs new file mode 100644 index 000000000000..0d40b0325f77 --- /dev/null +++ b/tests/run-make/mixing-formats/rmake.rs @@ -0,0 +1,94 @@ +// Testing various mixings of rlibs and dylibs. Makes sure that it's possible to +// link an rlib to a dylib. The dependency tree among the file looks like: +// +// foo +// / \ +// bar1 bar2 +// / \ / +// baz baz2 +// +// This is generally testing the permutations of the foo/bar1/bar2 layer against +// the baz/baz2 layer + +//@ ignore-cross-compile + +use run_make_support::{rustc, tmp_dir}; +use std::fs; + +fn test_with_teardown(rustc_calls: impl Fn()) { + rustc_calls(); + //FIXME(Oneirical): This should be replaced with the run-make-support fs wrappers. + fs::remove_dir_all(tmp_dir()).unwrap(); + fs::create_dir(tmp_dir()).unwrap(); +} + +fn main() { + test_with_teardown(|| { + // Building just baz + rustc().crate_type("rlib").input("foo.rs").run(); + rustc().crate_type("dylib").input("bar1.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("dylib,rlib").input("baz.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("bin").input("baz.rs").run(); + }); + test_with_teardown(|| { + rustc().crate_type("dylib").input("foo.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("rlib").input("bar1.rs").run(); + rustc().crate_type("dylib,rlib").input("baz.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("bin").input("baz.rs").run(); + }); + test_with_teardown(|| { + // Building baz2 + rustc().crate_type("rlib").input("foo.rs").run(); + rustc().crate_type("dylib").input("bar1.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("dylib").input("bar2.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("dylib").input("baz2.rs").run_fail_assert_exit_code(1); + rustc().crate_type("bin").input("baz2.rs").run_fail_assert_exit_code(1); + }); + test_with_teardown(|| { + rustc().crate_type("rlib").input("foo.rs").run(); + rustc().crate_type("rlib").input("bar1.rs").run(); + rustc().crate_type("dylib").input("bar2.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("dylib,rlib").input("baz2.rs").run(); + rustc().crate_type("bin").input("baz2.rs").run(); + }); + test_with_teardown(|| { + rustc().crate_type("rlib").input("foo.rs").run(); + rustc().crate_type("dylib").input("bar1.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("rlib").input("bar2.rs").run(); + rustc().crate_type("dylib,rlib").input("baz2.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("bin").input("baz2.rs").run(); + }); + test_with_teardown(|| { + rustc().crate_type("rlib").input("foo.rs").run(); + rustc().crate_type("rlib").input("bar1.rs").run(); + rustc().crate_type("rlib").input("bar2.rs").run(); + rustc().crate_type("dylib,rlib").input("baz2.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("bin").input("baz2.rs").run(); + }); + test_with_teardown(|| { + rustc().crate_type("dylib").input("foo.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("rlib").input("bar1.rs").run(); + rustc().crate_type("rlib").input("bar2.rs").run(); + rustc().crate_type("dylib,rlib").input("baz2.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("bin").input("baz2.rs").run(); + }); + test_with_teardown(|| { + rustc().crate_type("dylib").input("foo.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("dylib").input("bar1.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("rlib").input("bar2.rs").run(); + rustc().crate_type("dylib,rlib").input("baz2.rs").run(); + rustc().crate_type("bin").input("baz2.rs").run(); + }); + test_with_teardown(|| { + rustc().crate_type("dylib").input("foo.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("rlib").input("bar1.rs").run(); + rustc().crate_type("dylib").input("bar2.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("dylib,rlib").input("baz2.rs").run(); + rustc().crate_type("bin").input("baz2.rs").run(); + }); + rustc().crate_type("dylib").input("foo.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("dylib").input("bar1.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("dylib").input("bar2.rs").arg("-Cprefer-dynamic").run(); + rustc().crate_type("dylib,rlib").input("baz2.rs").run(); + rustc().crate_type("bin").input("baz2.rs").run(); +} diff --git a/tests/run-make/mixing-libs/dylib.rs b/tests/run-make/mixing-libs/dylib.rs index 6856887501c2..cde5cc139ba6 100644 --- a/tests/run-make/mixing-libs/dylib.rs +++ b/tests/run-make/mixing-libs/dylib.rs @@ -1,4 +1,6 @@ #![crate_type = "dylib"] extern crate rlib; -pub fn dylib() { rlib::rlib() } +pub fn dylib() { + rlib::rlib() +} diff --git a/tests/run-make/native-link-modifier-whole-archive/native_lib_in_src.rs b/tests/run-make/native-link-modifier-whole-archive/native_lib_in_src.rs index 971f3be7a61e..d5bc0c3eb697 100644 --- a/tests/run-make/native-link-modifier-whole-archive/native_lib_in_src.rs +++ b/tests/run-make/native-link-modifier-whole-archive/native_lib_in_src.rs @@ -1,9 +1,11 @@ use std::io::Write; -#[link(name = "c_static_lib_with_constructor", - kind = "static", - modifiers = "-bundle,+whole-archive")] -extern {} +#[link( + name = "c_static_lib_with_constructor", + kind = "static", + modifiers = "-bundle,+whole-archive" +)] +extern "C" {} pub fn hello() { print!("native_lib_in_src."); diff --git a/tests/run-make/non-pie-thread-local/foo.rs b/tests/run-make/non-pie-thread-local/foo.rs index b67f3847cd49..30d2537750d7 100644 --- a/tests/run-make/non-pie-thread-local/foo.rs +++ b/tests/run-make/non-pie-thread-local/foo.rs @@ -2,7 +2,9 @@ struct Destroy; impl Drop for Destroy { - fn drop(&mut self) { println!("drop"); } + fn drop(&mut self) { + println!("drop"); + } } thread_local! { diff --git a/tests/run-make/notify-all-emit-artifacts/lib.rs b/tests/run-make/notify-all-emit-artifacts/lib.rs new file mode 100644 index 000000000000..6ed194204b45 --- /dev/null +++ b/tests/run-make/notify-all-emit-artifacts/lib.rs @@ -0,0 +1,21 @@ +fn one() -> usize { + 1 +} + +pub mod a { + pub fn two() -> usize { + ::one() + ::one() + } +} + +pub mod b { + pub fn three() -> usize { + ::one() + ::a::two() + } +} + +#[inline(never)] +pub fn main() { + a::two(); + b::three(); +} diff --git a/tests/run-make/notify-all-emit-artifacts/rmake.rs b/tests/run-make/notify-all-emit-artifacts/rmake.rs new file mode 100644 index 000000000000..c866d9179f94 --- /dev/null +++ b/tests/run-make/notify-all-emit-artifacts/rmake.rs @@ -0,0 +1,45 @@ +// rust should produce artifact notifications about files it was asked to --emit. +// +// It should work in incremental mode both on the first pass where files are generated as well +// as on subsequent passes where they are taken from the incremental cache +// +// See +extern crate run_make_support; + +use run_make_support::{rustc, tmp_dir}; + +fn main() { + let inc_dir = tmp_dir(); + + // With single codegen unit files are renamed to match the source file name + for _ in 0..=1 { + let output = rustc() + .input("lib.rs") + .emit("obj,asm,llvm-ir,llvm-bc,mir") + .codegen_units(1) + .json("artifacts") + .error_format("json") + .incremental(&inc_dir) + .run(); + let stderr = String::from_utf8_lossy(&output.stderr); + for file in &["lib.o", "lib.ll", "lib.bc", "lib.s"] { + assert!(stderr.contains(file), "No {:?} in {:?}", file, stderr); + } + } + + // with multiple codegen units files keep codegen unit id part. + for _ in 0..=1 { + let output = rustc() + .input("lib.rs") + .emit("obj,asm,llvm-ir,llvm-bc,mir") + .codegen_units(2) + .json("artifacts") + .error_format("json") + .incremental(&inc_dir) + .run(); + let stderr = String::from_utf8_lossy(&output.stderr); + for file in &["rcgu.o", "rcgu.ll", "rcgu.bc", "rcgu.s"] { + assert!(stderr.contains(file), "No {:?} in {:?}", file, stderr); + } + } +} diff --git a/tests/run-make/pass-non-c-like-enum-to-c/nonclike.rs b/tests/run-make/pass-non-c-like-enum-to-c/nonclike.rs index 517286a868d8..7b5c620b3381 100644 --- a/tests/run-make/pass-non-c-like-enum-to-c/nonclike.rs +++ b/tests/run-make/pass-non-c-like-enum-to-c/nonclike.rs @@ -4,7 +4,7 @@ pub enum TT { BB, } -#[repr(C,u8)] +#[repr(C, u8)] pub enum T { A(u64), B, @@ -16,6 +16,6 @@ extern "C" { } fn main() { - assert_eq!(33, unsafe { tt_add(TT::AA(1,2), TT::AA(10,20)) }); + assert_eq!(33, unsafe { tt_add(TT::AA(1, 2), TT::AA(10, 20)) }); assert_eq!(11, unsafe { t_add(T::A(1), T::A(10)) }); } diff --git a/tests/run-make/pdb-buildinfo-cl-cmd/main.rs b/tests/run-make/pdb-buildinfo-cl-cmd/main.rs index f79c691f0853..f328e4d9d04c 100644 --- a/tests/run-make/pdb-buildinfo-cl-cmd/main.rs +++ b/tests/run-make/pdb-buildinfo-cl-cmd/main.rs @@ -1,2 +1 @@ -fn main() { -} +fn main() {} diff --git a/tests/run-make/pgo-branch-weights/interesting.rs b/tests/run-make/pgo-branch-weights/interesting.rs index a26d6fd69d14..7066496f4beb 100644 --- a/tests/run-make/pgo-branch-weights/interesting.rs +++ b/tests/run-make/pgo-branch-weights/interesting.rs @@ -1,5 +1,5 @@ -#![crate_name="interesting"] -#![crate_type="rlib"] +#![crate_name = "interesting"] +#![crate_type = "rlib"] extern crate opaque; @@ -22,7 +22,6 @@ pub fn function_called_42_times(c: char) { // This branch is taken 12 times opaque::f1(); } else { - if c == 'b' { // This branch is taken 28 times opaque::f2(); diff --git a/tests/run-make/pgo-branch-weights/opaque.rs b/tests/run-make/pgo-branch-weights/opaque.rs index 72f93c9feab6..39dedf0f7bf5 100644 --- a/tests/run-make/pgo-branch-weights/opaque.rs +++ b/tests/run-make/pgo-branch-weights/opaque.rs @@ -1,5 +1,5 @@ -#![crate_name="opaque"] -#![crate_type="rlib"] +#![crate_name = "opaque"] +#![crate_type = "rlib"] pub fn f1() {} pub fn f2() {} diff --git a/tests/run-make/pgo-indirect-call-promotion/interesting.rs b/tests/run-make/pgo-indirect-call-promotion/interesting.rs index 4fd096d626de..398017f9611b 100644 --- a/tests/run-make/pgo-indirect-call-promotion/interesting.rs +++ b/tests/run-make/pgo-indirect-call-promotion/interesting.rs @@ -1,5 +1,5 @@ -#![crate_name="interesting"] -#![crate_type="rlib"] +#![crate_name = "interesting"] +#![crate_type = "rlib"] extern crate opaque; @@ -15,7 +15,6 @@ pub fn function_called_never() { #[no_mangle] pub fn call_a_bunch_of_functions(fns: &[fn()]) { - // Indirect call promotion transforms the below into something like // // for f in fns { @@ -33,13 +32,11 @@ pub fn call_a_bunch_of_functions(fns: &[fn()]) { } } - pub trait Foo { fn foo(&self); } impl Foo for u32 { - #[no_mangle] fn foo(&self) { opaque::opaque_f2(); @@ -48,7 +45,6 @@ impl Foo for u32 { #[no_mangle] pub fn call_a_bunch_of_trait_methods(trait_objects: &[&dyn Foo]) { - // Same as above, just with vtables in between for x in trait_objects { x.foo(); diff --git a/tests/run-make/pgo-indirect-call-promotion/main.rs b/tests/run-make/pgo-indirect-call-promotion/main.rs index 27181f30710b..604f1f748737 100644 --- a/tests/run-make/pgo-indirect-call-promotion/main.rs +++ b/tests/run-make/pgo-indirect-call-promotion/main.rs @@ -2,9 +2,8 @@ extern crate interesting; fn main() { // function pointer case - let fns: Vec<_> = std::iter::repeat(interesting::function_called_always as fn()) - .take(1000) - .collect(); + let fns: Vec<_> = + std::iter::repeat(interesting::function_called_always as fn()).take(1000).collect(); interesting::call_a_bunch_of_functions(&fns[..]); // Trait object case diff --git a/tests/run-make/pgo-indirect-call-promotion/opaque.rs b/tests/run-make/pgo-indirect-call-promotion/opaque.rs index 9628d711c505..d7b2e810bed1 100644 --- a/tests/run-make/pgo-indirect-call-promotion/opaque.rs +++ b/tests/run-make/pgo-indirect-call-promotion/opaque.rs @@ -1,5 +1,5 @@ -#![crate_name="opaque"] -#![crate_type="rlib"] +#![crate_name = "opaque"] +#![crate_type = "rlib"] #[no_mangle] pub fn opaque_f1() {} diff --git a/tests/run-make/pgo-use/main.rs b/tests/run-make/pgo-use/main.rs index eb9192c87e6f..6150cff4d63a 100644 --- a/tests/run-make/pgo-use/main.rs +++ b/tests/run-make/pgo-use/main.rs @@ -11,7 +11,7 @@ pub fn hot_function(c: u8) { fn main() { let arg = std::env::args().skip(1).next().unwrap(); - for i in 0 .. 1000_000 { + for i in 0..1000_000 { let some_value = arg.as_bytes()[i % arg.len()]; if some_value == b'!' { // This branch is never taken at runtime diff --git a/tests/run-make/pointer-auth-link-with-c/test.rs b/tests/run-make/pointer-auth-link-with-c/test.rs index 615ad0aeb3d0..1a3be80e898b 100644 --- a/tests/run-make/pointer-auth-link-with-c/test.rs +++ b/tests/run-make/pointer-auth-link-with-c/test.rs @@ -4,5 +4,7 @@ extern "C" { } fn main() { - unsafe {foo();} + unsafe { + foo(); + } } diff --git a/tests/run-make/pretty-print-to-file/input.rs b/tests/run-make/pretty-print-to-file/input.rs index aa828155b205..ce23804e4307 100644 --- a/tests/run-make/pretty-print-to-file/input.rs +++ b/tests/run-make/pretty-print-to-file/input.rs @@ -1,5 +1,5 @@ -#[crate_type="lib"] +#[crate_type = "lib"] -pub fn -foo() -> i32 -{ 45 } +pub fn foo() -> i32 { + 45 +} diff --git a/tests/run-make/print-check-cfg/rmake.rs b/tests/run-make/print-check-cfg/rmake.rs index 554884b7d579..a0aa95c8abcf 100644 --- a/tests/run-make/print-check-cfg/rmake.rs +++ b/tests/run-make/print-check-cfg/rmake.rs @@ -8,59 +8,84 @@ use std::ops::Deref; use run_make_support::rustc; -fn main() { - check( - /*args*/ &[], - /*has_any*/ false, - /*has_any_any*/ true, - /*contains*/ &[], - ); - check( - /*args*/ &["--check-cfg=cfg()"], - /*has_any*/ false, - /*has_any_any*/ false, - /*contains*/ &["unix", "miri"], - ); - check( - /*args*/ &["--check-cfg=cfg(any())"], - /*has_any*/ true, - /*has_any_any*/ false, - /*contains*/ &["windows", "test"], - ); - check( - /*args*/ &["--check-cfg=cfg(feature)"], - /*has_any*/ false, - /*has_any_any*/ false, - /*contains*/ &["unix", "miri", "feature"], - ); - check( - /*args*/ &[r#"--check-cfg=cfg(feature, values(none(), "", "test", "lol"))"#], - /*has_any*/ false, - /*has_any_any*/ false, - /*contains*/ &["feature", "feature=\"\"", "feature=\"test\"", "feature=\"lol\""], - ); - check( - /*args*/ &[ - r#"--check-cfg=cfg(feature, values(any()))"#, - r#"--check-cfg=cfg(feature, values("tmp"))"# - ], - /*has_any*/ false, - /*has_any_any*/ false, - /*contains*/ &["unix", "miri", "feature=any()"], - ); - check( - /*args*/ &[ - r#"--check-cfg=cfg(has_foo, has_bar)"#, - r#"--check-cfg=cfg(feature, values("tmp"))"#, - r#"--check-cfg=cfg(feature, values("tmp"))"# - ], - /*has_any*/ false, - /*has_any_any*/ false, - /*contains*/ &["has_foo", "has_bar", "feature=\"tmp\""], - ); +struct CheckCfg { + args: &'static [&'static str], + contains: Contains, } -fn check(args: &[&str], has_any: bool, has_any_any: bool, contains: &[&str]) { +enum Contains { + Some { contains: &'static [&'static str], doesnt_contain: &'static [&'static str] }, + Only(&'static str), +} + +fn main() { + check(CheckCfg { args: &[], contains: Contains::Only("any()=any()") }); + check(CheckCfg { + args: &["--check-cfg=cfg()"], + contains: Contains::Some { + contains: &["unix", "miri"], + doesnt_contain: &["any()", "any()=any()"], + }, + }); + check(CheckCfg { + args: &["--check-cfg=cfg(any())"], + contains: Contains::Some { + contains: &["any()", "unix", r#"target_feature="crt-static""#], + doesnt_contain: &["any()=any()"], + }, + }); + check(CheckCfg { + args: &["--check-cfg=cfg(feature)"], + contains: Contains::Some { + contains: &["unix", "miri", "feature"], + doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="], + }, + }); + check(CheckCfg { + args: &[r#"--check-cfg=cfg(feature, values(none(), "", "test", "lol"))"#], + contains: Contains::Some { + contains: &["feature", "feature=\"\"", "feature=\"test\"", "feature=\"lol\""], + doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="], + }, + }); + check(CheckCfg { + args: &["--check-cfg=cfg(feature, values())"], + contains: Contains::Some { + contains: &["feature="], + doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature"], + }, + }); + check(CheckCfg { + args: &["--check-cfg=cfg(feature, values())", "--check-cfg=cfg(feature, values(none()))"], + contains: Contains::Some { + contains: &["feature"], + doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="], + }, + }); + check(CheckCfg { + args: &[ + r#"--check-cfg=cfg(feature, values(any()))"#, + r#"--check-cfg=cfg(feature, values("tmp"))"#, + ], + contains: Contains::Some { + contains: &["unix", "miri", "feature=any()"], + doesnt_contain: &["any()", "any()=any()", "feature", "feature=", "feature=\"tmp\""], + }, + }); + check(CheckCfg { + args: &[ + r#"--check-cfg=cfg(has_foo, has_bar)"#, + r#"--check-cfg=cfg(feature, values("tmp"))"#, + r#"--check-cfg=cfg(feature, values("tmp"))"#, + ], + contains: Contains::Some { + contains: &["has_foo", "has_bar", "feature=\"tmp\""], + doesnt_contain: &["any()", "any()=any()", "feature"], + }, + }); +} + +fn check(CheckCfg { args, contains }: CheckCfg) { let output = rustc() .input("lib.rs") .arg("-Zunstable-options") @@ -70,18 +95,11 @@ fn check(args: &[&str], has_any: bool, has_any_any: bool, contains: &[&str]) { let stdout = String::from_utf8(output.stdout).unwrap(); - let mut found_any = false; - let mut found_any_any = false; let mut found = HashSet::::new(); - let mut recorded = HashSet::::new(); for l in stdout.lines() { assert!(l == l.trim()); - if l == "any()" { - found_any = true; - } else if l == "any()=any()" { - found_any_any = true; - } else if let Some((left, right)) = l.split_once('=') { + if let Some((left, right)) = l.split_once('=') { if right != "any()" && right != "" { assert!(right.starts_with("\"")); assert!(right.ends_with("\"")); @@ -90,17 +108,37 @@ fn check(args: &[&str], has_any: bool, has_any_any: bool, contains: &[&str]) { } else { assert!(!l.contains("\"")); } - assert!(recorded.insert(l.to_string()), "{}", &l); - if contains.contains(&l) { - assert!(found.insert(l.to_string()), "{}", &l); - } + assert!(found.insert(l.to_string()), "{}", &l); } - let should_found = HashSet::::from_iter(contains.iter().map(|s| s.to_string())); - let diff: Vec<_> = should_found.difference(&found).collect(); - - assert_eq!(found_any, has_any); - assert_eq!(found_any_any, has_any_any); - assert_eq!(found_any_any, recorded.len() == 1); - assert!(diff.is_empty(), "{:?} != {:?} (~ {:?})", &should_found, &found, &diff); + match contains { + Contains::Some { contains, doesnt_contain } => { + { + let should_found = + HashSet::::from_iter(contains.iter().map(|s| s.to_string())); + let diff: Vec<_> = should_found.difference(&found).collect(); + assert!( + diff.is_empty(), + "should found: {:?}, didn't found {:?}", + &should_found, + &diff + ); + } + { + let should_not_find = + HashSet::::from_iter(doesnt_contain.iter().map(|s| s.to_string())); + let diff: Vec<_> = should_not_find.intersection(&found).collect(); + assert!( + diff.is_empty(), + "should not find {:?}, did found {:?}", + &should_not_find, + &diff + ); + } + } + Contains::Only(only) => { + assert!(found.contains(&only.to_string()), "{:?} != {:?}", &only, &found); + assert!(found.len() == 1, "len: {}, instead of 1", found.len()); + } + } } diff --git a/tests/run-make/proc-macro-init-order/b.rs b/tests/run-make/proc-macro-init-order/b.rs index 355d2b165274..067f47c1b7a1 100644 --- a/tests/run-make/proc-macro-init-order/b.rs +++ b/tests/run-make/proc-macro-init-order/b.rs @@ -1,2 +1,3 @@ #![crate_type = "lib"] -#[macro_use] extern crate a; +#[macro_use] +extern crate a; diff --git a/tests/run-make/proc-macro-init-order/c.rs b/tests/run-make/proc-macro-init-order/c.rs index b9c2155728cb..505f8470338e 100644 --- a/tests/run-make/proc-macro-init-order/c.rs +++ b/tests/run-make/proc-macro-init-order/c.rs @@ -1,3 +1,3 @@ #![crate_type = "staticlib"] -extern crate b; extern crate a; +extern crate b; diff --git a/tests/run-make/prune-link-args/empty.rs b/tests/run-make/prune-link-args/empty.rs index 45590d86ba6c..f328e4d9d04c 100644 --- a/tests/run-make/prune-link-args/empty.rs +++ b/tests/run-make/prune-link-args/empty.rs @@ -1 +1 @@ -fn main() { } +fn main() {} diff --git a/tests/run-make/raw-dylib-alt-calling-convention/driver.rs b/tests/run-make/raw-dylib-alt-calling-convention/driver.rs index b7f372c6b2b2..918e013af6ef 100644 --- a/tests/run-make/raw-dylib-alt-calling-convention/driver.rs +++ b/tests/run-make/raw-dylib-alt-calling-convention/driver.rs @@ -2,7 +2,6 @@ extern crate raw_dylib_alt_calling_convention_test; fn main() { raw_dylib_alt_calling_convention_test::library_function( - std::env::args().skip(1).next().map_or( - false, - |s| std::str::FromStr::from_str(&s).unwrap())); + std::env::args().skip(1).next().map_or(false, |s| std::str::FromStr::from_str(&s).unwrap()), + ); } diff --git a/tests/run-make/raw-dylib-c/lib.rs b/tests/run-make/raw-dylib-c/lib.rs index f17125f308c2..ebb08a0ba9e9 100644 --- a/tests/run-make/raw-dylib-c/lib.rs +++ b/tests/run-make/raw-dylib-c/lib.rs @@ -1,16 +1,16 @@ #[link(name = "extern_1.dll", kind = "raw-dylib", modifiers = "+verbatim")] -extern { +extern "C" { fn extern_fn_1(); } #[link(name = "extern_2", kind = "raw-dylib")] -extern { +extern "C" { fn extern_fn_3(); } pub fn library_function() { #[link(name = "extern_1", kind = "raw-dylib")] - extern { + extern "C" { fn extern_fn_2(); fn print_extern_variable(); static mut extern_variable: i32; diff --git a/tests/run-make/raw-dylib-cross-compilation/lib.rs b/tests/run-make/raw-dylib-cross-compilation/lib.rs index 3338ac0a0b50..d3b7fd23ca82 100644 --- a/tests/run-make/raw-dylib-cross-compilation/lib.rs +++ b/tests/run-make/raw-dylib-cross-compilation/lib.rs @@ -8,7 +8,7 @@ trait Sized {} #[link(name = "extern_1", kind = "raw-dylib")] -extern { +extern "C" { fn extern_fn(); } diff --git a/tests/run-make/raw-dylib-custom-dlltool/lib.rs b/tests/run-make/raw-dylib-custom-dlltool/lib.rs index 2f3f497a00de..db1d64505038 100644 --- a/tests/run-make/raw-dylib-custom-dlltool/lib.rs +++ b/tests/run-make/raw-dylib-custom-dlltool/lib.rs @@ -1,5 +1,5 @@ #[link(name = "extern_1", kind = "raw-dylib")] -extern { +extern "C" { fn extern_fn_1(); } diff --git a/tests/run-make/raw-dylib-import-name-type/driver.rs b/tests/run-make/raw-dylib-import-name-type/driver.rs index 6c1c212f187b..b235fef9e308 100644 --- a/tests/run-make/raw-dylib-import-name-type/driver.rs +++ b/tests/run-make/raw-dylib-import-name-type/driver.rs @@ -76,7 +76,7 @@ extern "vectorcall" { } #[link(name = "extern", kind = "raw-dylib")] -extern { +extern "C" { fn print_extern_variable_undecorated(); fn print_extern_variable_noprefix(); fn print_extern_variable_decorated(); diff --git a/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs b/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs index 0c3125be6f59..53f3fcb2f880 100644 --- a/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs +++ b/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs @@ -2,7 +2,7 @@ extern crate raw_dylib_test; extern crate raw_dylib_test_wrapper; #[link(name = "extern_2", kind = "raw-dylib")] -extern { +extern "C" { fn extern_fn_2(); } diff --git a/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs b/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs index 4877cb80aea5..07e289a21d97 100644 --- a/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs +++ b/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs @@ -1,5 +1,5 @@ #[link(name = "extern_1", kind = "raw-dylib")] -extern { +extern "C" { fn extern_fn_1(); fn extern_fn_2(); } diff --git a/tests/run-make/raw-dylib-link-ordinal/lib.rs b/tests/run-make/raw-dylib-link-ordinal/lib.rs index 1bbb45bbc772..69f0a5bca46f 100644 --- a/tests/run-make/raw-dylib-link-ordinal/lib.rs +++ b/tests/run-make/raw-dylib-link-ordinal/lib.rs @@ -1,5 +1,5 @@ #[link(name = "exporter", kind = "raw-dylib")] -extern { +extern "C" { #[link_ordinal(13)] fn imported_function(); #[link_ordinal(5)] diff --git a/tests/run-make/reproducible-build-2/linker.rs b/tests/run-make/reproducible-build-2/linker.rs index 998d1f328596..ec238b2fa562 100644 --- a/tests/run-make/reproducible-build-2/linker.rs +++ b/tests/run-make/reproducible-build-2/linker.rs @@ -1,7 +1,7 @@ use std::env; -use std::path::Path; use std::fs::File; use std::io::{Read, Write}; +use std::path::Path; fn main() { let mut dst = env::current_exe().unwrap(); @@ -19,7 +19,7 @@ fn main() { if !path.is_file() { out.push_str(&arg); out.push_str("\n"); - continue + continue; } let mut contents = Vec::new(); diff --git a/tests/run-make/reproducible-build-2/reproducible-build-aux.rs b/tests/run-make/reproducible-build-2/reproducible-build-aux.rs index 8105b3d2bda3..9708b2d15b42 100644 --- a/tests/run-make/reproducible-build-2/reproducible-build-aux.rs +++ b/tests/run-make/reproducible-build-2/reproducible-build-aux.rs @@ -1,4 +1,4 @@ -#![crate_type="lib"] +#![crate_type = "lib"] pub static STATIC: i32 = 1234; @@ -18,7 +18,7 @@ impl Drop for Struct { pub enum Enum { Variant1, Variant2(u32), - Variant3 { x: u32 } + Variant3 { x: u32 }, } pub struct TupleStruct(pub i8, pub i16, pub i32, pub i64); diff --git a/tests/run-make/reproducible-build-2/reproducible-build.rs b/tests/run-make/reproducible-build-2/reproducible-build.rs index a6c04774c869..849b3d510af8 100644 --- a/tests/run-make/reproducible-build-2/reproducible-build.rs +++ b/tests/run-make/reproducible-build-2/reproducible-build.rs @@ -18,6 +18,8 @@ // - Trait object shims // - Fn Pointer shims +// ignore-tidy-linelength + #![allow(dead_code, warnings)] extern crate reproducible_build_aux; @@ -40,7 +42,7 @@ impl Drop for Struct { pub enum Enum { Variant1, Variant2(u32), - Variant3 { x: u32 } + Variant3 { x: u32 }, } struct TupleStruct(i8, i16, i32, i64); @@ -67,19 +69,14 @@ fn main() { generic_fn::>(); generic_fn::, reproducible_build_aux::Struct>(); - let dropped = Struct { - x: "", - y: 'a', - }; + let dropped = Struct { x: "", y: 'a' }; let _ = Enum::Variant1; let _ = Enum::Variant2(0); let _ = Enum::Variant3 { x: 0 }; let _ = TupleStruct(1, 2, 3, 4); - let closure = |x| { - x + 1i32 - }; + let closure = |x| x + 1i32; fn inner i32>(f: F) -> i32 { f(STATIC) @@ -94,13 +91,13 @@ fn main() { f(0); } - with_fn_once_adapter(|_:i32| { }); + with_fn_once_adapter(|_: i32| {}); reproducible_build_aux::regular_fn(STATIC); reproducible_build_aux::generic_fn::(); reproducible_build_aux::generic_fn::>(); - reproducible_build_aux::generic_fn::, - reproducible_build_aux::Struct>(); + reproducible_build_aux::generic_fn::, reproducible_build_aux::Struct>( + ); let _ = reproducible_build_aux::Enum::Variant1; let _ = reproducible_build_aux::Enum::Variant2(0); diff --git a/tests/run-make/reproducible-build/linker.rs b/tests/run-make/reproducible-build/linker.rs index 3dda6f190e44..ab3b4049cc32 100644 --- a/tests/run-make/reproducible-build/linker.rs +++ b/tests/run-make/reproducible-build/linker.rs @@ -1,7 +1,7 @@ use std::env; -use std::path::Path; use std::fs::File; use std::io::{Read, Write}; +use std::path::Path; fn main() { let mut dst = env::current_exe().unwrap(); @@ -19,7 +19,7 @@ fn main() { if !path.is_file() { out.push_str(&arg); out.push_str("\n"); - continue + continue; } let mut contents = Vec::new(); diff --git a/tests/run-make/reproducible-build/reproducible-build-aux.rs b/tests/run-make/reproducible-build/reproducible-build-aux.rs index 8105b3d2bda3..9708b2d15b42 100644 --- a/tests/run-make/reproducible-build/reproducible-build-aux.rs +++ b/tests/run-make/reproducible-build/reproducible-build-aux.rs @@ -1,4 +1,4 @@ -#![crate_type="lib"] +#![crate_type = "lib"] pub static STATIC: i32 = 1234; @@ -18,7 +18,7 @@ impl Drop for Struct { pub enum Enum { Variant1, Variant2(u32), - Variant3 { x: u32 } + Variant3 { x: u32 }, } pub struct TupleStruct(pub i8, pub i16, pub i32, pub i64); diff --git a/tests/run-make/reproducible-build/reproducible-build.rs b/tests/run-make/reproducible-build/reproducible-build.rs index a6c04774c869..849b3d510af8 100644 --- a/tests/run-make/reproducible-build/reproducible-build.rs +++ b/tests/run-make/reproducible-build/reproducible-build.rs @@ -18,6 +18,8 @@ // - Trait object shims // - Fn Pointer shims +// ignore-tidy-linelength + #![allow(dead_code, warnings)] extern crate reproducible_build_aux; @@ -40,7 +42,7 @@ impl Drop for Struct { pub enum Enum { Variant1, Variant2(u32), - Variant3 { x: u32 } + Variant3 { x: u32 }, } struct TupleStruct(i8, i16, i32, i64); @@ -67,19 +69,14 @@ fn main() { generic_fn::>(); generic_fn::, reproducible_build_aux::Struct>(); - let dropped = Struct { - x: "", - y: 'a', - }; + let dropped = Struct { x: "", y: 'a' }; let _ = Enum::Variant1; let _ = Enum::Variant2(0); let _ = Enum::Variant3 { x: 0 }; let _ = TupleStruct(1, 2, 3, 4); - let closure = |x| { - x + 1i32 - }; + let closure = |x| x + 1i32; fn inner i32>(f: F) -> i32 { f(STATIC) @@ -94,13 +91,13 @@ fn main() { f(0); } - with_fn_once_adapter(|_:i32| { }); + with_fn_once_adapter(|_: i32| {}); reproducible_build_aux::regular_fn(STATIC); reproducible_build_aux::generic_fn::(); reproducible_build_aux::generic_fn::>(); - reproducible_build_aux::generic_fn::, - reproducible_build_aux::Struct>(); + reproducible_build_aux::generic_fn::, reproducible_build_aux::Struct>( + ); let _ = reproducible_build_aux::Enum::Variant1; let _ = reproducible_build_aux::Enum::Variant2(0); diff --git a/tests/run-make/reset-codegen-1/foo.rs b/tests/run-make/reset-codegen-1/foo.rs index 45590d86ba6c..f328e4d9d04c 100644 --- a/tests/run-make/reset-codegen-1/foo.rs +++ b/tests/run-make/reset-codegen-1/foo.rs @@ -1 +1 @@ -fn main() { } +fn main() {} diff --git a/tests/run-make/resolve-rename/bar.rs b/tests/run-make/resolve-rename/bar.rs index 4a09ce355e68..706ff4535202 100644 --- a/tests/run-make/resolve-rename/bar.rs +++ b/tests/run-make/resolve-rename/bar.rs @@ -2,4 +2,6 @@ extern crate foo; -pub fn bar() { foo::foo() } +pub fn bar() { + foo::foo() +} diff --git a/tests/run-make/resolve-rename/baz.rs b/tests/run-make/resolve-rename/baz.rs index 9176073ef97f..74822fb4e1ef 100644 --- a/tests/run-make/resolve-rename/baz.rs +++ b/tests/run-make/resolve-rename/baz.rs @@ -2,4 +2,6 @@ extern crate bar; -pub fn baz() { bar::bar() } +pub fn baz() { + bar::bar() +} diff --git a/tests/run-make/return-non-c-like-enum-from-c/nonclike.rs b/tests/run-make/return-non-c-like-enum-from-c/nonclike.rs index ea22a2a56e09..1cd6360bdd23 100644 --- a/tests/run-make/return-non-c-like-enum-from-c/nonclike.rs +++ b/tests/run-make/return-non-c-like-enum-from-c/nonclike.rs @@ -4,7 +4,7 @@ pub enum TT { BB, } -#[repr(C,u8)] +#[repr(C, u8)] pub enum T { A(u64), B, diff --git a/tests/run-make/return-non-c-like-enum/nonclike.rs b/tests/run-make/return-non-c-like-enum/nonclike.rs index de529cf641ab..32884d8d690b 100644 --- a/tests/run-make/return-non-c-like-enum/nonclike.rs +++ b/tests/run-make/return-non-c-like-enum/nonclike.rs @@ -9,7 +9,7 @@ pub extern "C" fn tt_new(a: u64, b: u64) -> TT { TT::AA(a, b) } -#[repr(C,u8)] +#[repr(C, u8)] pub enum T { A(u64), B, diff --git a/tests/run-make/rlib-chain/m2.rs b/tests/run-make/rlib-chain/m2.rs index eba12fe12188..9430e1d156c0 100644 --- a/tests/run-make/rlib-chain/m2.rs +++ b/tests/run-make/rlib-chain/m2.rs @@ -1,4 +1,6 @@ #![crate_type = "rlib"] extern crate m1; -pub fn m2() { m1::m1() } +pub fn m2() { + m1::m1() +} diff --git a/tests/run-make/rlib-chain/m3.rs b/tests/run-make/rlib-chain/m3.rs index ade191db49c8..b45712e55e16 100644 --- a/tests/run-make/rlib-chain/m3.rs +++ b/tests/run-make/rlib-chain/m3.rs @@ -1,4 +1,6 @@ #![crate_type = "rlib"] extern crate m2; -pub fn m3() { m2::m2() } +pub fn m3() { + m2::m2() +} diff --git a/tests/run-make/rlib-chain/m4.rs b/tests/run-make/rlib-chain/m4.rs index fa8ec6079dea..c732512af9fc 100644 --- a/tests/run-make/rlib-chain/m4.rs +++ b/tests/run-make/rlib-chain/m4.rs @@ -1,3 +1,5 @@ extern crate m3; -fn main() { m3::m3() } +fn main() { + m3::m3() +} diff --git a/tests/run-make/rust-lld-by-default/rmake.rs b/tests/run-make/rust-lld-by-default/rmake.rs index 6a8dae1043e3..8ab16394a915 100644 --- a/tests/run-make/rust-lld-by-default/rmake.rs +++ b/tests/run-make/rust-lld-by-default/rmake.rs @@ -17,8 +17,9 @@ fn main() { .input("main.rs") .run(); assert!( - find_lld_version_in_logs(output), - "the LLD version string should be present in the output logs" + find_lld_version_in_logs(&output), + "the LLD version string should be present in the output logs:\n{}", + std::str::from_utf8(&output.stderr).unwrap() ); // But it can still be disabled by turning the linker feature off. @@ -29,13 +30,14 @@ fn main() { .input("main.rs") .run(); assert!( - !find_lld_version_in_logs(output), - "the LLD version string should not be present in the output logs" + !find_lld_version_in_logs(&output), + "the LLD version string should not be present in the output logs:\n{}", + std::str::from_utf8(&output.stderr).unwrap() ); } -fn find_lld_version_in_logs(output: Output) -> bool { +fn find_lld_version_in_logs(output: &Output) -> bool { let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); let stderr = std::str::from_utf8(&output.stderr).unwrap(); - stderr.lines().any(|line| lld_version_re.is_match(line)) + stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index 9bdb69f47d8e..e6c4a321d000 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -23,8 +23,9 @@ fn main() { .input("lib.rs") .run(); assert!( - find_lld_version_in_logs(output), - "the LLD version string should be present in the output logs" + find_lld_version_in_logs(&output), + "the LLD version string should be present in the output logs:\n{}", + std::str::from_utf8(&output.stderr).unwrap() ); // But it can also be disabled via linker features. @@ -37,13 +38,14 @@ fn main() { .input("lib.rs") .run(); assert!( - !find_lld_version_in_logs(output), - "the LLD version string should not be present in the output logs" + !find_lld_version_in_logs(&output), + "the LLD version string should not be present in the output logs:\n{}", + std::str::from_utf8(&output.stderr).unwrap() ); } -fn find_lld_version_in_logs(output: Output) -> bool { +fn find_lld_version_in_logs(output: &Output) -> bool { let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); let stderr = std::str::from_utf8(&output.stderr).unwrap(); - stderr.lines().any(|line| lld_version_re.is_match(line)) + stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index feeb82e709e1..a74e858045d4 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -21,8 +21,9 @@ fn main() { .input("main.rs") .run(); assert!( - find_lld_version_in_logs(output), - "the LLD version string should be present in the output logs" + find_lld_version_in_logs(&output), + "the LLD version string should be present in the output logs:\n{}", + std::str::from_utf8(&output.stderr).unwrap() ); // It should not be used when we explictly opt-out of lld. @@ -33,8 +34,9 @@ fn main() { .input("main.rs") .run(); assert!( - !find_lld_version_in_logs(output), - "the LLD version string should not be present in the output logs" + !find_lld_version_in_logs(&output), + "the LLD version string should not be present in the output logs:\n{}", + std::str::from_utf8(&output.stderr).unwrap() ); // While we're here, also check that the last linker feature flag "wins" when passed multiple @@ -50,13 +52,14 @@ fn main() { .input("main.rs") .run(); assert!( - find_lld_version_in_logs(output), - "the LLD version string should be present in the output logs" + find_lld_version_in_logs(&output), + "the LLD version string should be present in the output logs:\n{}", + std::str::from_utf8(&output.stderr).unwrap() ); } -fn find_lld_version_in_logs(output: Output) -> bool { +fn find_lld_version_in_logs(output: &Output) -> bool { let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); let stderr = std::str::from_utf8(&output.stderr).unwrap(); - stderr.lines().any(|line| lld_version_re.is_match(line)) + stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } diff --git a/tests/run-make/rustdoc-error-lines/input.rs b/tests/run-make/rustdoc-error-lines/input.rs index b4db182e85f2..1ca2efc0dd59 100644 --- a/tests/run-make/rustdoc-error-lines/input.rs +++ b/tests/run-make/rustdoc-error-lines/input.rs @@ -6,9 +6,7 @@ /// #![feature(bool_to_option)] /// let x: char = 1; /// ``` -pub fn foo() { - -} +pub fn foo() {} /// Add some text around the test... /// diff --git a/tests/run-make/rustdoc-error-lines/rmake.rs b/tests/run-make/rustdoc-error-lines/rmake.rs index 31536c78dd46..db6e28e4feb7 100644 --- a/tests/run-make/rustdoc-error-lines/rmake.rs +++ b/tests/run-make/rustdoc-error-lines/rmake.rs @@ -11,10 +11,10 @@ fn main() { let should_contain = &[ "input.rs - foo (line 5)", "input.rs:7:15", - "input.rs - bar (line 15)", - "input.rs:17:15", - "input.rs - bar (line 24)", - "input.rs:26:15", + "input.rs - bar (line 13)", + "input.rs:15:15", + "input.rs - bar (line 22)", + "input.rs:24:15", ]; for text in should_contain { assert!(output.contains(text), "output doesn't contains {:?}", text); diff --git a/tests/run-make/rustdoc-map-file/foo.rs b/tests/run-make/rustdoc-map-file/foo.rs index e12b9d2292c5..f98543f9b052 100644 --- a/tests/run-make/rustdoc-map-file/foo.rs +++ b/tests/run-make/rustdoc-map-file/foo.rs @@ -1,5 +1,5 @@ -pub use private::Quz; pub use hidden::Bar; +pub use private::Quz; mod private { pub struct Quz; @@ -12,5 +12,5 @@ pub mod hidden { #[macro_export] macro_rules! foo { - () => {} + () => {}; } diff --git a/tests/run-make/rustdoc-scrape-examples-invalid-expr/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-invalid-expr/src/lib.rs index c30c99dec603..ba8ee66fc78b 100644 --- a/tests/run-make/rustdoc-scrape-examples-invalid-expr/src/lib.rs +++ b/tests/run-make/rustdoc-scrape-examples-invalid-expr/src/lib.rs @@ -1 +1,3 @@ -pub const fn f() -> usize { 5 } +pub const fn f() -> usize { + 5 +} diff --git a/tests/run-make/rustdoc-scrape-examples-macros/examples/ex.rs b/tests/run-make/rustdoc-scrape-examples-macros/examples/ex.rs index 4d8c8b30e311..70a9a187f07e 100644 --- a/tests/run-make/rustdoc-scrape-examples-macros/examples/ex.rs +++ b/tests/run-make/rustdoc-scrape-examples-macros/examples/ex.rs @@ -8,20 +8,20 @@ a_proc_macro!(); // no #[an_attr_macro] fn a() { - f(); // no + f(); // no } #[an_attr_macro(with_span)] fn b() { - f(); // yes + f(); // yes } fn c() { - a_rules_macro!(f()); // yes + a_rules_macro!(f()); // yes } fn d() { - a_rules_macro!(()); // no + a_rules_macro!(()); // no } -fn main(){} +fn main() {} diff --git a/tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs index d8658a0f2557..26ab1390a49a 100644 --- a/tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs +++ b/tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs @@ -8,5 +8,7 @@ pub fn f() {} #[macro_export] macro_rules! a_rules_macro { - ($e:expr) => { ($e, foobar::f()); } + ($e:expr) => { + ($e, foobar::f()); + }; } diff --git a/tests/run-make/rustdoc-scrape-examples-test/examples/ex.rs b/tests/run-make/rustdoc-scrape-examples-test/examples/ex.rs index d1a9a74e7825..c37b8dd48853 100644 --- a/tests/run-make/rustdoc-scrape-examples-test/examples/ex.rs +++ b/tests/run-make/rustdoc-scrape-examples-test/examples/ex.rs @@ -2,5 +2,5 @@ fn main() {} #[test] fn a_test() { - foobar::ok(); + foobar::ok(); } diff --git a/tests/run-make/rustdoc-scrape-examples-whitespace/examples/ex.rs b/tests/run-make/rustdoc-scrape-examples-whitespace/examples/ex.rs index 44ff689dfc87..09df782a1367 100644 --- a/tests/run-make/rustdoc-scrape-examples-whitespace/examples/ex.rs +++ b/tests/run-make/rustdoc-scrape-examples-whitespace/examples/ex.rs @@ -1,8 +1,10 @@ struct Foo; impl Foo { - fn bar() { foobar::ok(); } + fn bar() { + foobar::ok(); + } } fn main() { - Foo::bar(); + Foo::bar(); } diff --git a/tests/run-make/share-generics-dylib/linked_leaf.rs b/tests/run-make/share-generics-dylib/linked_leaf.rs index e510dad691c5..200a732d588d 100644 --- a/tests/run-make/share-generics-dylib/linked_leaf.rs +++ b/tests/run-make/share-generics-dylib/linked_leaf.rs @@ -1,11 +1,12 @@ +// Blank line after this one because it must come before `instance_user_{a,b}_rlib`. extern crate instance_user_dylib; + extern crate instance_user_a_rlib; extern crate instance_user_b_rlib; use std::cell::Cell; fn main() { - instance_user_a_rlib::foo(); instance_user_b_rlib::foo(); instance_user_dylib::foo(); diff --git a/tests/run-make/split-debuginfo/main.rs b/tests/run-make/split-debuginfo/main.rs index 21fa16e40a4a..e815672fa819 100644 --- a/tests/run-make/split-debuginfo/main.rs +++ b/tests/run-make/split-debuginfo/main.rs @@ -1,6 +1,6 @@ extern crate bar; -use bar::{Bar, make_bar}; +use bar::{make_bar, Bar}; fn main() { let b = make_bar(3); diff --git a/tests/run-make/stable-symbol-names/stable-symbol-names1.rs b/tests/run-make/stable-symbol-names/stable-symbol-names1.rs index b85a428278cd..ff20d4306dd7 100644 --- a/tests/run-make/stable-symbol-names/stable-symbol-names1.rs +++ b/tests/run-make/stable-symbol-names/stable-symbol-names1.rs @@ -1,31 +1,31 @@ -#![crate_type="rlib"] +#![crate_type = "rlib"] pub trait Foo { - fn generic_method(); + fn generic_method(); } pub struct Bar; impl Foo for Bar { - fn generic_method() {} + fn generic_method() {} } pub fn mono_function() { - Bar::generic_method::(); + Bar::generic_method::(); } pub fn mono_function_lifetime<'a>(x: &'a u64) -> u64 { - *x + *x } pub fn generic_function(t: T) -> T { - t + t } pub fn user() { - generic_function(0u32); - generic_function("abc"); - let x = 2u64; - generic_function(&x); - let _ = mono_function_lifetime(&x); + generic_function(0u32); + generic_function("abc"); + let x = 2u64; + generic_function(&x); + let _ = mono_function_lifetime(&x); } diff --git a/tests/run-make/stable-symbol-names/stable-symbol-names2.rs b/tests/run-make/stable-symbol-names/stable-symbol-names2.rs index 33df9d6c6898..6a50c2a4f573 100644 --- a/tests/run-make/stable-symbol-names/stable-symbol-names2.rs +++ b/tests/run-make/stable-symbol-names/stable-symbol-names2.rs @@ -1,17 +1,17 @@ -#![crate_type="rlib"] +#![crate_type = "rlib"] extern crate stable_symbol_names1; pub fn user() { - stable_symbol_names1::generic_function(1u32); - stable_symbol_names1::generic_function("def"); - let x = 2u64; - stable_symbol_names1::generic_function(&x); - stable_symbol_names1::mono_function(); - stable_symbol_names1::mono_function_lifetime(&0); + stable_symbol_names1::generic_function(1u32); + stable_symbol_names1::generic_function("def"); + let x = 2u64; + stable_symbol_names1::generic_function(&x); + stable_symbol_names1::mono_function(); + stable_symbol_names1::mono_function_lifetime(&0); } pub fn trait_impl_test_function() { - use stable_symbol_names1::*; - Bar::generic_method::(); + use stable_symbol_names1::*; + Bar::generic_method::(); } diff --git a/tests/run-make/static-unwinding/lib.rs b/tests/run-make/static-unwinding/lib.rs index 3fb1117a1105..975de43cfd8d 100644 --- a/tests/run-make/static-unwinding/lib.rs +++ b/tests/run-make/static-unwinding/lib.rs @@ -5,11 +5,16 @@ pub static mut statik: isize = 0; struct A; impl Drop for A { fn drop(&mut self) { - unsafe { statik = 1; } + unsafe { + statik = 1; + } } } -pub fn callback(f: F) where F: FnOnce() { +pub fn callback(f: F) +where + F: FnOnce(), +{ let _a = A; f(); } diff --git a/tests/run-make/static-unwinding/main.rs b/tests/run-make/static-unwinding/main.rs index 0c66ea1aa07f..ceb0a24804c5 100644 --- a/tests/run-make/static-unwinding/main.rs +++ b/tests/run-make/static-unwinding/main.rs @@ -7,15 +7,19 @@ static mut statik: isize = 0; struct A; impl Drop for A { fn drop(&mut self) { - unsafe { statik = 1; } + unsafe { + statik = 1; + } } } fn main() { - thread::spawn(move|| { + thread::spawn(move || { let _a = A; lib::callback(|| panic!()); - }).join().unwrap_err(); + }) + .join() + .unwrap_err(); unsafe { assert_eq!(lib::statik, 1); diff --git a/tests/run-make/suspicious-library/bar.rs b/tests/run-make/suspicious-library/bar.rs index 550c94cd0c60..030693a694f9 100644 --- a/tests/run-make/suspicious-library/bar.rs +++ b/tests/run-make/suspicious-library/bar.rs @@ -1,3 +1,5 @@ extern crate foo; -fn main() { foo::foo() } +fn main() { + foo::foo() +} diff --git a/tests/run-make/symbol-mangling-hashed/a_dylib.rs b/tests/run-make/symbol-mangling-hashed/a_dylib.rs index 8aec8fd82a53..49d65b72cacc 100644 --- a/tests/run-make/symbol-mangling-hashed/a_dylib.rs +++ b/tests/run-make/symbol-mangling-hashed/a_dylib.rs @@ -1,4 +1,4 @@ -#![crate_type="dylib"] +#![crate_type = "dylib"] pub fn hello() { println!("hello dylib"); } diff --git a/tests/run-make/symbol-mangling-hashed/a_rlib.rs b/tests/run-make/symbol-mangling-hashed/a_rlib.rs index 873c86c5d0b4..71e44ccc2007 100644 --- a/tests/run-make/symbol-mangling-hashed/a_rlib.rs +++ b/tests/run-make/symbol-mangling-hashed/a_rlib.rs @@ -1,4 +1,4 @@ -#![crate_type="rlib"] +#![crate_type = "rlib"] pub fn hello() { println!("hello rlib"); diff --git a/tests/run-make/symbol-mangling-hashed/b_bin.rs b/tests/run-make/symbol-mangling-hashed/b_bin.rs index bcc53c37e122..8ee7fecda62a 100644 --- a/tests/run-make/symbol-mangling-hashed/b_bin.rs +++ b/tests/run-make/symbol-mangling-hashed/b_bin.rs @@ -1,5 +1,5 @@ -extern crate a_rlib; extern crate a_dylib; +extern crate a_rlib; extern crate b_dylib; fn main() { diff --git a/tests/run-make/symbol-mangling-hashed/b_dylib.rs b/tests/run-make/symbol-mangling-hashed/b_dylib.rs index c26a04b39ec3..3252c9c75c2a 100644 --- a/tests/run-make/symbol-mangling-hashed/b_dylib.rs +++ b/tests/run-make/symbol-mangling-hashed/b_dylib.rs @@ -1,7 +1,7 @@ -#![crate_type="dylib"] +#![crate_type = "dylib"] -extern crate a_rlib; extern crate a_dylib; +extern crate a_rlib; pub fn hello() { a_rlib::hello(); diff --git a/tests/run-make/symbol-visibility/a_cdylib.rs b/tests/run-make/symbol-visibility/a_cdylib.rs index d4fbff85bfe6..cc034c8a31e5 100644 --- a/tests/run-make/symbol-visibility/a_cdylib.rs +++ b/tests/run-make/symbol-visibility/a_cdylib.rs @@ -1,4 +1,4 @@ -#![crate_type="cdylib"] +#![crate_type = "cdylib"] extern crate an_rlib; diff --git a/tests/run-make/symbol-visibility/a_rust_dylib.rs b/tests/run-make/symbol-visibility/a_rust_dylib.rs index a47df0ab7eed..22c0482343ee 100644 --- a/tests/run-make/symbol-visibility/a_rust_dylib.rs +++ b/tests/run-make/symbol-visibility/a_rust_dylib.rs @@ -1,4 +1,4 @@ -#![crate_type="dylib"] +#![crate_type = "dylib"] extern crate an_rlib; @@ -12,4 +12,6 @@ pub extern "C" fn public_c_function_from_rust_dylib() { } // This should be exported if -Zshare-generics=yes -pub fn public_generic_function_from_rust_dylib(x: T) -> T { x } +pub fn public_generic_function_from_rust_dylib(x: T) -> T { + x +} diff --git a/tests/run-make/symbol-visibility/an_executable.rs b/tests/run-make/symbol-visibility/an_executable.rs index 3f5e125ad193..945873bd9ce1 100644 --- a/tests/run-make/symbol-visibility/an_executable.rs +++ b/tests/run-make/symbol-visibility/an_executable.rs @@ -1,4 +1,4 @@ -#![crate_type="bin"] +#![crate_type = "bin"] extern crate an_rlib; diff --git a/tests/run-make/symbol-visibility/an_rlib.rs b/tests/run-make/symbol-visibility/an_rlib.rs index 3696422b11e9..b291dbe571cd 100644 --- a/tests/run-make/symbol-visibility/an_rlib.rs +++ b/tests/run-make/symbol-visibility/an_rlib.rs @@ -1,4 +1,4 @@ -#![crate_type="rlib"] +#![crate_type = "rlib"] pub fn public_rust_function_from_rlib() {} diff --git a/tests/run-make/symlinked-extern/bar.rs b/tests/run-make/symlinked-extern/bar.rs index cd9c959d5e6a..895582d5f13b 100644 --- a/tests/run-make/symlinked-extern/bar.rs +++ b/tests/run-make/symlinked-extern/bar.rs @@ -2,5 +2,4 @@ extern crate foo; -pub fn bar(_s: foo::S) { -} +pub fn bar(_s: foo::S) {} diff --git a/tests/run-make/symlinked-extern/foo.rs b/tests/run-make/symlinked-extern/foo.rs index c00700b8cf83..4dcf6e135f60 100644 --- a/tests/run-make/symlinked-extern/foo.rs +++ b/tests/run-make/symlinked-extern/foo.rs @@ -2,4 +2,6 @@ pub struct S; -pub fn foo() -> S { S } +pub fn foo() -> S { + S +} diff --git a/tests/run-make/target-cpu-native/foo.rs b/tests/run-make/target-cpu-native/foo.rs index f79c691f0853..f328e4d9d04c 100644 --- a/tests/run-make/target-cpu-native/foo.rs +++ b/tests/run-make/target-cpu-native/foo.rs @@ -1,2 +1 @@ -fn main() { -} +fn main() {} diff --git a/tests/run-make/test-harness/test-ignore-cfg.rs b/tests/run-make/test-harness/test-ignore-cfg.rs index 31ef131f2ad7..c6bd7680bd5c 100644 --- a/tests/run-make/test-harness/test-ignore-cfg.rs +++ b/tests/run-make/test-harness/test-ignore-cfg.rs @@ -1,9 +1,7 @@ #[test] #[cfg_attr(ignorecfg, ignore)] -fn shouldignore() { -} +fn shouldignore() {} #[test] #[cfg_attr(noignorecfg, ignore)] -fn shouldnotignore() { -} +fn shouldnotignore() {} diff --git a/tests/run-make/type-mismatch-same-crate-name/crateA.rs b/tests/run-make/type-mismatch-same-crate-name/crateA.rs index 4871c8c2e9cc..0dccfbb4bed6 100644 --- a/tests/run-make/type-mismatch-same-crate-name/crateA.rs +++ b/tests/run-make/type-mismatch-same-crate-name/crateA.rs @@ -3,7 +3,7 @@ mod foo { } mod bar { - pub trait Bar{} + pub trait Bar {} pub fn bar() -> Box { unimplemented!() @@ -12,5 +12,5 @@ mod bar { // This makes the publicly accessible path // differ from the internal one. +pub use bar::{bar, Bar}; pub use foo::Foo; -pub use bar::{Bar, bar}; diff --git a/tests/run-make/type-mismatch-same-crate-name/crateB.rs b/tests/run-make/type-mismatch-same-crate-name/crateB.rs index 24fcc7cadc10..e946c0ecac76 100644 --- a/tests/run-make/type-mismatch-same-crate-name/crateB.rs +++ b/tests/run-make/type-mismatch-same-crate-name/crateB.rs @@ -1,4 +1,4 @@ extern crate crateA; -pub fn try_foo(x: crateA::Foo){} -pub fn try_bar(x: Box){} +pub fn try_foo(x: crateA::Foo) {} +pub fn try_bar(x: Box) {} diff --git a/tests/run-make/use-suggestions-rust-2018/use-suggestions.rs b/tests/run-make/use-suggestions-rust-2018/use-suggestions.rs index d262d6f9877c..1bb987d0ebdf 100644 --- a/tests/run-make/use-suggestions-rust-2018/use-suggestions.rs +++ b/tests/run-make/use-suggestions-rust-2018/use-suggestions.rs @@ -1,3 +1,3 @@ fn main() { - let x = Baz{}; + let x = Baz {}; } diff --git a/tests/run-make/wasm-custom-section/bar.rs b/tests/run-make/wasm-custom-section/bar.rs index c95f3e1438b7..1e94e99ff086 100644 --- a/tests/run-make/wasm-custom-section/bar.rs +++ b/tests/run-make/wasm-custom-section/bar.rs @@ -10,4 +10,4 @@ pub static A: [u8; 2] = [5, 6]; pub static B: [u8; 2] = [7, 8]; #[no_mangle] -pub extern fn foo() {} +pub extern "C" fn foo() {} diff --git a/tests/run-make/wasm-custom-sections-opt/foo.rs b/tests/run-make/wasm-custom-sections-opt/foo.rs index 9af7728b7f3a..f521dd937a0e 100644 --- a/tests/run-make/wasm-custom-sections-opt/foo.rs +++ b/tests/run-make/wasm-custom-sections-opt/foo.rs @@ -13,7 +13,7 @@ pub mod another { } #[no_mangle] -pub extern fn foo() { +pub extern "C" fn foo() { // This will import `another::foo` through ThinLTO passes, and it better not // also accidentally import the `FOO` custom section into this module as // well diff --git a/tests/run-make/wasm-exceptions-nostd/src/arena_alloc.rs b/tests/run-make/wasm-exceptions-nostd/src/arena_alloc.rs index 572d253309ce..12f1b4d8d12f 100644 --- a/tests/run-make/wasm-exceptions-nostd/src/arena_alloc.rs +++ b/tests/run-make/wasm-exceptions-nostd/src/arena_alloc.rs @@ -14,9 +14,7 @@ pub struct ArenaAllocator { impl ArenaAllocator { pub const fn new() -> Self { - Self { - arena: UnsafeCell::new(Arena::new()), - } + Self { arena: UnsafeCell::new(Arena::new()) } } } @@ -42,10 +40,7 @@ struct Arena { impl Arena { pub const fn new() -> Self { - Self { - buf: [0x55; ARENA_SIZE], - allocated: 0, - } + Self { buf: [0x55; ARENA_SIZE], allocated: 0 } } pub unsafe fn alloc(&mut self, layout: Layout) -> *mut u8 { diff --git a/tests/run-make/wasm-exceptions-nostd/src/lib.rs b/tests/run-make/wasm-exceptions-nostd/src/lib.rs index 9d336510469c..3ea8797d3a6d 100644 --- a/tests/run-make/wasm-exceptions-nostd/src/lib.rs +++ b/tests/run-make/wasm-exceptions-nostd/src/lib.rs @@ -1,9 +1,7 @@ #![no_std] #![crate_type = "cdylib"] - // Allow a few unstable features because we create a panic // runtime for native wasm exceptions from scratch - #![feature(core_intrinsics)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] @@ -39,20 +37,24 @@ pub extern "C" fn start() -> usize { let data = 0x1234usize as *mut u8; // Something to recognize unsafe { - core::intrinsics::catch_unwind(|data: *mut u8| { - let _log_on_drop = LogOnDrop; + core::intrinsics::catch_unwind( + |data: *mut u8| { + let _log_on_drop = LogOnDrop; - logging::log_str(&alloc::format!("`r#try` called with ptr {:?}", data)); - let x = [12]; - let _ = x[4]; // should panic + logging::log_str(&alloc::format!("`r#try` called with ptr {:?}", data)); + let x = [12]; + let _ = x[4]; // should panic - logging::log_str("This line should not be visible! :("); - }, data, |data, exception| { - let exception = *Box::from_raw(exception as *mut String); - logging::log_str("Caught something!"); - logging::log_str(&alloc::format!(" data : {:?}", data)); - logging::log_str(&alloc::format!(" exception: {:?}", exception)); - }); + logging::log_str("This line should not be visible! :("); + }, + data, + |data, exception| { + let exception = *Box::from_raw(exception as *mut String); + logging::log_str("Caught something!"); + logging::log_str(&alloc::format!(" data : {:?}", data)); + logging::log_str(&alloc::format!(" exception: {:?}", exception)); + }, + ); } logging::log_str("This program terminates correctly."); diff --git a/tests/run-make/wasm-exceptions-nostd/src/panicking.rs b/tests/run-make/wasm-exceptions-nostd/src/panicking.rs index 4a8923fd43db..52a32f3cd303 100644 --- a/tests/run-make/wasm-exceptions-nostd/src/panicking.rs +++ b/tests/run-make/wasm-exceptions-nostd/src/panicking.rs @@ -17,10 +17,7 @@ fn panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { use alloc::boxed::Box; use alloc::string::ToString; - let msg = info - .message() - .map(|msg| msg.to_string()) - .unwrap_or("(no message)".to_string()); + let msg = info.message().map(|msg| msg.to_string()).unwrap_or("(no message)".to_string()); let exception = Box::new(msg.to_string()); unsafe { let exception_raw = Box::into_raw(exception); diff --git a/tests/run-make/wasm-export-all-symbols/bar.rs b/tests/run-make/wasm-export-all-symbols/bar.rs index ac9c20a57e5a..039291f902e5 100644 --- a/tests/run-make/wasm-export-all-symbols/bar.rs +++ b/tests/run-make/wasm-export-all-symbols/bar.rs @@ -1,7 +1,7 @@ #![crate_type = "rlib"] #[no_mangle] -pub extern fn foo() {} +pub extern "C" fn foo() {} #[no_mangle] pub static FOO: u64 = 42; diff --git a/tests/run-make/wasm-symbols-not-exported/bar.rs b/tests/run-make/wasm-symbols-not-exported/bar.rs index 6ffbd3ec6900..dd4d14416e70 100644 --- a/tests/run-make/wasm-symbols-not-exported/bar.rs +++ b/tests/run-make/wasm-symbols-not-exported/bar.rs @@ -11,15 +11,14 @@ unsafe impl GlobalAlloc for B { 1 as *mut u8 } - unsafe fn dealloc(&self, ptr: *mut u8, x: Layout) { - } + unsafe fn dealloc(&self, ptr: *mut u8, x: Layout) {} } #[global_allocator] static A: B = B; #[no_mangle] -pub extern fn foo(a: u32) -> u32 { +pub extern "C" fn foo(a: u32) -> u32 { assert_eq!(a, 3); a * 2 } diff --git a/tests/run-make/wasm-symbols-not-exported/foo.rs b/tests/run-make/wasm-symbols-not-exported/foo.rs index d46baee01b96..f85103f35354 100644 --- a/tests/run-make/wasm-symbols-not-exported/foo.rs +++ b/tests/run-make/wasm-symbols-not-exported/foo.rs @@ -1,7 +1,7 @@ #![crate_type = "cdylib"] #[no_mangle] -pub extern fn foo() { +pub extern "C" fn foo() { println!("foo"); panic!("test"); } diff --git a/tests/run-make/wasm-symbols-not-imported/foo.rs b/tests/run-make/wasm-symbols-not-imported/foo.rs index b25bdc9800d1..6af8d50a2ace 100644 --- a/tests/run-make/wasm-symbols-not-imported/foo.rs +++ b/tests/run-make/wasm-symbols-not-imported/foo.rs @@ -4,7 +4,7 @@ use core::panic::PanicInfo; #[no_mangle] -pub extern fn foo() { +pub extern "C" fn foo() { panic!() } diff --git a/tests/run-make/windows-spawn/spawn.rs b/tests/run-make/windows-spawn/spawn.rs index a9e86d1577e5..4afbaf876cd0 100644 --- a/tests/run-make/windows-spawn/spawn.rs +++ b/tests/run-make/windows-spawn/spawn.rs @@ -6,5 +6,5 @@ fn main() { assert_eq!( Command::new("hopefullydoesntexist").arg("bar").spawn().unwrap_err().kind(), ErrorKind::NotFound - ) + ); } diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/build.rs b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/build.rs index 3a7aa1be868c..f1fb58039485 100644 --- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/build.rs +++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/enclave/build.rs @@ -1,17 +1,9 @@ fn main() { - cc::Build::new() - .file("foo.c") - .compile("foo_c"); + cc::Build::new().file("foo.c").compile("foo_c"); - cc::Build::new() - .file("foo_asm.s") - .compile("foo_asm"); + cc::Build::new().file("foo_asm.s").compile("foo_asm"); - cc::Build::new() - .cpp(true) - .cpp_set_stdlib(None) - .file("foo_cxx.cpp") - .compile("foo_cxx"); + cc::Build::new().cpp(true).cpp_set_stdlib(None).file("foo_cxx.cpp").compile("foo_cxx"); // When the cmake crate detects the clang compiler, it passes the // "--target" argument to the linker which subsequently fails. The @@ -20,11 +12,11 @@ fn main() { // `CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY` can be used // https://cmake.org/cmake/help/v3.5/module/CMakeForceCompiler.html let dst = cmake::Config::new("libcmake_foo") - .build_target("cmake_foo") - .define("CMAKE_C_COMPILER_FORCED", "1") - .define("CMAKE_CXX_COMPILER_FORCED", "1") - .define("CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY", "1") - .build(); + .build_target("cmake_foo") + .define("CMAKE_C_COMPILER_FORCED", "1") + .define("CMAKE_CXX_COMPILER_FORCED", "1") + .define("CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY", "1") + .build(); println!("cargo:rustc-link-search=native={}/build/", dst.display()); println!("cargo:rustc-link-lib=static=cmake_foo"); } diff --git a/tests/run-pass-valgrind/cast-enum-with-dtor.rs b/tests/run-pass-valgrind/cast-enum-with-dtor.rs index f7ef92df8fbe..a57dc3734789 100644 --- a/tests/run-pass-valgrind/cast-enum-with-dtor.rs +++ b/tests/run-pass-valgrind/cast-enum-with-dtor.rs @@ -2,14 +2,14 @@ // check dtor calling order when casting enums. +use std::mem; use std::sync::atomic; use std::sync::atomic::Ordering; -use std::mem; enum E { A = 0, B = 1, - C = 2 + C = 2, } static FLAG: atomic::AtomicUsize = atomic::AtomicUsize::new(0); @@ -19,7 +19,7 @@ impl Drop for E { // avoid dtor loop unsafe { mem::forget(mem::replace(self, E::B)) }; - FLAG.store(FLAG.load(Ordering::SeqCst)+1, Ordering::SeqCst); + FLAG.store(FLAG.load(Ordering::SeqCst) + 1, Ordering::SeqCst); } } diff --git a/tests/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/tests/run-pass-valgrind/cleanup-auto-borrow-obj.rs index dfc094abeb9b..e4ce80b33059 100644 --- a/tests/run-pass-valgrind/cleanup-auto-borrow-obj.rs +++ b/tests/run-pass-valgrind/cleanup-auto-borrow-obj.rs @@ -7,12 +7,15 @@ static mut DROP_RAN: bool = false; struct Foo; impl Drop for Foo { fn drop(&mut self) { - unsafe { DROP_RAN = true; } + unsafe { + DROP_RAN = true; + } } } - -trait Trait { fn dummy(&self) { } } +trait Trait { + fn dummy(&self) {} +} impl Trait for Foo {} pub fn main() { diff --git a/tests/run-pass-valgrind/coerce-match-calls.rs b/tests/run-pass-valgrind/coerce-match-calls.rs index f6c7151ff103..8c7375610dd7 100644 --- a/tests/run-pass-valgrind/coerce-match-calls.rs +++ b/tests/run-pass-valgrind/coerce-match-calls.rs @@ -7,9 +7,15 @@ use std::boxed::Box; pub fn main() { let _: Box<[isize]> = if true { Box::new([1, 2, 3]) } else { Box::new([1]) }; - let _: Box<[isize]> = match true { true => Box::new([1, 2, 3]), false => Box::new([1]) }; + let _: Box<[isize]> = match true { + true => Box::new([1, 2, 3]), + false => Box::new([1]), + }; // Check we don't get over-keen at propagating coercions in the case of casts. let x = if true { 42 } else { 42u8 } as u16; - let x = match true { true => 42, false => 42u8 } as u16; + let x = match true { + true => 42, + false => 42u8, + } as u16; } diff --git a/tests/run-pass-valgrind/coerce-match.rs b/tests/run-pass-valgrind/coerce-match.rs index 3f33264c5a80..95f16a8cc896 100644 --- a/tests/run-pass-valgrind/coerce-match.rs +++ b/tests/run-pass-valgrind/coerce-match.rs @@ -12,11 +12,20 @@ pub fn main() { }; let _: Box<[isize]> = match true { - true => { let b: Box<_> = Box::new([1, 2, 3]); b } - false => { let b: Box<_> = Box::new([1]); b } + true => { + let b: Box<_> = Box::new([1, 2, 3]); + b + } + false => { + let b: Box<_> = Box::new([1]); + b + } }; // Check we don't get over-keen at propagating coercions in the case of casts. let x = if true { 42 } else { 42u8 } as u16; - let x = match true { true => 42, false => 42u8 } as u16; + let x = match true { + true => 42, + false => 42u8, + } as u16; } diff --git a/tests/run-pass-valgrind/down-with-thread-dtors.rs b/tests/run-pass-valgrind/down-with-thread-dtors.rs index 15aeac98c667..0d3745bba5ba 100644 --- a/tests/run-pass-valgrind/down-with-thread-dtors.rs +++ b/tests/run-pass-valgrind/down-with-thread-dtors.rs @@ -27,13 +27,17 @@ impl Drop for Bar { impl Drop for Baz { fn drop(&mut self) { - unsafe { HIT = true; } + unsafe { + HIT = true; + } } } fn main() { std::thread::spawn(|| { FOO.with(|_| {}); - }).join().unwrap(); + }) + .join() + .unwrap(); assert!(unsafe { HIT }); } diff --git a/tests/run-pass-valgrind/dst-dtor-1.rs b/tests/run-pass-valgrind/dst-dtor-1.rs index 5b8433f61456..47065151a037 100644 --- a/tests/run-pass-valgrind/dst-dtor-1.rs +++ b/tests/run-pass-valgrind/dst-dtor-1.rs @@ -3,15 +3,19 @@ static mut DROP_RAN: bool = false; struct Foo; impl Drop for Foo { fn drop(&mut self) { - unsafe { DROP_RAN = true; } + unsafe { + DROP_RAN = true; + } } } -trait Trait { fn dummy(&self) { } } +trait Trait { + fn dummy(&self) {} +} impl Trait for Foo {} struct Fat { - f: T + f: T, } pub fn main() { diff --git a/tests/run-pass-valgrind/dst-dtor-2.rs b/tests/run-pass-valgrind/dst-dtor-2.rs index 991fe00950bb..d8abebfb4473 100644 --- a/tests/run-pass-valgrind/dst-dtor-2.rs +++ b/tests/run-pass-valgrind/dst-dtor-2.rs @@ -3,12 +3,14 @@ static mut DROP_RAN: isize = 0; struct Foo; impl Drop for Foo { fn drop(&mut self) { - unsafe { DROP_RAN += 1; } + unsafe { + DROP_RAN += 1; + } } } struct Fat { - f: T + f: T, } pub fn main() { diff --git a/tests/run-pass-valgrind/dst-dtor-3.rs b/tests/run-pass-valgrind/dst-dtor-3.rs index f0c2dda5ab05..09adaca21c71 100644 --- a/tests/run-pass-valgrind/dst-dtor-3.rs +++ b/tests/run-pass-valgrind/dst-dtor-3.rs @@ -5,11 +5,15 @@ static mut DROP_RAN: bool = false; struct Foo; impl Drop for Foo { fn drop(&mut self) { - unsafe { DROP_RAN = true; } + unsafe { + DROP_RAN = true; + } } } -trait Trait { fn dummy(&self) { } } +trait Trait { + fn dummy(&self) {} +} impl Trait for Foo {} pub fn main() { diff --git a/tests/run-pass-valgrind/dst-dtor-4.rs b/tests/run-pass-valgrind/dst-dtor-4.rs index ad6d46f7c088..a66ac8e3cfca 100644 --- a/tests/run-pass-valgrind/dst-dtor-4.rs +++ b/tests/run-pass-valgrind/dst-dtor-4.rs @@ -5,7 +5,9 @@ static mut DROP_RAN: isize = 0; struct Foo; impl Drop for Foo { fn drop(&mut self) { - unsafe { DROP_RAN += 1; } + unsafe { + DROP_RAN += 1; + } } } diff --git a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs b/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs index ece4dea9aaf6..5d3f558a63a9 100644 --- a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs +++ b/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs @@ -43,7 +43,6 @@ impl FnOnce<()> for D { } } - fn main() { let x = *(Box::new(A) as Box>); assert_eq!(x.call_once(()), format!("hello")); diff --git a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs b/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs index 94df2b0b83f0..9b6648f2e27a 100644 --- a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs +++ b/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs @@ -51,7 +51,6 @@ impl FnOnce<(String, Box)> for D { } } - fn main() { let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str()); let x = *(Box::new(A) as Box), Output = String>>); @@ -61,10 +60,10 @@ fn main() { assert_eq!(x.call_once((s1, s2)), format!("42")); let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str()); let x = *(Box::new(C(format!("jumping fox"))) - as Box), Output = String>>); + as Box), Output = String>>); assert_eq!(x.call_once((s1, s2)), format!("jumping fox")); let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str()); let x = *(Box::new(D(Box::new(format!("lazy dog")))) - as Box), Output = String>>); + as Box), Output = String>>); assert_eq!(x.call_once((s1, s2)), format!("lazy dog")); } diff --git a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects.rs b/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects.rs index 3d67101e734c..3f6b6d262b5d 100644 --- a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects.rs +++ b/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects.rs @@ -36,7 +36,6 @@ impl Foo for D { } } - fn main() { let x = *(Box::new(A) as Box); assert_eq!(x.foo(), format!("hello")); diff --git a/tests/rustdoc-js/assoc-type-backtrack.rs b/tests/rustdoc-js/assoc-type-backtrack.rs index c3cdd78c6e1c..2dfede9dc383 100644 --- a/tests/rustdoc-js/assoc-type-backtrack.rs +++ b/tests/rustdoc-js/assoc-type-backtrack.rs @@ -5,22 +5,27 @@ pub trait MyTrait2 { pub trait MyTrait { type Item; fn next(&mut self) -> Option; - fn fold(self, init: B, f: F) -> B where + fn fold(self, init: B, f: F) -> B + where Self: Sized, - F: MyTrait2<(B, Self::Item), Output=B>; + F: MyTrait2<(B, Self::Item), Output = B>; } pub struct Cloned(I); -impl<'a, T, I> MyTrait for Cloned where +impl<'a, T, I> MyTrait for Cloned +where T: 'a + Clone, - I: MyTrait + I: MyTrait, { type Item = T; - fn next(&mut self) -> Option { loop {} } - fn fold(self, init: B, f: F) -> B where + fn next(&mut self) -> Option { + loop {} + } + fn fold(self, init: B, f: F) -> B + where Self: Sized, - F: MyTrait2<(B, Self::Item), Output=B> + F: MyTrait2<(B, Self::Item), Output = B>, { loop {} } @@ -32,7 +37,7 @@ pub trait MyFuture { pub trait MyIntoFuture { type Output; - type Fut: MyFuture; + type Fut: MyFuture; fn into_future(self) -> Self::Fut; fn into_future_2(self, other: Self) -> Self::Fut; } diff --git a/tests/rustdoc-js/assoc-type-loop.rs b/tests/rustdoc-js/assoc-type-loop.rs index f123c83f50fd..09efe8c7be5c 100644 --- a/tests/rustdoc-js/assoc-type-loop.rs +++ b/tests/rustdoc-js/assoc-type-loop.rs @@ -1,9 +1,9 @@ -#![crate_name="foo"] +#![crate_name = "foo"] // reduced from sqlx 0.7.3 use std::future::Future; -use std::pin::Pin; use std::ops::{Deref, DerefMut}; +use std::pin::Pin; pub enum Error {} pub trait Acquire<'c> { type Database: Database; @@ -16,7 +16,7 @@ pub trait Connection { type Database: Database; type Options: ConnectionOptions; fn begin( - &mut self + &mut self, ) -> Pin, Error>> + Send + '_>> where Self: Sized; @@ -28,7 +28,8 @@ pub struct Transaction<'c, DB: Database> { _db: &'c DB, } impl<'t, 'c, DB: Database> Acquire<'t> for &'t mut Transaction<'c, DB> - where ::Connection: Send +where + ::Connection: Send, { type Database = DB; type Connection = &'t mut ::Connection; diff --git a/tests/rustdoc-js/auxiliary/interner.rs b/tests/rustdoc-js/auxiliary/interner.rs index c95029be9f0f..e4e4ff6276d6 100644 --- a/tests/rustdoc-js/auxiliary/interner.rs +++ b/tests/rustdoc-js/auxiliary/interner.rs @@ -77,17 +77,14 @@ pub trait Interner: Sized { type ClosureKind: Copy + Debug + Hash + Eq; // Required method - fn mk_canonical_var_infos( - self, - infos: &[CanonicalVarInfo] - ) -> Self::CanonicalVars; + fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo]) -> Self::CanonicalVars; } pub trait DebugWithInfcx: Debug { // Required method fn fmt>( this: WithInfcx<'_, Infcx, &Self>, - f: &mut Formatter<'_> + f: &mut Formatter<'_>, ) -> std::fmt::Result; } @@ -130,11 +127,7 @@ pub struct TypeFlags; pub trait Ty> { // Required method - fn new_anon_bound( - interner: I, - debruijn: DebruijnIndex, - var: BoundVar - ) -> Self; + fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self; } pub trait PlaceholderLike { @@ -152,12 +145,7 @@ pub struct BoundVar; pub struct ConstKind(std::marker::PhantomData); pub trait Const> { // Required method - fn new_anon_bound( - interner: I, - debruijn: DebruijnIndex, - var: BoundVar, - ty: I::Ty - ) -> Self; + fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar, ty: I::Ty) -> Self; } pub trait ConstTy { @@ -170,25 +158,28 @@ pub struct DebruijnIndex; pub struct RegionKind(std::marker::PhantomData); pub trait Region> { // Required method - fn new_anon_bound( - interner: I, - debruijn: DebruijnIndex, - var: BoundVar - ) -> Self; + fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self; } pub trait TypeVisitor: Sized { type Result: VisitorResult = (); // Provided methods - fn visit_binder>( - &mut self, - t: &I::Binder - ) -> Self::Result { unimplemented!() } - fn visit_ty(&mut self, t: I::Ty) -> Self::Result { unimplemented!() } - fn visit_region(&mut self, _r: I::Region) -> Self::Result { unimplemented!() } - fn visit_const(&mut self, c: I::Const) -> Self::Result { unimplemented!() } - fn visit_predicate(&mut self, p: I::Predicate) -> Self::Result { unimplemented!() } + fn visit_binder>(&mut self, t: &I::Binder) -> Self::Result { + unimplemented!() + } + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { + unimplemented!() + } + fn visit_region(&mut self, _r: I::Region) -> Self::Result { + unimplemented!() + } + fn visit_const(&mut self, c: I::Const) -> Self::Result { + unimplemented!() + } + fn visit_predicate(&mut self, p: I::Predicate) -> Self::Result { + unimplemented!() + } } pub trait VisitorResult { @@ -206,7 +197,9 @@ impl VisitorResult for () { fn output() -> Self {} fn from_residual(_: Self::Residual) -> Self {} fn from_branch(_: ControlFlow) -> Self {} - fn branch(self) -> ControlFlow { ControlFlow::Continue(()) } + fn branch(self) -> ControlFlow { + ControlFlow::Continue(()) + } } pub struct WithInfcx<'a, Infcx: InferCtxtLike, T> { @@ -221,24 +214,18 @@ pub trait InferCtxtLike { fn interner(&self) -> Self::Interner; fn universe_of_ty(&self, ty: TyVid) -> Option; fn root_ty_var(&self, vid: TyVid) -> TyVid; - fn probe_ty_var( - &self, - vid: TyVid - ) -> Option<::Ty>; + fn probe_ty_var(&self, vid: TyVid) -> Option<::Ty>; fn universe_of_lt( &self, - lt: ::InferRegion + lt: ::InferRegion, ) -> Option; fn opportunistic_resolve_lt_var( &self, - vid: ::InferRegion + vid: ::InferRegion, ) -> Option<::Region>; fn universe_of_ct(&self, ct: ConstVid) -> Option; fn root_ct_var(&self, vid: ConstVid) -> ConstVid; - fn probe_ct_var( - &self, - vid: ConstVid - ) -> Option<::Const>; + fn probe_ct_var(&self, vid: ConstVid) -> Option<::Const>; } pub struct TyVid; diff --git a/tests/rustdoc-js/doc-alias.rs b/tests/rustdoc-js/doc-alias.rs index 750b7b757bc3..453b55c956c7 100644 --- a/tests/rustdoc-js/doc-alias.rs +++ b/tests/rustdoc-js/doc-alias.rs @@ -16,7 +16,9 @@ impl Trait for Struct { const AssociatedConst: i32 = 12; #[doc(alias = "ImplTraitFunction")] - fn function() -> Self::Target { 0 } + fn function() -> Self::Target { + 0 + } } #[doc(alias = "EnumItem")] @@ -71,5 +73,5 @@ impl Union { #[doc(alias = "MacroItem")] #[macro_export] macro_rules! Macro { - () => {} + () => {}; } diff --git a/tests/rustdoc-js/enum-variant-not-type.rs b/tests/rustdoc-js/enum-variant-not-type.rs index 421bddf62894..f0facd63cfcd 100644 --- a/tests/rustdoc-js/enum-variant-not-type.rs +++ b/tests/rustdoc-js/enum-variant-not-type.rs @@ -5,10 +5,14 @@ pub trait MyTrait { fn not_appearing(&self) -> Option<&Self::T>; } -pub fn my_fn(t: X) -> X { t } +pub fn my_fn(t: X) -> X { + t +} pub trait AutoCorrectConfounder { type InsertUnnecessarilyLongTypeNameHere; - fn assoc_type_acts_like_generic(&self, x: &Self::InsertUnnecessarilyLongTypeNameHere) - -> Option<&Self::InsertUnnecessarilyLongTypeNameHere>; + fn assoc_type_acts_like_generic( + &self, + x: &Self::InsertUnnecessarilyLongTypeNameHere, + ) -> Option<&Self::InsertUnnecessarilyLongTypeNameHere>; } diff --git a/tests/rustdoc-js/foreign-type-path.rs b/tests/rustdoc-js/foreign-type-path.rs index 83400104ea77..f9228c7b9ac3 100644 --- a/tests/rustdoc-js/foreign-type-path.rs +++ b/tests/rustdoc-js/foreign-type-path.rs @@ -2,12 +2,11 @@ pub mod aaaaaaa { - extern { + extern "C" { pub type MyForeignType; } impl MyForeignType { pub fn my_method() {} } - } diff --git a/tests/rustdoc-js/full-path-function.rs b/tests/rustdoc-js/full-path-function.rs index 8dcc3f2b69d8..a1a9220654d0 100644 --- a/tests/rustdoc-js/full-path-function.rs +++ b/tests/rustdoc-js/full-path-function.rs @@ -2,16 +2,26 @@ pub mod sac { pub struct Sac; impl Sac { - pub fn len(&self) -> usize { 0 } + pub fn len(&self) -> usize { + 0 + } } } pub mod b { pub struct Sac; impl Sac { - pub fn len(&self) -> usize { 0 } - pub fn bar(&self, w: u32) -> usize { 0 } - pub fn bar2(&self, w: u32) -> u32 { 0 } - pub fn string(w: String) -> u32 { 0 } + pub fn len(&self) -> usize { + 0 + } + pub fn bar(&self, w: u32) -> usize { + 0 + } + pub fn bar2(&self, w: u32) -> u32 { + 0 + } + pub fn string(w: String) -> u32 { + 0 + } } } diff --git a/tests/rustdoc-js/gat.rs b/tests/rustdoc-js/gat.rs index b4861cc683ff..7a2b5551114c 100644 --- a/tests/rustdoc-js/gat.rs +++ b/tests/rustdoc-js/gat.rs @@ -2,7 +2,15 @@ pub trait Foo { type Assoc; } -pub fn sample = u8>>(_: X) -> u32 { loop {} } -pub fn synergy(_: impl Foo = u8>) -> ! { loop {} } -pub fn consider(_: impl Foo = u32>) -> bool { loop {} } -pub fn integrate(_: impl Foo = T>) -> T { loop {} } +pub fn sample = u8>>(_: X) -> u32 { + loop {} +} +pub fn synergy(_: impl Foo = u8>) -> ! { + loop {} +} +pub fn consider(_: impl Foo = u32>) -> bool { + loop {} +} +pub fn integrate(_: impl Foo = T>) -> T { + loop {} +} diff --git a/tests/rustdoc-js/generics-impl.rs b/tests/rustdoc-js/generics-impl.rs index 696218021d5a..27d44fdd7e92 100644 --- a/tests/rustdoc-js/generics-impl.rs +++ b/tests/rustdoc-js/generics-impl.rs @@ -1,4 +1,4 @@ -use std::io::{Result as IoResult, Read}; +use std::io::{Read, Result as IoResult}; pub struct Aaaaaaa; @@ -29,7 +29,10 @@ impl Ddddddd { pub fn ggggggg(self) -> u64 { 1 } - pub fn hhhhhhh() -> Self where T: Default { + pub fn hhhhhhh() -> Self + where + T: Default, + { Ddddddd(T::default()) } } diff --git a/tests/rustdoc-js/generics-trait.rs b/tests/rustdoc-js/generics-trait.rs index 20db117ccd5c..58c86361e419 100644 --- a/tests/rustdoc-js/generics-trait.rs +++ b/tests/rustdoc-js/generics-trait.rs @@ -1,8 +1,16 @@ pub trait SomeTrait {} pub trait OtherThingxxxxxxxx {} -pub fn alef() -> Result { loop {} } -pub fn bet() -> Result { loop {} } +pub fn alef() -> Result { + loop {} +} +pub fn bet() -> Result { + loop {} +} -pub fn alpha(_param: Result) { loop {} } -pub fn beta(_param: Result) { loop {} } +pub fn alpha(_param: Result) { + loop {} +} +pub fn beta(_param: Result) { + loop {} +} diff --git a/tests/rustdoc-js/generics.rs b/tests/rustdoc-js/generics.rs index 055c51c7ec57..c3ca13666141 100644 --- a/tests/rustdoc-js/generics.rs +++ b/tests/rustdoc-js/generics.rs @@ -3,26 +3,41 @@ pub struct Q; pub struct R(T); // returns test -pub fn alef() -> R

{ loop {} } -pub fn bet() -> R { loop {} } +pub fn alef() -> R

{ + loop {} +} +pub fn bet() -> R { + loop {} +} // in_args test -pub fn alpha(_x: R

) { loop {} } -pub fn beta(_x: R) { loop {} } +pub fn alpha(_x: R

) { + loop {} +} +pub fn beta(_x: R) { + loop {} +} // test case with multiple appearances of the same type -pub struct ExtraCreditStructMulti { t: T, u: U } +pub struct ExtraCreditStructMulti { + t: T, + u: U, +} pub struct ExtraCreditInnerMulti {} pub fn extracreditlabhomework( - _param: ExtraCreditStructMulti -) { loop {} } -pub fn redherringmatchforextracredit( - _param: ExtraCreditStructMulti -) { loop {} } + _param: ExtraCreditStructMulti, +) { + loop {} +} +pub fn redherringmatchforextracredit(_param: ExtraCreditStructMulti) { + loop {} +} pub trait TraitCat {} pub trait TraitDog {} pub fn gamma(t: T) {} -pub fn super_soup(s: Result) -> Result { s } +pub fn super_soup(s: Result) -> Result { + s +} diff --git a/tests/rustdoc-js/hof.rs b/tests/rustdoc-js/hof.rs index 4d2c6e331cac..e4d550250e8a 100644 --- a/tests/rustdoc-js/hof.rs +++ b/tests/rustdoc-js/hof.rs @@ -4,9 +4,9 @@ pub struct First(T); pub struct Second(T); pub struct Third(T); -pub fn fn_ptr(_: fn (First) -> !, _: bool) {} -pub fn fn_once(_: impl FnOnce (Second) -> !, _: u8) {} -pub fn fn_mut(_: impl FnMut (Third) -> !, _: i8) {} -pub fn fn_(_: impl Fn (u32) -> !, _: char) {} +pub fn fn_ptr(_: fn(First) -> !, _: bool) {} +pub fn fn_once(_: impl FnOnce(Second) -> !, _: u8) {} +pub fn fn_mut(_: impl FnMut(Third) -> !, _: i8) {} +pub fn fn_(_: impl Fn(u32) -> !, _: char) {} pub fn multiple(_: impl Fn(&'static str, &'static str) -> i8) {} diff --git a/tests/rustdoc-js/macro-search.rs b/tests/rustdoc-js/macro-search.rs index dc397490cf58..7fa9cbc4ab23 100644 --- a/tests/rustdoc-js/macro-search.rs +++ b/tests/rustdoc-js/macro-search.rs @@ -1,10 +1,10 @@ #[macro_export] macro_rules! abracadabra { - () => {} + () => {}; } #[macro_export] macro_rules! abracadabra_b { - () => {} + () => {}; } pub fn abracadabra() {} pub fn abracadabra_c() {} diff --git a/tests/rustdoc-js/never-search.rs b/tests/rustdoc-js/never-search.rs index 299b4660dae9..800f9ead8b35 100644 --- a/tests/rustdoc-js/never-search.rs +++ b/tests/rustdoc-js/never-search.rs @@ -3,11 +3,27 @@ #[allow(nonstandard_style)] pub struct never; -pub fn loops() -> ! { loop {} } -pub fn returns() -> never { never } +pub fn loops() -> ! { + loop {} +} +pub fn returns() -> never { + never +} -pub fn impossible(x: !) { match x {} } -pub fn uninteresting(x: never) { match x { never => {} } } +pub fn impossible(x: !) { + match x {} +} +pub fn uninteresting(x: never) { + match x { + never => {} + } +} -pub fn box_impossible(x: Box) { match *x {} } -pub fn box_uninteresting(x: Box) { match *x { never => {} } } +pub fn box_impossible(x: Box) { + match *x {} +} +pub fn box_uninteresting(x: Box) { + match *x { + never => {} + } +} diff --git a/tests/rustdoc-js/path-maxeditdistance.rs b/tests/rustdoc-js/path-maxeditdistance.rs index 3861280d59bf..88af4f487741 100644 --- a/tests/rustdoc-js/path-maxeditdistance.rs +++ b/tests/rustdoc-js/path-maxeditdistance.rs @@ -1,3 +1,3 @@ -#![crate_name="abracadabra"] +#![crate_name = "abracadabra"] pub struct HocusPocusPrestidigitation; diff --git a/tests/rustdoc-js/prototype.rs b/tests/rustdoc-js/prototype.rs index 5f6d73cc1962..77553561238c 100644 --- a/tests/rustdoc-js/prototype.rs +++ b/tests/rustdoc-js/prototype.rs @@ -1,4 +1,4 @@ // The alias needed to be there to reproduce the bug // that used to be here. -#[doc(alias="other_alias")] +#[doc(alias = "other_alias")] pub fn something_else() {} diff --git a/tests/rustdoc-js/reexport-dedup-macro.rs b/tests/rustdoc-js/reexport-dedup-macro.rs index 3d18da3951c7..f70b9c3d7338 100644 --- a/tests/rustdoc-js/reexport-dedup-macro.rs +++ b/tests/rustdoc-js/reexport-dedup-macro.rs @@ -1,5 +1,5 @@ //@ aux-crate: macro_in_module=macro-in-module.rs -#![crate_name="foo"] +#![crate_name = "foo"] extern crate macro_in_module; // Test case based on the relationship between alloc and std. diff --git a/tests/rustdoc-js/reexport-dedup-method.rs b/tests/rustdoc-js/reexport-dedup-method.rs index 5dbd66e9c8ed..c00df094d7ac 100644 --- a/tests/rustdoc-js/reexport-dedup-method.rs +++ b/tests/rustdoc-js/reexport-dedup-method.rs @@ -1,5 +1,5 @@ // This test enforces that the (renamed) reexports are present in the search results. -#![crate_name="foo"] +#![crate_name = "foo"] pub mod fmt { pub struct Subscriber; @@ -14,5 +14,5 @@ mod foo { } } -pub use foo::AnotherOne; pub use fmt::Subscriber; +pub use foo::AnotherOne; diff --git a/tests/rustdoc-js/reexport-dedup.rs b/tests/rustdoc-js/reexport-dedup.rs index 40aea9633036..83c23d5c3664 100644 --- a/tests/rustdoc-js/reexport-dedup.rs +++ b/tests/rustdoc-js/reexport-dedup.rs @@ -1,5 +1,5 @@ // This test enforces that the (renamed) reexports are present in the search results. -#![crate_name="foo"] +#![crate_name = "foo"] pub mod fmt { pub struct Subscriber; @@ -8,5 +8,5 @@ mod foo { pub struct AnotherOne; } -pub use foo::AnotherOne; pub use fmt::Subscriber; +pub use foo::AnotherOne; diff --git a/tests/rustdoc-js/reexport.rs b/tests/rustdoc-js/reexport.rs index d51b7fb369c2..0b3718cd9a3e 100644 --- a/tests/rustdoc-js/reexport.rs +++ b/tests/rustdoc-js/reexport.rs @@ -9,5 +9,5 @@ mod foo { pub struct AnotherOne; } -pub use foo::AnotherOne; pub use fmt::Subscriber as FmtSubscriber; +pub use foo::AnotherOne; diff --git a/tests/rustdoc-js/reference.rs b/tests/rustdoc-js/reference.rs index 3a0a23c65d5b..93b2a6df8e6c 100644 --- a/tests/rustdoc-js/reference.rs +++ b/tests/rustdoc-js/reference.rs @@ -7,13 +7,17 @@ pub fn pinky(input: &usize, manage: usize) { pub struct Thumb; impl Thumb { - pub fn up(&self, finger: Thumb) { unimplemented!() } + pub fn up(&self, finger: Thumb) { + unimplemented!() + } } pub enum Index {} impl Index { - pub fn point(self, data: &Index) { unimplemented!() } + pub fn point(self, data: &Index) { + unimplemented!() + } } pub union Ring { @@ -22,11 +26,15 @@ pub union Ring { } impl Ring { - pub fn wear(&mut self, extra: &Ring) { unimplemented!() } + pub fn wear(&mut self, extra: &Ring) { + unimplemented!() + } } extern "C" { pub type Middle; } -pub fn show(left: &&mut Middle, right: &mut &Middle) { unimplemented!() } +pub fn show(left: &&mut Middle, right: &mut &Middle) { + unimplemented!() +} diff --git a/tests/rustdoc-js/slice-array.rs b/tests/rustdoc-js/slice-array.rs index 15ac4294f3d7..e4e34a26fa25 100644 --- a/tests/rustdoc-js/slice-array.rs +++ b/tests/rustdoc-js/slice-array.rs @@ -3,12 +3,20 @@ pub struct Q; pub struct R(T); // returns test -pub fn alef() -> &'static [R

] { loop {} } -pub fn bet() -> R<[Q; 32]> { loop {} } +pub fn alef() -> &'static [R

` (where P is one of the previous types except `Self`) -ERROR rustc_hir_typeck::method::confirm Foo was a subtype of &Foo but now is not? + ERROR rustc_hir_typeck::method::confirm Foo was a subtype of &Foo but now is not? error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/simd/repr_packed.rs b/tests/ui/simd/repr_packed.rs index 411bba3454eb..1ba15bda98dd 100644 --- a/tests/ui/simd/repr_packed.rs +++ b/tests/ui/simd/repr_packed.rs @@ -6,9 +6,6 @@ #[repr(simd, packed)] struct Simd([T; N]); -#[repr(simd)] -struct FullSimd([T; N]); - fn check_size_align() { use std::mem; assert_eq!(mem::size_of::>(), mem::size_of::<[T; N]>()); @@ -39,21 +36,15 @@ fn main() { check_ty::(); unsafe { - // powers-of-two have no padding and work as usual + // powers-of-two have no padding and have the same layout as #[repr(simd)] let x: Simd = simd_add(Simd::([0., 1., 2., 3.]), Simd::([2., 2., 2., 2.])); assert_eq!(std::mem::transmute::<_, [f64; 4]>(x), [2., 3., 4., 5.]); - // non-powers-of-two have padding and need to be expanded to full vectors - fn load(v: Simd) -> FullSimd { - unsafe { - let mut tmp = core::mem::MaybeUninit::>::uninit(); - std::ptr::copy_nonoverlapping(&v as *const _, tmp.as_mut_ptr().cast(), 1); - tmp.assume_init() - } - } - let x: FullSimd = - simd_add(load(Simd::([0., 1., 2.])), load(Simd::([2., 2., 2.]))); - assert_eq!(x.0, [2., 3., 4.]); + // non-powers-of-two should have padding (which is removed by #[repr(packed)]), + // but the intrinsic handles it + let x: Simd = simd_add(Simd::([0., 1., 2.]), Simd::([2., 2., 2.])); + let arr: [f64; 3] = x.0; + assert_eq!(arr, [2., 3., 4.]); } } diff --git a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.rs b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.rs new file mode 100644 index 000000000000..59a015da84eb --- /dev/null +++ b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.rs @@ -0,0 +1,19 @@ +#![feature(specialization)] +#![allow(incomplete_features)] + +trait Trait { + type Type; +} + +impl Trait for i32 { + default type Type = i32; +} + +struct Wrapper::Type> {} +//~^ ERROR `::Type` is forbidden as the type of a const generic parameter + +impl Wrapper {} +//~^ ERROR the constant `C` is not of type `::Type` +//~^^ ERROR mismatched types + +fn main() {} diff --git a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr new file mode 100644 index 000000000000..b4c14c2294e5 --- /dev/null +++ b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr @@ -0,0 +1,36 @@ +error: `::Type` is forbidden as the type of a const generic parameter + --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:12:25 + | +LL | struct Wrapper::Type> {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: the constant `C` is not of type `::Type` + --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:15:22 + | +LL | impl Wrapper {} + | ^^^^^^^^^^ expected associated type, found `usize` + | + = help: consider constraining the associated type `::Type` to `usize` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +note: required by a bound in `Wrapper` + --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:12:16 + | +LL | struct Wrapper::Type> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Wrapper` + +error[E0308]: mismatched types + --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:15:30 + | +LL | impl Wrapper {} + | ^ expected associated type, found `usize` + | + = note: expected associated type `::Type` + found type `usize` + = help: consider constraining the associated type `::Type` to `usize` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs index 4d1cd4332fee..f89a463bc580 100644 --- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs @@ -7,8 +7,7 @@ struct S; impl Copy for S {} //~^ ERROR: mismatched types -//~| ERROR: the trait bound `S: Clone` is not satisfied -//~| ERROR: the constant `N` is not of type `usize` impl Copy for S {} +//~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>` fn main() {} diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr index 716a47879482..1dac58e1f694 100644 --- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr @@ -1,29 +1,11 @@ -error[E0277]: the trait bound `S: Clone` is not satisfied - --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29 +error[E0119]: conflicting implementations of trait `Copy` for type `S<_>` + --> $DIR/bad-const-wf-doesnt-specialize.rs:10:1 | LL | impl Copy for S {} - | ^^^^ the trait `Clone` is not implemented for `S` - | - = help: the trait `Clone` is implemented for `S` -note: required by a bound in `Copy` - --> $SRC_DIR/core/src/marker.rs:LL:COL -help: consider annotating `S` with `#[derive(Clone)]` - | -LL + #[derive(Clone)] -LL | struct S; - | - -error: the constant `N` is not of type `usize` - --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29 - | -LL | impl Copy for S {} - | ^^^^ expected `usize`, found `i32` - | -note: required by a bound in `S` - --> $DIR/bad-const-wf-doesnt-specialize.rs:6:10 - | -LL | struct S; - | ^^^^^^^^^^^^^^ required by this bound in `S` + | -------------------------------- first implementation here +LL | +LL | impl Copy for S {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>` error[E0308]: mismatched types --> $DIR/bad-const-wf-doesnt-specialize.rs:8:31 @@ -31,7 +13,7 @@ error[E0308]: mismatched types LL | impl Copy for S {} | ^ expected `usize`, found `i32` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0119, E0308. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.next.stderr b/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.next.stderr new file mode 100644 index 000000000000..17918a77821d --- /dev/null +++ b/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.next.stderr @@ -0,0 +1,12 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/source-impl-requires-constraining-predicates-ambig.rs:14:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.rs b/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.rs new file mode 100644 index 000000000000..977493c885b2 --- /dev/null +++ b/tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.rs @@ -0,0 +1,29 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass +//@[current] known-bug: unknown +//@[current] failure-status: 101 +//@[current] dont-check-compiler-stderr + +// Tests that rebasing from the concrete impl to the default impl also processes the +// `[u32; 0]: IntoIterator` predicate to constrain the `?U` impl arg. +// This test also makes sure that we don't do anything weird when rebasing the args +// is ambiguous. + +#![feature(specialization)] +//[next]~^ WARN the feature `specialization` is incomplete + +trait Spec { + type Assoc; +} + +default impl Spec for T where T: IntoIterator { + type Assoc = U; +} + +impl Spec for [T; 0] {} + +fn main() { + let x: <[_; 0] as Spec>::Assoc = 1; +} diff --git a/tests/ui/specialization/source-impl-requires-constraining-predicates.current.stderr b/tests/ui/specialization/source-impl-requires-constraining-predicates.current.stderr new file mode 100644 index 000000000000..3442e5b5ca61 --- /dev/null +++ b/tests/ui/specialization/source-impl-requires-constraining-predicates.current.stderr @@ -0,0 +1,12 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/source-impl-requires-constraining-predicates.rs:9:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/specialization/source-impl-requires-constraining-predicates.next.stderr b/tests/ui/specialization/source-impl-requires-constraining-predicates.next.stderr new file mode 100644 index 000000000000..3442e5b5ca61 --- /dev/null +++ b/tests/ui/specialization/source-impl-requires-constraining-predicates.next.stderr @@ -0,0 +1,12 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/source-impl-requires-constraining-predicates.rs:9:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/specialization/source-impl-requires-constraining-predicates.rs b/tests/ui/specialization/source-impl-requires-constraining-predicates.rs new file mode 100644 index 000000000000..532fc3676406 --- /dev/null +++ b/tests/ui/specialization/source-impl-requires-constraining-predicates.rs @@ -0,0 +1,24 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Tests that rebasing from the concrete impl to the default impl also processes the +// `[u32; 0]: IntoIterator` predicate to constrain the `?U` impl arg. + +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete + +trait Spec { + type Assoc; +} + +default impl Spec for T where T: IntoIterator { + type Assoc = U; +} + +impl Spec for [T; 0] {} + +fn main() { + let x: <[u32; 0] as Spec>::Assoc = 1; +} diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr b/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr index 78d77a78e0ee..e9498a003179 100644 --- a/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr +++ b/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr @@ -7,13 +7,6 @@ LL | impl Overlap for u32 { LL | impl Overlap for ::Id { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` -error[E0282]: type annotations needed - --> $DIR/specialization-default-items-drop-coherence.rs:18:23 - | -LL | default type Id = T; - | ^ cannot infer type for associated type `::Id` +error: aborting due to 1 previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0119, E0282. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.rs b/tests/ui/specialization/specialization-default-items-drop-coherence.rs index fad041f2ee10..6dc012776391 100644 --- a/tests/ui/specialization/specialization-default-items-drop-coherence.rs +++ b/tests/ui/specialization/specialization-default-items-drop-coherence.rs @@ -15,7 +15,7 @@ trait Default { } impl Default for T { - default type Id = T; //[next]~ ERROR type annotations needed + default type Id = T; } trait Overlap { diff --git a/tests/ui/specialization/specialization-overlap-projection.next.stderr b/tests/ui/specialization/specialization-overlap-projection.next.stderr index ab040193fa4c..5b17696162ed 100644 --- a/tests/ui/specialization/specialization-overlap-projection.next.stderr +++ b/tests/ui/specialization/specialization-overlap-projection.next.stderr @@ -9,7 +9,7 @@ LL | #![feature(specialization)] = note: `#[warn(incomplete_features)]` on by default error[E0119]: conflicting implementations of trait `Foo` for type `u32` - --> $DIR/specialization-overlap-projection.rs:28:1 + --> $DIR/specialization-overlap-projection.rs:25:1 | LL | impl Foo for u32 {} | ---------------- first implementation here @@ -17,7 +17,7 @@ LL | impl Foo for ::Output {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` error[E0119]: conflicting implementations of trait `Foo` for type `u32` - --> $DIR/specialization-overlap-projection.rs:30:1 + --> $DIR/specialization-overlap-projection.rs:27:1 | LL | impl Foo for u32 {} | ---------------- first implementation here @@ -25,25 +25,6 @@ LL | impl Foo for u32 {} LL | impl Foo for ::Output {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` -error[E0282]: type annotations needed - --> $DIR/specialization-overlap-projection.rs:17:27 - | -LL | default type Output = bool; - | ^^^^ cannot infer type for associated type `::Output` +error: aborting due to 2 previous errors; 1 warning emitted -error[E0282]: type annotations needed - --> $DIR/specialization-overlap-projection.rs:21:35 - | -LL | impl Assoc for u8 { type Output = u8; } - | ^^ cannot infer type for associated type `::Output` - -error[E0282]: type annotations needed - --> $DIR/specialization-overlap-projection.rs:23:36 - | -LL | impl Assoc for u16 { type Output = u16; } - | ^^^ cannot infer type for associated type `::Output` - -error: aborting due to 5 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0119, E0282. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/specialization-overlap-projection.rs b/tests/ui/specialization/specialization-overlap-projection.rs index 78e75f623c4b..16dccf82dcb9 100644 --- a/tests/ui/specialization/specialization-overlap-projection.rs +++ b/tests/ui/specialization/specialization-overlap-projection.rs @@ -15,13 +15,10 @@ trait Assoc { impl Assoc for T { default type Output = bool; - //[next]~^ ERROR type annotations needed } impl Assoc for u8 { type Output = u8; } -//[next]~^ ERROR type annotations needed impl Assoc for u16 { type Output = u16; } -//[next]~^ ERROR type annotations needed trait Foo {} impl Foo for u32 {} diff --git a/tests/ui/suggestions/deref-path-method.stderr b/tests/ui/suggestions/deref-path-method.stderr index bfcc2307fd7f..b27d9aef0661 100644 --- a/tests/ui/suggestions/deref-path-method.stderr +++ b/tests/ui/suggestions/deref-path-method.stderr @@ -9,7 +9,7 @@ note: if you're trying to build a new `Vec<_, _>` consider using one of the foll Vec::::with_capacity Vec::::try_with_capacity Vec::::from_raw_parts - and 6 others + and 4 others --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL help: the function `contains` is implemented on `[_]` | diff --git a/tests/ui/suggestions/issue-109291.stderr b/tests/ui/suggestions/issue-109291.stderr index a173bbbb4900..d4a9351af3a8 100644 --- a/tests/ui/suggestions/issue-109291.stderr +++ b/tests/ui/suggestions/issue-109291.stderr @@ -8,7 +8,6 @@ note: if you're trying to build a new `Backtrace` consider using one of the foll Backtrace::capture Backtrace::force_capture Backtrace::disabled - Backtrace::create --> $SRC_DIR/std/src/backtrace.rs:LL:COL help: there is an associated function `force_capture` with a similar name | diff --git a/tests/ui/suggestions/issue-85347.rs b/tests/ui/suggestions/issue-85347.rs index 95e76e76cfa8..5d1a902af304 100644 --- a/tests/ui/suggestions/issue-85347.rs +++ b/tests/ui/suggestions/issue-85347.rs @@ -3,12 +3,12 @@ trait Foo { type Bar<'a>: Deref::Bar>; //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied //~| HELP add missing - //~| ERROR associated type bindings are not allowed here - //~| HELP consider removing this type binding + //~| ERROR associated item constraints are not allowed here + //~| HELP consider removing this associated item binding //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied //~| HELP add missing - //~| ERROR associated type bindings are not allowed here - //~| HELP consider removing this type binding + //~| ERROR associated item constraints are not allowed here + //~| HELP consider removing this associated item binding } fn main() {} diff --git a/tests/ui/suggestions/issue-85347.stderr b/tests/ui/suggestions/issue-85347.stderr index de0aa09ce49c..b3616041c4cd 100644 --- a/tests/ui/suggestions/issue-85347.stderr +++ b/tests/ui/suggestions/issue-85347.stderr @@ -14,13 +14,13 @@ help: add missing lifetime argument LL | type Bar<'a>: Deref::Bar<'a, Target = Self>>; | +++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-85347.rs:3:46 | LL | type Bar<'a>: Deref::Bar>; - | ^^^^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | type Bar<'a>: Deref::Bar>; | ~~~~~~~~~~~~~~~ @@ -42,14 +42,14 @@ help: add missing lifetime argument LL | type Bar<'a>: Deref::Bar<'a, Target = Self>>; | +++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-85347.rs:3:46 | LL | type Bar<'a>: Deref::Bar>; - | ^^^^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^^^^ associated item constraint not allowed here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider removing this type binding +help: consider removing this associated item binding | LL | type Bar<'a>: Deref::Bar>; | ~~~~~~~~~~~~~~~ diff --git a/tests/ui/suggestions/missing-lifetime-specifier.rs b/tests/ui/suggestions/missing-lifetime-specifier.rs index cd7fa0c1d856..dd437fc0c0b8 100644 --- a/tests/ui/suggestions/missing-lifetime-specifier.rs +++ b/tests/ui/suggestions/missing-lifetime-specifier.rs @@ -1,6 +1,11 @@ -// different number of duplicated diagnostics on different targets -//@ only-x86_64 -//@ only-linux +// The specific errors produced depend the thread-local implementation. +// Run only on platforms with "fast" TLS. +//@ ignore-windows FIXME(#84933) +//@ ignore-wasm globals are used instead of thread locals +//@ ignore-emscripten globals are used instead of thread locals +//@ ignore-android does not use #[thread_local] +//@ ignore-nto does not use #[thread_local] +// Different number of duplicated diagnostics on different targets //@ compile-flags: -Zdeduplicate-diagnostics=yes #![allow(bare_trait_objects)] @@ -21,23 +26,19 @@ trait Tar<'t, 'k, I> {} thread_local! { static a: RefCell>>> = RefCell::new(HashMap::new()); - //~^ ERROR missing lifetime specifiers - //~| ERROR missing lifetime specifiers + //~^ ERROR missing lifetime specifiers } thread_local! { static b: RefCell>>> = RefCell::new(HashMap::new()); - //~^ ERROR missing lifetime specifiers - //~| ERROR missing lifetime specifiers + //~^ ERROR missing lifetime specifiers } thread_local! { static c: RefCell>>>> = RefCell::new(HashMap::new()); //~^ ERROR missing lifetime specifiers - //~| ERROR missing lifetime specifiers } thread_local! { static d: RefCell>>>> = RefCell::new(HashMap::new()); //~^ ERROR missing lifetime specifiers - //~| ERROR missing lifetime specifiers } thread_local! { @@ -47,8 +48,7 @@ thread_local! { thread_local! { static f: RefCell>>>> = RefCell::new(HashMap::new()); //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR missing lifetime - //~| ERROR missing lifetime + //~| ERROR missing lifetime specifier } fn main() {} diff --git a/tests/ui/suggestions/missing-lifetime-specifier.stderr b/tests/ui/suggestions/missing-lifetime-specifier.stderr index 2b85cfde7b64..e0b6bb872b55 100644 --- a/tests/ui/suggestions/missing-lifetime-specifier.stderr +++ b/tests/ui/suggestions/missing-lifetime-specifier.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:23:44 + --> $DIR/missing-lifetime-specifier.rs:28:44 | LL | static a: RefCell>>> = RefCell::new(HashMap::new()); | ^^^ expected 2 lifetime parameters @@ -11,20 +11,7 @@ LL | static a: RefCell>>>> = RefC | ++++++++++++++++++ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:23:44 - | -LL | / thread_local! { -LL | | static a: RefCell>>> = RefCell::new(HashMap::new()); - | | ^^^ expected 2 lifetime parameters -LL | | -LL | | -LL | | } - | |_- - | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from - -error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:28:44 + --> $DIR/missing-lifetime-specifier.rs:32:44 | LL | static b: RefCell>>> = RefCell::new(HashMap::new()); | ^^^^ expected 2 lifetime parameters @@ -38,22 +25,7 @@ LL | static b: RefCell>> | +++++++ ++++++++++++++++++ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:28:44 - | -LL | / thread_local! { -LL | | static b: RefCell>>> = RefCell::new(HashMap::new()); - | | ^^^^ expected 2 lifetime parameters - | | | - | | expected named lifetime parameter -LL | | -LL | | -LL | | } - | |_- - | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 4 lifetimes it is borrowed from - -error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:33:47 + --> $DIR/missing-lifetime-specifier.rs:36:47 | LL | static c: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected 2 lifetime parameters @@ -65,20 +37,7 @@ LL | static c: RefCell>>>> = | +++++++++++++++++ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:33:47 - | -LL | / thread_local! { -LL | | static c: RefCell>>>> = RefCell::new(HashMap::new()); - | | ^ expected 2 lifetime parameters -LL | | -LL | | -LL | | } - | |_- - | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from - -error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:38:44 + --> $DIR/missing-lifetime-specifier.rs:40:44 | LL | static d: RefCell>>>> = RefCell::new(HashMap::new()); | ^ ^ expected 2 lifetime parameters @@ -91,23 +50,8 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're LL | static d: RefCell>>>> = RefCell::new(HashMap::new()); | +++++++ +++++++++++++++++ -error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:38:44 - | -LL | / thread_local! { -LL | | static d: RefCell>>>> = RefCell::new(HashMap::new()); - | | ^ ^ expected 2 lifetime parameters - | | | - | | expected named lifetime parameter -LL | | -LL | | -LL | | } - | |_- - | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 4 lifetimes it is borrowed from - error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-specifier.rs:48:44 + --> $DIR/missing-lifetime-specifier.rs:49:44 | LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected named lifetime parameter @@ -118,22 +62,8 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); | +++++++ -error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-specifier.rs:48:44 - | -LL | / thread_local! { -LL | | static f: RefCell>>>> = RefCell::new(HashMap::new()); - | | ^ expected named lifetime parameter -LL | | -LL | | -LL | | -LL | | } - | |_- - | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from - error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/missing-lifetime-specifier.rs:44:44 + --> $DIR/missing-lifetime-specifier.rs:45:44 | LL | static e: RefCell>>>> = RefCell::new(HashMap::new()); | ^^^ ------- supplied 1 lifetime argument @@ -141,7 +71,7 @@ LL | static e: RefCell>>>> = RefCell: | expected 2 lifetime arguments | note: union defined here, with 2 lifetime parameters: `'t`, `'k` - --> $DIR/missing-lifetime-specifier.rs:16:11 + --> $DIR/missing-lifetime-specifier.rs:21:11 | LL | pub union Qux<'t, 'k, I> { | ^^^ -- -- @@ -151,7 +81,7 @@ LL | static e: RefCell>>>> = | +++++++++ error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/missing-lifetime-specifier.rs:48:45 + --> $DIR/missing-lifetime-specifier.rs:49:45 | LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); | ^^^ ------- supplied 1 lifetime argument @@ -159,7 +89,7 @@ LL | static f: RefCell>>>> = RefCell | expected 2 lifetime arguments | note: trait defined here, with 2 lifetime parameters: `'t`, `'k` - --> $DIR/missing-lifetime-specifier.rs:20:7 + --> $DIR/missing-lifetime-specifier.rs:25:7 | LL | trait Tar<'t, 'k, I> {} | ^^^ -- -- @@ -168,7 +98,7 @@ help: add missing lifetime argument LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); | +++++++++ -error: aborting due to 12 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0106, E0107. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/suggestions/silenced-binding-typo.stderr b/tests/ui/suggestions/silenced-binding-typo.stderr index c362d00c713a..a1e8b9e30d4b 100644 --- a/tests/ui/suggestions/silenced-binding-typo.stderr +++ b/tests/ui/suggestions/silenced-binding-typo.stderr @@ -1,10 +1,12 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/silenced-binding-typo.rs:4:14 | +LL | let _x = 42; + | -- `_x` defined here LL | let _y = x; | ^ | -help: a local variable with a similar name exists, consider renaming `_x` into `x` +help: the leading underscore in `_x` marks it as unused, consider renaming it to `x` | LL | let x = 42; | ~ diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs index c98eec4af01c..99f943d71e9e 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs +++ b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs @@ -8,5 +8,5 @@ fn main() { //~| HELP you might have meant to write a path instead of an associated type bound //~| ERROR struct takes at least 1 generic argument but 0 generic arguments were supplied //~| HELP add missing generic argument - //~| ERROR associated type bindings are not allowed here + //~| ERROR associated item constraints are not allowed here } diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr index 834c141ec3e1..56b6a69a283f 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr +++ b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr @@ -20,11 +20,11 @@ help: add missing generic argument LL | let _: Vec = A::B; | ++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/type-ascription-instead-of-path-in-type.rs:6:16 | LL | let _: Vec = A::B; - | ^^^ associated type not allowed here + | ^^^ associated item constraint not allowed here error: aborting due to 3 previous errors diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs index cab484a120c3..445ea2de610f 100644 --- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs +++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs @@ -14,14 +14,12 @@ impl Trait for i32 { // Should not not trigger suggestion here... impl Trait for () {} //~^ ERROR trait takes 1 generic argument but 2 generic arguments were supplied -//~| ERROR `S` is not constrained //... but should do so in all of the below cases except the last one fn func>(t: T) -> impl Trait<(), i32> { //~^ ERROR trait takes 1 generic argument but 2 generic arguments were supplied //~| ERROR trait takes 1 generic argument but 2 generic arguments were supplied //~| ERROR trait takes 1 generic argument but 2 generic arguments were supplied -//~| ERROR type annotations needed 3 } diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr index 99e81a9039e7..06e2fa5d4d1f 100644 --- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr +++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr @@ -16,14 +16,8 @@ note: trait defined here, with 1 generic parameter: `T` LL | pub trait Trait { | ^^^^^ - -error[E0207]: the type parameter `S` is not constrained by the impl trait, self type, or predicates - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:15:9 - | -LL | impl Trait for () {} - | ^ unconstrained type parameter - error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:12 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:12 | LL | fn func>(t: T) -> impl Trait<(), i32> { | ^^^^^ expected 1 generic argument @@ -39,7 +33,7 @@ LL | fn func>(t: T) -> impl Trait<(), i32> { | +++++++ error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:46 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:46 | LL | fn func>(t: T) -> impl Trait<(), i32> { | ^^^^^ expected 1 generic argument @@ -55,7 +49,7 @@ LL | fn func>(t: T) -> impl Trait<(), Assoc = i32> { | +++++++ error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:46 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:46 | LL | fn func>(t: T) -> impl Trait<(), i32> { | ^^^^^ expected 1 generic argument @@ -71,14 +65,8 @@ help: replace the generic bound with the associated type LL | fn func>(t: T) -> impl Trait<(), Assoc = i32> { | +++++++ -error[E0282]: type annotations needed - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:41 - | -LL | fn func>(t: T) -> impl Trait<(), i32> { - | ^^^^^^^^^^^^^^^^^^^ cannot infer type - error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:28:18 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:18 | LL | struct Struct> { | ^^^^^ expected 1 generic argument @@ -94,7 +82,7 @@ LL | struct Struct> { | +++++++ error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:33:23 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:31:23 | LL | trait AnotherTrait> {} | ^^^^^ expected 1 generic argument @@ -110,7 +98,7 @@ LL | trait AnotherTrait> {} | +++++++ error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:36:9 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:34:9 | LL | impl> Struct {} | ^^^^^ expected 1 generic argument @@ -126,7 +114,7 @@ LL | impl> Struct {} | +++++++ error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:42:58 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:40:58 | LL | impl, U> YetAnotherTrait for Struct {} | ^^^^^^ - help: remove this generic argument @@ -134,12 +122,12 @@ LL | impl, U> YetAnotherTrait for Struct {} | expected 1 generic argument | note: struct defined here, with 1 generic parameter: `T` - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:28:8 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:8 | LL | struct Struct> { | ^^^^^^ - -error: aborting due to 11 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0107, E0207, E0282. +Some errors have detailed explanations: E0107, E0207. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr b/tests/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr index b7a7784755ec..ebd45b9dd963 100644 --- a/tests/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr +++ b/tests/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr @@ -4,7 +4,7 @@ error[E0277]: expected a `FnOnce(&i32)` closure, found `i32` LL | f:: X<'x, F = i32>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce(&i32)` closure, found `i32` | - = help: the trait `for<'a> FnOnce<(&'a i32,)>` is not implemented for `i32` + = help: the trait `for<'a> FnOnce(&'a i32)` is not implemented for `i32` note: required by a bound in `f` --> $DIR/check-trait-object-bounds-2.rs:8:9 | diff --git a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs index f8e3f8e968e1..98825bd536e0 100644 --- a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs +++ b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs @@ -2,7 +2,7 @@ fn strip_lf(s: &str) -> &str { s.strip_suffix(b'\n').unwrap_or(s) //~^ ERROR expected a `FnMut(char)` closure, found `u8` //~| NOTE expected an `FnMut(char)` closure, found `u8` - //~| HELP the trait `FnMut<(char,)>` is not implemented for `u8` + //~| HELP the trait `FnMut(char)` is not implemented for `u8` //~| HELP the following other types implement trait `Pattern<'a>`: //~| NOTE required for `u8` to implement `Pattern<'_>` diff --git a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr index 27006f59b902..49272e7d357b 100644 --- a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr +++ b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr @@ -4,7 +4,7 @@ error[E0277]: expected a `FnMut(char)` closure, found `u8` LL | s.strip_suffix(b'\n').unwrap_or(s) | ^^^^^^^^^^^^ expected an `FnMut(char)` closure, found `u8` | - = help: the trait `FnMut<(char,)>` is not implemented for `u8`, which is required by `u8: Pattern<'_>` + = help: the trait `FnMut(char)` is not implemented for `u8`, which is required by `u8: Pattern<'_>` = help: the following other types implement trait `Pattern<'a>`: &'b String &'b [char; N] diff --git a/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.rs b/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.rs new file mode 100644 index 000000000000..bf1278f992b6 --- /dev/null +++ b/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.rs @@ -0,0 +1,27 @@ +//! This test used to ICE: #121134 +//! The issue is that we're trying to prove a projection, but there's +//! no bound for the projection's trait, and the projection has the wrong +//! kind of generic parameter (lifetime vs type). +//! When actually calling the function with those broken bounds, trying to +//! instantiate the bounds with inference vars would ICE. +#![feature(unboxed_closures)] + +trait Output<'a> { + type Type; +} + +struct Wrapper; + +impl Wrapper { + fn do_something_wrapper(&mut self, _: F) + where + F: for<'a> FnOnce(>::Type), + //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied + { + } +} + +fn main() { + let mut wrapper = Wrapper; + wrapper.do_something_wrapper(|value| ()); +} diff --git a/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.stderr b/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.stderr new file mode 100644 index 000000000000..acda3418894d --- /dev/null +++ b/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.stderr @@ -0,0 +1,19 @@ +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/generic_param_mismatch_in_unsatisfied_projection.rs:18:33 + | +LL | F: for<'a> FnOnce(>::Type), + | ^^^^^^ expected 0 generic arguments + | +note: trait defined here, with 0 generic parameters + --> $DIR/generic_param_mismatch_in_unsatisfied_projection.rs:9:7 + | +LL | trait Output<'a> { + | ^^^^^^ +help: replace the generic bound with the associated type + | +LL | F: for<'a> FnOnce(>::Type), + | ++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index 58a4c229e5e6..cdcb0cdf2593 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -55,12 +55,6 @@ LL | impl DispatchFromDyn> for T {} = help: add `#![feature(dispatch_from_dyn)]` 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[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures - --> $DIR/issue-78372.rs:3:1 - | -LL | impl DispatchFromDyn> for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/issue-78372.rs:12:17 | @@ -88,6 +82,12 @@ LL | fn foo(self: Smaht); = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) +error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures + --> $DIR/issue-78372.rs:3:1 + | +LL | impl DispatchFromDyn> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 8 previous errors Some errors have detailed explanations: E0038, E0307, E0378, E0412, E0658. diff --git a/tests/ui/traits/issue-87558.rs b/tests/ui/traits/issue-87558.rs index 76f0f7453ddd..61a24f6b9671 100644 --- a/tests/ui/traits/issue-87558.rs +++ b/tests/ui/traits/issue-87558.rs @@ -2,7 +2,7 @@ struct ErrorKind; struct Error(ErrorKind); impl Fn(&isize) for Error { //~^ ERROR manual implementations of `Fn` are experimental - //~| ERROR associated type bindings are not allowed here + //~| ERROR associated item constraints are not allowed here //~| ERROR closure, found `Error` //~| ERROR not all trait items implemented, missing: `call` fn from() {} //~ ERROR method `from` is not a member of trait `Fn` diff --git a/tests/ui/traits/issue-87558.stderr b/tests/ui/traits/issue-87558.stderr index 1ce273a9f25e..4cc3ec2ea8b9 100644 --- a/tests/ui/traits/issue-87558.stderr +++ b/tests/ui/traits/issue-87558.stderr @@ -12,11 +12,11 @@ LL | impl Fn(&isize) for Error { | = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-87558.rs:3:6 | LL | impl Fn(&isize) for Error { - | ^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^ associated item constraint not allowed here | help: parenthesized trait syntax expands to `Fn<(&isize,), Output=()>` --> $DIR/issue-87558.rs:3:6 @@ -30,7 +30,7 @@ error[E0277]: expected a `FnMut(&isize)` closure, found `Error` LL | impl Fn(&isize) for Error { | ^^^^^ expected an `FnMut(&isize)` closure, found `Error` | - = help: the trait `FnMut<(&isize,)>` is not implemented for `Error` + = help: the trait `FnMut(&isize)` is not implemented for `Error` note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL diff --git a/tests/ui/traits/next-solver/fn-trait.stderr b/tests/ui/traits/next-solver/fn-trait.stderr index e33487235e66..86d97cb16b32 100644 --- a/tests/ui/traits/next-solver/fn-trait.stderr +++ b/tests/ui/traits/next-solver/fn-trait.stderr @@ -6,7 +6,7 @@ LL | require_fn(f as unsafe fn() -> i32); | | | required by a bound introduced by this call | - = help: the trait `Fn<()>` is not implemented for `unsafe fn() -> i32` + = help: the trait `Fn()` is not implemented for `unsafe fn() -> i32` = note: unsafe function cannot be called generically without an unsafe block = note: wrap the `unsafe fn() -> i32` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `require_fn` @@ -37,7 +37,7 @@ LL | require_fn(g); | | | required by a bound introduced by this call | - = help: the trait `Fn<()>` is not implemented for fn item `extern "C" fn() -> i32 {g}` + = help: the trait `Fn()` is not implemented for fn item `extern "C" fn() -> i32 {g}` = note: wrap the `extern "C" fn() -> i32 {g}` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `require_fn` --> $DIR/fn-trait.rs:3:23 @@ -67,7 +67,7 @@ LL | require_fn(g as extern "C" fn() -> i32); | | | required by a bound introduced by this call | - = help: the trait `Fn<()>` is not implemented for `extern "C" fn() -> i32` + = help: the trait `Fn()` is not implemented for `extern "C" fn() -> i32` = note: wrap the `extern "C" fn() -> i32` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `require_fn` --> $DIR/fn-trait.rs:3:23 @@ -97,7 +97,7 @@ LL | require_fn(h); | | | required by a bound introduced by this call | - = help: the trait `Fn<()>` is not implemented for fn item `unsafe fn() -> i32 {h}` + = help: the trait `Fn()` is not implemented for fn item `unsafe fn() -> i32 {h}` = note: unsafe function cannot be called generically without an unsafe block = note: wrap the `unsafe fn() -> i32 {h}` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `require_fn` 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 2e0566cad08e..17da1f524796 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -25,10 +25,10 @@ help: this trait has no implementations, consider adding one 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) } -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) } -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) } -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) } + 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) } + 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) } + 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) } + 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[E0119]: conflicting implementations of trait `Overlap` for type `fn(_)` --> $DIR/issue-118950-root-region.rs:19:1 | diff --git a/tests/ui/traits/next-solver/specialization-transmute.rs b/tests/ui/traits/next-solver/specialization-transmute.rs index caa3bfc552eb..9e31fed9b180 100644 --- a/tests/ui/traits/next-solver/specialization-transmute.rs +++ b/tests/ui/traits/next-solver/specialization-transmute.rs @@ -10,7 +10,7 @@ trait Default { } impl Default for T { - default type Id = T; //~ ERROR type annotations needed + default type Id = T; // This will be fixed by #111994 fn intu(&self) -> &Self::Id { //~^ ERROR type annotations needed diff --git a/tests/ui/traits/next-solver/specialization-transmute.stderr b/tests/ui/traits/next-solver/specialization-transmute.stderr index 76ae08fdb7a7..524522bef098 100644 --- a/tests/ui/traits/next-solver/specialization-transmute.stderr +++ b/tests/ui/traits/next-solver/specialization-transmute.stderr @@ -34,13 +34,6 @@ note: required by a bound in `transmute` LL | fn transmute, U: Copy>(t: T) -> U { | ^^^^^^ required by this bound in `transmute` -error[E0282]: type annotations needed - --> $DIR/specialization-transmute.rs:13:23 - | -LL | default type Id = T; - | ^ cannot infer type for associated type `::Id` +error: aborting due to 4 previous errors; 1 warning emitted -error: aborting due to 5 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0282, E0284. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/next-solver/specialization-unconstrained.rs b/tests/ui/traits/next-solver/specialization-unconstrained.rs index f4046fba20b2..e44246a1262a 100644 --- a/tests/ui/traits/next-solver/specialization-unconstrained.rs +++ b/tests/ui/traits/next-solver/specialization-unconstrained.rs @@ -11,7 +11,7 @@ trait Default { } impl Default for T { - default type Id = T; //~ ERROR type annotations needed + default type Id = T; } fn test, U>() {} diff --git a/tests/ui/traits/next-solver/specialization-unconstrained.stderr b/tests/ui/traits/next-solver/specialization-unconstrained.stderr index 68232aacc0c5..a6f6a4f260d4 100644 --- a/tests/ui/traits/next-solver/specialization-unconstrained.stderr +++ b/tests/ui/traits/next-solver/specialization-unconstrained.stderr @@ -20,13 +20,6 @@ note: required by a bound in `test` LL | fn test, U>() {} | ^^^^^^ required by this bound in `test` -error[E0282]: type annotations needed - --> $DIR/specialization-unconstrained.rs:14:22 - | -LL | default type Id = T; - | ^ cannot infer type for associated type `::Id` +error: aborting due to 1 previous error; 1 warning emitted -error: aborting due to 2 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0282, E0284. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/next-solver/unsound-region-obligation.rs b/tests/ui/traits/next-solver/unsound-region-obligation.rs index 32a510d16543..733be2043548 100644 --- a/tests/ui/traits/next-solver/unsound-region-obligation.rs +++ b/tests/ui/traits/next-solver/unsound-region-obligation.rs @@ -1,4 +1,4 @@ -//~ ERROR the type `<() as StaticTy>::Item<'a>` does not fulfill the required lifetime +//~ ERROR the type `&'a ()` does not fulfill the required lifetime //@ compile-flags: -Znext-solver // Regression test for rust-lang/trait-system-refactor-initiative#59 diff --git a/tests/ui/traits/next-solver/unsound-region-obligation.stderr b/tests/ui/traits/next-solver/unsound-region-obligation.stderr index 518de7ea3e02..fe96a184f430 100644 --- a/tests/ui/traits/next-solver/unsound-region-obligation.stderr +++ b/tests/ui/traits/next-solver/unsound-region-obligation.stderr @@ -1,4 +1,4 @@ -error[E0477]: the type `<() as StaticTy>::Item<'a>` does not fulfill the required lifetime +error[E0477]: the type `&'a ()` does not fulfill the required lifetime | = note: type must satisfy the static lifetime diff --git a/tests/ui/traits/suggest-dereferences/root-obligation.stderr b/tests/ui/traits/suggest-dereferences/root-obligation.stderr index 56f95e207158..14b2ecbb9f2d 100644 --- a/tests/ui/traits/suggest-dereferences/root-obligation.stderr +++ b/tests/ui/traits/suggest-dereferences/root-obligation.stderr @@ -2,11 +2,11 @@ error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied --> $DIR/root-obligation.rs:6:38 | LL | .filter(|c| "aeiou".contains(c)) - | -------- ^ the trait `Fn<(char,)>` is not implemented for `&char`, which is required by `&char: Pattern<'_>` + | -------- ^ the trait `Fn(char)` is not implemented for `&char`, which is required by `&char: Pattern<'_>` | | | required by a bound introduced by this call | - = note: required for `&char` to implement `FnOnce<(char,)>` + = note: required for `&char` to implement `FnOnce(char)` = note: required for `&char` to implement `Pattern<'_>` note: required by a bound in `core::str::::contains` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/traits/vtable/vtable-vacant.rs b/tests/ui/traits/vtable/vtable-vacant.rs index 26de3f606210..b3c768157036 100644 --- a/tests/ui/traits/vtable/vtable-vacant.rs +++ b/tests/ui/traits/vtable/vtable-vacant.rs @@ -1,7 +1,6 @@ //@ build-fail #![feature(rustc_attrs)] #![feature(negative_impls)] -#![allow(where_clauses_object_safety)] // B --> A diff --git a/tests/ui/traits/vtable/vtable-vacant.stderr b/tests/ui/traits/vtable/vtable-vacant.stderr index 9ce1d0b76328..f6961ca010ed 100644 --- a/tests/ui/traits/vtable/vtable-vacant.stderr +++ b/tests/ui/traits/vtable/vtable-vacant.stderr @@ -7,7 +7,7 @@ error: vtable entries for ``: [ Method(::foo_b1), Vacant, ] - --> $DIR/vtable-vacant.rs:15:1 + --> $DIR/vtable-vacant.rs:14:1 | LL | trait B: A { | ^^^^^^^^^^ diff --git a/tests/ui/transmutability/issue-101739-2.rs b/tests/ui/transmutability/issue-101739-2.rs index e2cec24aac14..1c0bd29d7079 100644 --- a/tests/ui/transmutability/issue-101739-2.rs +++ b/tests/ui/transmutability/issue-101739-2.rs @@ -15,7 +15,6 @@ mod assert { >() where Dst: BikeshedIntrinsicFrom< //~ ERROR trait takes at most 2 generic arguments but 5 generic arguments were supplied - //~^ ERROR: the constant `ASSUME_ALIGNMENT` is not of type `Assume` Src, ASSUME_ALIGNMENT, //~ ERROR: mismatched types ASSUME_LIFETIMES, diff --git a/tests/ui/transmutability/issue-101739-2.stderr b/tests/ui/transmutability/issue-101739-2.stderr index 639b44608924..38912696c18e 100644 --- a/tests/ui/transmutability/issue-101739-2.stderr +++ b/tests/ui/transmutability/issue-101739-2.stderr @@ -9,29 +9,13 @@ LL | | ASSUME_VALIDITY, LL | | ASSUME_VISIBILITY, | |_____________________________- help: remove these generic arguments -error: the constant `ASSUME_ALIGNMENT` is not of type `Assume` - --> $DIR/issue-101739-2.rs:17:14 - | -LL | Dst: BikeshedIntrinsicFrom< - | ______________^ -LL | | -LL | | Src, -LL | | ASSUME_ALIGNMENT, -... | -LL | | ASSUME_VISIBILITY, -LL | | >, - | |_________^ expected `Assume`, found `bool` - | -note: required by a bound in `BikeshedIntrinsicFrom` - --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL - error[E0308]: mismatched types - --> $DIR/issue-101739-2.rs:20:13 + --> $DIR/issue-101739-2.rs:19:13 | LL | ASSUME_ALIGNMENT, | ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0107, E0308. For more information about an error, try `rustc --explain E0107`. 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 new file mode 100644 index 000000000000..6a1a770228da --- /dev/null +++ b/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr @@ -0,0 +1,10 @@ +error: `Bar` is forbidden as the type of a const generic parameter + --> $DIR/const_generic_type.rs:7:24 + | +LL | async fn test() { + | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: aborting due to 1 previous error + 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 new file mode 100644 index 000000000000..a1a69bfaca37 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr @@ -0,0 +1,19 @@ +error[E0283]: type annotations needed + --> $DIR/const_generic_type.rs:7:1 + | +LL | async fn test() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | + = note: cannot satisfy `_: std::fmt::Display` + +error: `Bar` is forbidden as the type of a const generic parameter + --> $DIR/const_generic_type.rs:7:24 + | +LL | async fn test() { + | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.rs b/tests/ui/type-alias-impl-trait/const_generic_type.rs new file mode 100644 index 000000000000..95a5e1c62861 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/const_generic_type.rs @@ -0,0 +1,14 @@ +//@edition: 2021 +//@revisions: infer no_infer + +#![feature(type_alias_impl_trait)] +type Bar = impl std::fmt::Display; + +async fn test() { + //[no_infer]~^ ERROR: type annotations needed + //~^^ ERROR: `Bar` is forbidden as the type of a const generic parameter + #[cfg(infer)] + let x: u32 = N; +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-63279.stderr b/tests/ui/type-alias-impl-trait/issue-63279.stderr index 58cafd21ca87..97158ee297da 100644 --- a/tests/ui/type-alias-impl-trait/issue-63279.stderr +++ b/tests/ui/type-alias-impl-trait/issue-63279.stderr @@ -4,7 +4,7 @@ error[E0277]: expected a `FnOnce()` closure, found `()` LL | fn c() -> Closure { | ^^^^^^^ expected an `FnOnce()` closure, found `()` | - = help: the trait `FnOnce<()>` is not implemented for `()` + = help: the trait `FnOnce()` is not implemented for `()` = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` error[E0277]: expected a `FnOnce()` closure, found `()` @@ -13,7 +13,7 @@ error[E0277]: expected a `FnOnce()` closure, found `()` LL | || -> Closure { || () } | ^^^^^^^ expected an `FnOnce()` closure, found `()` | - = help: the trait `FnOnce<()>` is not implemented for `()` + = help: the trait `FnOnce()` is not implemented for `()` = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` error[E0308]: mismatched types diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs index 050b7b44b4e0..3defe0cb44d3 100644 --- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs +++ b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs @@ -5,6 +5,6 @@ type Pat = std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>); //~^ ERROR type and const arguments are not allowed on const parameter `START` //~| ERROR type arguments are not allowed on const parameter `END` -//~| ERROR associated type bindings are not allowed here +//~| ERROR associated item constraints are not allowed here fn main() {} diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr index 40effe924da8..7f4e6e314f53 100644 --- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr +++ b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr @@ -26,11 +26,11 @@ note: const parameter `END` defined here LL | type Pat = | ^^^ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/bad_const_generics_args_on_const_param.rs:5:67 | LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>); - | ^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^ associated item constraint not allowed here error: aborting due to 3 previous errors diff --git a/tests/ui/typeck/escaping_bound_vars.rs b/tests/ui/typeck/escaping_bound_vars.rs index 985a3fdbccf3..3cde041f1858 100644 --- a/tests/ui/typeck/escaping_bound_vars.rs +++ b/tests/ui/typeck/escaping_bound_vars.rs @@ -10,7 +10,7 @@ pub fn test() where (): Test<{ 1 + (<() as Elide(&())>::call) }>, //~^ ERROR cannot capture late-bound lifetime in constant - //~| ERROR associated type bindings are not allowed here + //~| ERROR associated item constraints are not allowed here { } diff --git a/tests/ui/typeck/escaping_bound_vars.stderr b/tests/ui/typeck/escaping_bound_vars.stderr index bd9c95fab979..f383099ce13b 100644 --- a/tests/ui/typeck/escaping_bound_vars.stderr +++ b/tests/ui/typeck/escaping_bound_vars.stderr @@ -6,11 +6,11 @@ LL | (): Test<{ 1 + (<() as Elide(&())>::call) }>, | | | lifetime defined here -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/escaping_bound_vars.rs:11:28 | LL | (): Test<{ 1 + (<() as Elide(&())>::call) }>, - | ^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^ associated item constraint not allowed here error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/issue-83693.rs b/tests/ui/typeck/issue-83693.rs index a4255822056d..02a0bb30d7ce 100644 --- a/tests/ui/typeck/issue-83693.rs +++ b/tests/ui/typeck/issue-83693.rs @@ -8,12 +8,12 @@ impl F { fn call() { ::call //~^ ERROR: cannot find type `TestResult` in this scope [E0412] - //~| associated type bindings are not allowed here [E0229] + //~| associated item constraints are not allowed here [E0229] } } fn call() { ::call //~^ ERROR: cannot find type `x` in this scope [E0412] - //~| ERROR: associated type bindings are not allowed here [E0229] + //~| ERROR: associated item constraints are not allowed here [E0229] } diff --git a/tests/ui/typeck/issue-83693.stderr b/tests/ui/typeck/issue-83693.stderr index ce4f73b820a1..34bca426116e 100644 --- a/tests/ui/typeck/issue-83693.stderr +++ b/tests/ui/typeck/issue-83693.stderr @@ -19,17 +19,17 @@ error[E0412]: cannot find type `x` in this scope LL | ::call | ^ not found in this scope -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-83693.rs:9:18 | LL | ::call - | ^^^^^^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^^^^^^ associated item constraint not allowed here -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-83693.rs:16:11 | LL | ::call - | ^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^ associated item constraint not allowed here error: aborting due to 5 previous errors diff --git a/tests/ui/typeck/issue-84768.rs b/tests/ui/typeck/issue-84768.rs index ffa92823b42f..3ba5dffcf07a 100644 --- a/tests/ui/typeck/issue-84768.rs +++ b/tests/ui/typeck/issue-84768.rs @@ -5,6 +5,6 @@ fn transform_mut(f: F) where F: for<'b> FnOnce(&'b mut u8) { ::call_once(f, 1) - //~^ ERROR: associated type bindings are not allowed here [E0229] + //~^ ERROR: associated item constraints are not allowed here [E0229] //~| ERROR: mismatched types [E0308] } diff --git a/tests/ui/typeck/issue-84768.stderr b/tests/ui/typeck/issue-84768.stderr index 3d2d53f5c76c..72784ba59c9b 100644 --- a/tests/ui/typeck/issue-84768.stderr +++ b/tests/ui/typeck/issue-84768.stderr @@ -1,8 +1,8 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-84768.rs:7:11 | LL | ::call_once(f, 1) - | ^^^^^^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^^^^^^ associated item constraint not allowed here error[E0308]: mismatched types --> $DIR/issue-84768.rs:7:42 diff --git a/tests/ui/typeck/issue-91267.rs b/tests/ui/typeck/issue-91267.rs index 4e39cfab5b43..1bffa09e6436 100644 --- a/tests/ui/typeck/issue-91267.rs +++ b/tests/ui/typeck/issue-91267.rs @@ -3,6 +3,6 @@ fn main() { type_ascribe!(0, u8=e>) //~^ ERROR: cannot find type `e` in this scope [E0412] - //~| ERROR: associated type bindings are not allowed here [E0229] + //~| ERROR: associated item constraints are not allowed here [E0229] //~| ERROR: mismatched types [E0308] } diff --git a/tests/ui/typeck/issue-91267.stderr b/tests/ui/typeck/issue-91267.stderr index 399309d0ec44..d16b1997e9f7 100644 --- a/tests/ui/typeck/issue-91267.stderr +++ b/tests/ui/typeck/issue-91267.stderr @@ -4,11 +4,11 @@ error[E0412]: cannot find type `e` in this scope LL | type_ascribe!(0, u8=e>) | ^ not found in this scope -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-91267.rs:4:25 | LL | type_ascribe!(0, u8=e>) - | ^^^^^^ associated type not allowed here + | ^^^^^^ associated item constraint not allowed here error[E0308]: mismatched types --> $DIR/issue-91267.rs:4:5 diff --git a/tests/ui/ufcs/bad-builder.stderr b/tests/ui/ufcs/bad-builder.stderr index e466f94d0d84..9cfeb7a5d09d 100644 --- a/tests/ui/ufcs/bad-builder.stderr +++ b/tests/ui/ufcs/bad-builder.stderr @@ -9,7 +9,7 @@ note: if you're trying to build a new `Vec` consider using one of the followi Vec::::with_capacity Vec::::try_with_capacity Vec::::from_raw_parts - and 6 others + and 4 others --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL help: there is an associated function `new` with a similar name | diff --git a/tests/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr b/tests/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr index 795bd0a0d180..9c5d824185b8 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr @@ -6,7 +6,7 @@ LL | let x = call_it(&S, 22); | | | required by a bound introduced by this call | - = help: the trait `Fn<(isize,)>` is not implemented for `S` + = help: the trait `Fn(isize)` is not implemented for `S` = note: `S` implements `FnMut`, but it must implement `Fn`, which is more general note: required by a bound in `call_it` --> $DIR/unboxed-closures-fnmut-as-fn.rs:22:14 diff --git a/tests/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr b/tests/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr index d836af2b0149..dfdb3ea19c3f 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr @@ -6,7 +6,7 @@ LL | let x = call_it(&square, 22); | | | required by a bound introduced by this call | - = help: the trait `for<'a> Fn<(&'a isize,)>` is not implemented for fn item `for<'a> unsafe fn(&'a isize) -> isize {square}` + = help: the trait `for<'a> Fn(&'a isize)` is not implemented for fn item `for<'a> unsafe fn(&'a isize) -> isize {square}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `call_it` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:9:15 @@ -22,7 +22,7 @@ LL | let y = call_it_mut(&mut square, 22); | | | required by a bound introduced by this call | - = help: the trait `for<'a> FnMut<(&'a isize,)>` is not implemented for fn item `for<'a> unsafe fn(&'a isize) -> isize {square}` + = help: the trait `for<'a> FnMut(&'a isize)` is not implemented for fn item `for<'a> unsafe fn(&'a isize) -> isize {square}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `call_it_mut` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:19 @@ -38,7 +38,7 @@ LL | let z = call_it_once(square, 22); | | | required by a bound introduced by this call | - = help: the trait `for<'a> FnOnce<(&'a isize,)>` is not implemented for fn item `for<'a> unsafe fn(&'a isize) -> isize {square}` + = help: the trait `for<'a> FnOnce(&'a isize)` is not implemented for fn item `for<'a> unsafe fn(&'a isize) -> isize {square}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `call_it_once` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:15:20 diff --git a/tests/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr b/tests/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr index c0dcf83a5bb0..b4521cc6890d 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr @@ -6,7 +6,7 @@ LL | let x = call_it(&square, 22); | | | required by a bound introduced by this call | - = help: the trait `for<'a> Fn<(&'a isize,)>` is not implemented for fn item `for<'a> extern "C" fn(&'a isize) -> isize {square}` + = help: the trait `for<'a> Fn(&'a isize)` is not implemented for fn item `for<'a> extern "C" fn(&'a isize) -> isize {square}` note: required by a bound in `call_it` --> $DIR/unboxed-closures-wrong-abi.rs:9:15 | @@ -21,7 +21,7 @@ LL | let y = call_it_mut(&mut square, 22); | | | required by a bound introduced by this call | - = help: the trait `for<'a> FnMut<(&'a isize,)>` is not implemented for fn item `for<'a> extern "C" fn(&'a isize) -> isize {square}` + = help: the trait `for<'a> FnMut(&'a isize)` is not implemented for fn item `for<'a> extern "C" fn(&'a isize) -> isize {square}` note: required by a bound in `call_it_mut` --> $DIR/unboxed-closures-wrong-abi.rs:12:19 | @@ -36,7 +36,7 @@ LL | let z = call_it_once(square, 22); | | | required by a bound introduced by this call | - = help: the trait `for<'a> FnOnce<(&'a isize,)>` is not implemented for fn item `for<'a> extern "C" fn(&'a isize) -> isize {square}` + = help: the trait `for<'a> FnOnce(&'a isize)` is not implemented for fn item `for<'a> extern "C" fn(&'a isize) -> isize {square}` note: required by a bound in `call_it_once` --> $DIR/unboxed-closures-wrong-abi.rs:15:20 | diff --git a/tests/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr b/tests/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr index d261c38f50c2..5519bb33ebc2 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr @@ -6,7 +6,7 @@ LL | let x = call_it(&square, 22); | | | required by a bound introduced by this call | - = help: the trait `for<'a> Fn<(&'a isize,)>` is not implemented for fn item `unsafe fn(isize) -> isize {square}` + = help: the trait `for<'a> Fn(&'a isize)` is not implemented for fn item `unsafe fn(isize) -> isize {square}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `call_it` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:10:15 @@ -22,7 +22,7 @@ LL | let y = call_it_mut(&mut square, 22); | | | required by a bound introduced by this call | - = help: the trait `for<'a> FnMut<(&'a isize,)>` is not implemented for fn item `unsafe fn(isize) -> isize {square}` + = help: the trait `for<'a> FnMut(&'a isize)` is not implemented for fn item `unsafe fn(isize) -> isize {square}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `call_it_mut` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:19 @@ -38,7 +38,7 @@ LL | let z = call_it_once(square, 22); | | | required by a bound introduced by this call | - = help: the trait `for<'a> FnOnce<(&'a isize,)>` is not implemented for fn item `unsafe fn(isize) -> isize {square}` + = help: the trait `for<'a> FnOnce(&'a isize)` is not implemented for fn item `unsafe fn(isize) -> isize {square}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `call_it_once` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:16:20 diff --git a/tests/ui/unsafe/initializing-ranged-via-ctor.stderr b/tests/ui/unsafe/initializing-ranged-via-ctor.stderr index 56b112867cf0..040c1d5bcbee 100644 --- a/tests/ui/unsafe/initializing-ranged-via-ctor.stderr +++ b/tests/ui/unsafe/initializing-ranged-via-ctor.stderr @@ -6,7 +6,7 @@ LL | println!("{:?}", Some(1).map(NonZeroAndOneU8).unwrap()); | | | required by a bound introduced by this call | - = help: the trait `FnOnce<({integer},)>` is not implemented for fn item `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}` + = help: the trait `FnOnce({integer})` is not implemented for fn item `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `Option::::map` --> $SRC_DIR/core/src/option.rs:LL:COL diff --git a/tests/ui/where-clauses/self-in-where-clause-allowed.rs b/tests/ui/where-clauses/self-in-where-clause-allowed.rs index fd2cfe2bf65e..a4c2d82b4837 100644 --- a/tests/ui/where-clauses/self-in-where-clause-allowed.rs +++ b/tests/ui/where-clauses/self-in-where-clause-allowed.rs @@ -1,7 +1,6 @@ //@ check-fail #![feature(auto_traits)] -#![deny(where_clauses_object_safety)] auto trait AutoTrait {} diff --git a/tests/ui/where-clauses/self-in-where-clause-allowed.stderr b/tests/ui/where-clauses/self-in-where-clause-allowed.stderr index 7f92ac102f01..5d23c4bee00f 100644 --- a/tests/ui/where-clauses/self-in-where-clause-allowed.stderr +++ b/tests/ui/where-clauses/self-in-where-clause-allowed.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `dyn Trait: AutoTrait` is not satisfied - --> $DIR/self-in-where-clause-allowed.rs:22:18 + --> $DIR/self-in-where-clause-allowed.rs:21:18 | LL | trait_object.autotrait_bound(); | ^^^^^^^^^^^^^^^ the trait `AutoTrait` is not implemented for `dyn Trait` | note: required by a bound in `Trait::autotrait_bound` - --> $DIR/self-in-where-clause-allowed.rs:13:43 + --> $DIR/self-in-where-clause-allowed.rs:12:43 | LL | fn autotrait_bound(&self) where Self: AutoTrait {} | ^^^^^^^^^ required by this bound in `Trait::autotrait_bound`

] { + loop {} +} +pub fn bet() -> R<[Q; 32]> { + loop {} +} // in_args test -pub fn alpha(_x: R<&'static [P]>) { loop {} } -pub fn beta(_x: [R; 32]) { loop {} } +pub fn alpha(_x: R<&'static [P]>) { + loop {} +} +pub fn beta(_x: [R; 32]) { + loop {} +} pub trait TraitCat {} pub trait TraitDog {} diff --git a/tests/rustdoc-js/struct-like-variant.rs b/tests/rustdoc-js/struct-like-variant.rs index 2f52a319ab9a..aafde9957ff8 100644 --- a/tests/rustdoc-js/struct-like-variant.rs +++ b/tests/rustdoc-js/struct-like-variant.rs @@ -3,6 +3,6 @@ pub enum Enum { Bar { /// This is a name. - name: String - } + name: String, + }, } diff --git a/tests/rustdoc-js/summaries.rs b/tests/rustdoc-js/summaries.rs index 1ee1c34aa156..9e8fc820245e 100644 --- a/tests/rustdoc-js/summaries.rs +++ b/tests/rustdoc-js/summaries.rs @@ -1,6 +1,5 @@ #![crate_type = "lib"] #![crate_name = "summaries"] - #![allow(rustdoc::broken_intra_doc_links)] //! This *summary* has a [link], [`code`], and [`Sidebar2`] intra-doc. diff --git a/tests/rustdoc-js/tuple-unit.rs b/tests/rustdoc-js/tuple-unit.rs index 93f9a671cbc3..4531545cf6c5 100644 --- a/tests/rustdoc-js/tuple-unit.rs +++ b/tests/rustdoc-js/tuple-unit.rs @@ -3,16 +3,24 @@ pub struct Q; pub struct R(T); // Checks that tuple and unit both work -pub fn side_effect() { } +pub fn side_effect() {} // Check a non-tuple -pub fn not_tuple() -> P { loop {} } +pub fn not_tuple() -> P { + loop {} +} // Check a 1-tuple -pub fn one() -> (P,) { loop {} } +pub fn one() -> (P,) { + loop {} +} // Check a 2-tuple -pub fn two() -> (P,P) { loop {} } +pub fn two() -> (P, P) { + loop {} +} // Check a nested tuple -pub fn nest() -> (Q, R<(u32,)>) { loop {} } +pub fn nest() -> (Q, R<(u32,)>) { + loop {} +} diff --git a/tests/rustdoc-js/type-parameters.rs b/tests/rustdoc-js/type-parameters.rs index cda5e26171fc..0edbfbea178b 100644 --- a/tests/rustdoc-js/type-parameters.rs +++ b/tests/rustdoc-js/type-parameters.rs @@ -1,15 +1,23 @@ -#![crate_name="foo"] +#![crate_name = "foo"] pub trait Some {} impl Some for () {} pub trait Other {} impl Other for () {} -pub fn alef() -> T { loop {} } -pub fn alpha() -> impl Some { } +pub fn alef() -> T { + loop {} +} +pub fn alpha() -> impl Some {} -pub fn bet(t: T) -> U { loop {} } +pub fn bet(t: T) -> U { + loop {} +} pub fn beta(t: T) -> T {} -pub fn other(t: T, u: U) { loop {} } -pub fn alternate(t: T, u: T) { loop {} } +pub fn other(t: T, u: U) { + loop {} +} +pub fn alternate(t: T, u: T) { + loop {} +} diff --git a/tests/rustdoc-js/where-clause.rs b/tests/rustdoc-js/where-clause.rs index 56c01019fb69..c0fede1cfd59 100644 --- a/tests/rustdoc-js/where-clause.rs +++ b/tests/rustdoc-js/where-clause.rs @@ -4,27 +4,46 @@ pub trait Trait { fn thank_you(x: T); } -pub fn abracadabra(_: X) where X: Trait {} +pub fn abracadabra(_: X) +where + X: Trait, +{ +} -pub fn alacazam() -> X where X: Trait {} +pub fn alacazam() -> X +where + X: Trait, +{ +} pub trait T1 {} pub trait T2<'a, T> { fn please(_: &'a T); } -pub fn presto(_: A, _: B) where A: T1, B: for <'b> T2<'b, Nested> {} +pub fn presto(_: A, _: B) +where + A: T1, + B: for<'b> T2<'b, Nested>, +{ +} pub trait Shazam {} -pub fn bippety() -> &'static X where X: Shazam { +pub fn bippety() -> &'static X +where + X: Shazam, +{ panic!() } pub struct Drizzel(T); impl Drizzel { - pub fn boppety(&self) -> &T where T: Shazam { + pub fn boppety(&self) -> &T + where + T: Shazam, + { panic!(); } } diff --git a/tests/rustdoc-json/lifetime/longest.rs b/tests/rustdoc-json/lifetime/longest.rs index 419b0b4fcab1..dccad41a861b 100644 --- a/tests/rustdoc-json/lifetime/longest.rs +++ b/tests/rustdoc-json/lifetime/longest.rs @@ -23,9 +23,5 @@ // @is "$.index[*][?(@.name=='longest')].inner.function.decl.output.borrowed_ref.type.primitive" \"str\" pub fn longest<'a>(l: &'a str, r: &'a str) -> &'a str { - if l.len() > r.len() { - l - } else { - r - } + if l.len() > r.len() { l } else { r } } diff --git a/tests/rustdoc-json/non_lifetime_binders.rs b/tests/rustdoc-json/non_lifetime_binders.rs index d925fcd52215..6f0732646ca1 100644 --- a/tests/rustdoc-json/non_lifetime_binders.rs +++ b/tests/rustdoc-json/non_lifetime_binders.rs @@ -12,4 +12,8 @@ pub struct Wrapper(std::marker::PhantomData); // @is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }' // @is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[1].name" \"T\" // @is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[1].kind" '{ "type": { "bounds": [], "default": null, "synthetic": false } }' -pub fn foo() where for<'a, T> &'a Wrapper: Trait {} +pub fn foo() +where + for<'a, T> &'a Wrapper: Trait, +{ +} diff --git a/tests/rustdoc-json/output_generics.rs b/tests/rustdoc-json/output_generics.rs index d421eafbb47b..e9df64b79e30 100644 --- a/tests/rustdoc-json/output_generics.rs +++ b/tests/rustdoc-json/output_generics.rs @@ -16,12 +16,19 @@ pub trait Trait { fn handle(value: T) -> Self; } -impl Trait for T where T: From { - fn handle(_: U) -> Self { unimplemented!() } +impl Trait for T +where + T: From, +{ + fn handle(_: U) -> Self { + unimplemented!() + } } impl<'a, R> Trait<&'a mut Events> for Other { - fn handle(_: &'a mut Events) -> Self { unimplemented!() } + fn handle(_: &'a mut Events) -> Self { + unimplemented!() + } } fn this_compiles<'a, R>(value: &'a mut Events) { diff --git a/tests/rustdoc-json/type/extern.rs b/tests/rustdoc-json/type/extern.rs index c30146ce9e03..59e099ec9fce 100644 --- a/tests/rustdoc-json/type/extern.rs +++ b/tests/rustdoc-json/type/extern.rs @@ -1,6 +1,6 @@ #![feature(extern_types)] -extern { +extern "C" { /// No inner information pub type Foo; } diff --git a/tests/rustdoc-json/unions/impl.rs b/tests/rustdoc-json/unions/impl.rs index 7456892df1bb..1515f7d93971 100644 --- a/tests/rustdoc-json/unions/impl.rs +++ b/tests/rustdoc-json/unions/impl.rs @@ -4,7 +4,7 @@ // @has "$.index[*][?(@.name=='Ux')].inner.union" pub union Ux { a: u32, - b: u64 + b: u64, } // @is "$.index[*][?(@.name=='Num')].visibility" \"public\" diff --git a/tests/rustdoc-json/unions/union.rs b/tests/rustdoc-json/unions/union.rs index 22b70e1ce8c5..1089d9c45585 100644 --- a/tests/rustdoc-json/unions/union.rs +++ b/tests/rustdoc-json/unions/union.rs @@ -7,7 +7,6 @@ pub union Union { float: f32, } - // @has "$.index[*][?(@.name=='make_int_union')].inner.function.decl.output.resolved_path" // @is "$.index[*][?(@.name=='make_int_union')].inner.function.decl.output.resolved_path.id" $Union pub fn make_int_union(int: i32) -> Union { diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning.rs b/tests/rustdoc-ui/custom_code_classes_in_docs-warning.rs deleted file mode 100644 index 5398d5833c75..000000000000 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning.rs +++ /dev/null @@ -1,83 +0,0 @@ -// This test ensures that warnings are working as expected for "custom_code_classes_in_docs" -// feature. - -#![feature(custom_code_classes_in_docs)] -#![deny(warnings)] -#![feature(no_core)] -#![no_core] - -/// ```{. } -/// main; -/// ``` -//~^^^ ERROR unexpected ` ` character after `.` -pub fn foo() {} - -/// ```{class= a} -/// main; -/// ``` -//~^^^ ERROR unexpected ` ` character after `=` -pub fn foo2() {} - -/// ```{#id} -/// main; -/// ``` -//~^^^ ERROR unexpected character `#` -pub fn foo3() {} - -/// ```{{ -/// main; -/// ``` -//~^^^ ERROR unexpected character `{` -pub fn foo4() {} - -/// ```} -/// main; -/// ``` -//~^^^ ERROR unexpected character `}` -pub fn foo5() {} - -/// ```) -/// main; -/// ``` -//~^^^ ERROR unexpected character `)` -pub fn foo6() {} - -/// ```{class=} -/// main; -/// ``` -//~^^^ ERROR unexpected `}` character after `=` -pub fn foo7() {} - -/// ```( -/// main; -/// ``` -//~^^^ ERROR unclosed comment: missing `)` at the end -pub fn foo8() {} - -/// ```{class=one=two} -/// main; -/// ``` -//~^^^ ERROR unexpected `=` character -pub fn foo9() {} - -/// ```{.one.two} -/// main; -/// ``` -pub fn foo10() {} - -/// ```{class=(one} -/// main; -/// ``` -//~^^^ ERROR unexpected `(` character after `=` -pub fn foo11() {} - -/// ```{class=one.two} -/// main; -/// ``` -pub fn foo12() {} - -/// ```{(comment)} -/// main; -/// ``` -//~^^^ ERROR unexpected character `(` -pub fn foo13() {} diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning.stderr deleted file mode 100644 index 14b4b3bab3fa..000000000000 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning.stderr +++ /dev/null @@ -1,97 +0,0 @@ -error: unexpected ` ` character after `.` - --> $DIR/custom_code_classes_in_docs-warning.rs:9:1 - | -LL | / /// ```{. } -LL | | /// main; -LL | | /// ``` - | |_______^ - | -note: the lint level is defined here - --> $DIR/custom_code_classes_in_docs-warning.rs:5:9 - | -LL | #![deny(warnings)] - | ^^^^^^^^ - = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` - -error: unexpected ` ` character after `=` - --> $DIR/custom_code_classes_in_docs-warning.rs:15:1 - | -LL | / /// ```{class= a} -LL | | /// main; -LL | | /// ``` - | |_______^ - -error: unexpected character `#` - --> $DIR/custom_code_classes_in_docs-warning.rs:21:1 - | -LL | / /// ```{#id} -LL | | /// main; -LL | | /// ``` - | |_______^ - -error: unexpected character `{` - --> $DIR/custom_code_classes_in_docs-warning.rs:27:1 - | -LL | / /// ```{{ -LL | | /// main; -LL | | /// ``` - | |_______^ - -error: unexpected character `}` - --> $DIR/custom_code_classes_in_docs-warning.rs:33:1 - | -LL | / /// ```} -LL | | /// main; -LL | | /// ``` - | |_______^ - -error: unexpected character `)` - --> $DIR/custom_code_classes_in_docs-warning.rs:39:1 - | -LL | / /// ```) -LL | | /// main; -LL | | /// ``` - | |_______^ - -error: unexpected `}` character after `=` - --> $DIR/custom_code_classes_in_docs-warning.rs:45:1 - | -LL | / /// ```{class=} -LL | | /// main; -LL | | /// ``` - | |_______^ - -error: unclosed comment: missing `)` at the end - --> $DIR/custom_code_classes_in_docs-warning.rs:51:1 - | -LL | / /// ```( -LL | | /// main; -LL | | /// ``` - | |_______^ - -error: unexpected `=` character - --> $DIR/custom_code_classes_in_docs-warning.rs:57:1 - | -LL | / /// ```{class=one=two} -LL | | /// main; -LL | | /// ``` - | |_______^ - -error: unexpected `(` character after `=` - --> $DIR/custom_code_classes_in_docs-warning.rs:68:1 - | -LL | / /// ```{class=(one} -LL | | /// main; -LL | | /// ``` - | |_______^ - -error: unexpected character `(` - --> $DIR/custom_code_classes_in_docs-warning.rs:79:1 - | -LL | / /// ```{(comment)} -LL | | /// main; -LL | | /// ``` - | |_______^ - -error: aborting due to 11 previous errors - diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs index 57d9038cb0ce..6b1aa455d981 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs @@ -1,7 +1,6 @@ // This test ensures that warnings are working as expected for "custom_code_classes_in_docs" // feature. -#![feature(custom_code_classes_in_docs)] #![deny(warnings)] #![feature(no_core)] #![no_core] diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr index ad049804213d..fc47404734ee 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr @@ -1,5 +1,5 @@ error: unclosed quote string `"` - --> $DIR/custom_code_classes_in_docs-warning3.rs:9:1 + --> $DIR/custom_code_classes_in_docs-warning3.rs:8:1 | LL | / /// ```{class="} LL | | /// main; @@ -11,14 +11,14 @@ LL | | /// ``` | |_______^ | note: the lint level is defined here - --> $DIR/custom_code_classes_in_docs-warning3.rs:5:9 + --> $DIR/custom_code_classes_in_docs-warning3.rs:4:9 | LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` error: unclosed quote string `"` - --> $DIR/custom_code_classes_in_docs-warning3.rs:9:1 + --> $DIR/custom_code_classes_in_docs-warning3.rs:8:1 | LL | / /// ```{class="} LL | | /// main; diff --git a/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.rs b/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.rs deleted file mode 100644 index e96444039f4c..000000000000 --- a/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ check-pass - -/// ```{class=language-c} -/// int main(void) { return 0; } -/// ``` -//~^^^ WARNING custom classes in code blocks will change behaviour -//~| NOTE found these custom classes: class=language-c -//~| NOTE see issue #79483 -//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -//~| HELP add `#![feature(custom_code_classes_in_docs)]` to the crate attributes to enable -pub struct Bar; - -/// ```ASN.1 -/// int main(void) { return 0; } -/// ``` -pub struct Bar2; diff --git a/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.stderr b/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.stderr deleted file mode 100644 index 822806997c26..000000000000 --- a/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: custom classes in code blocks will change behaviour - --> $DIR/feature-gate-custom_code_classes_in_docs.rs:3:1 - | -LL | / /// ```{class=language-c} -LL | | /// int main(void) { return 0; } -LL | | /// ``` - | |_______^ - | - = note: see issue #79483 for more information - = help: add `#![feature(custom_code_classes_in_docs)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: found these custom classes: class=language-c - -warning: 1 warning emitted - diff --git a/tests/rustdoc-ui/ice-blanket-impl-119792.rs b/tests/rustdoc-ui/ice-blanket-impl-119792.rs new file mode 100644 index 000000000000..90f0ea8469b9 --- /dev/null +++ b/tests/rustdoc-ui/ice-blanket-impl-119792.rs @@ -0,0 +1,19 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/119792 + +struct Wrapper(T); + +trait Div {} +trait Mul { + type Output; +} + +impl Mul for Wrapper { + type Output = (); +} + +impl Div for Wrapper {} + +pub trait NumOps {} + +impl NumOps for T where T: Mul + Div {} diff --git a/tests/rustdoc-ui/invalid_associated_const.rs b/tests/rustdoc-ui/invalid_associated_const.rs index 6f211a383a6f..f93834268f63 100644 --- a/tests/rustdoc-ui/invalid_associated_const.rs +++ b/tests/rustdoc-ui/invalid_associated_const.rs @@ -2,8 +2,8 @@ trait T { type A: S = 34>; - //~^ ERROR associated type bindings are not allowed here - //~| ERROR associated type bindings are not allowed here + //~^ ERROR associated item constraints are not allowed here + //~| ERROR associated item constraints are not allowed here } trait S { diff --git a/tests/rustdoc-ui/invalid_associated_const.stderr b/tests/rustdoc-ui/invalid_associated_const.stderr index 5eaddc2b8c98..6e5ddc449828 100644 --- a/tests/rustdoc-ui/invalid_associated_const.stderr +++ b/tests/rustdoc-ui/invalid_associated_const.stderr @@ -1,22 +1,22 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/invalid_associated_const.rs:4:17 | LL | type A: S = 34>; - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = 34>; | ~~~~~~~~~~ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/invalid_associated_const.rs:4:17 | LL | type A: S = 34>; - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = 34>; | ~~~~~~~~~~ diff --git a/tests/rustdoc-ui/issue-102467.rs b/tests/rustdoc-ui/issue-102467.rs index a27e61569794..d9bd48103d24 100644 --- a/tests/rustdoc-ui/issue-102467.rs +++ b/tests/rustdoc-ui/issue-102467.rs @@ -5,8 +5,8 @@ trait T { type A: S = 34>; - //~^ ERROR associated type bindings are not allowed here - //~| ERROR associated type bindings are not allowed here + //~^ ERROR associated item constraints are not allowed here + //~| ERROR associated item constraints are not allowed here } trait S { diff --git a/tests/rustdoc-ui/issue-102467.stderr b/tests/rustdoc-ui/issue-102467.stderr index 119ca949e999..99f911023192 100644 --- a/tests/rustdoc-ui/issue-102467.stderr +++ b/tests/rustdoc-ui/issue-102467.stderr @@ -1,22 +1,22 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102467.rs:7:17 | LL | type A: S = 34>; - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = 34>; | ~~~~~~~~~~ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102467.rs:7:17 | LL | type A: S = 34>; - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = 34>; | ~~~~~~~~~~ diff --git a/tests/rustdoc-ui/issues/issue-91713.stdout b/tests/rustdoc-ui/issues/issue-91713.stdout index cc3c8385d9a8..1ea3dbfb59f3 100644 --- a/tests/rustdoc-ui/issues/issue-91713.stdout +++ b/tests/rustdoc-ui/issues/issue-91713.stdout @@ -1,5 +1,4 @@ Available passes for running rustdoc: -check-custom-code-classes - check for custom code classes without the feature-gate enabled check_doc_test_visibility - run various visibility-related lints on doctests strip-aliased-non-local - strips all non-local private aliased items from the output strip-hidden - strips all `#[doc(hidden)]` items from the output @@ -12,7 +11,6 @@ calculate-doc-coverage - counts the number of items with and without documentati run-lints - runs some of rustdoc's lints Default passes for rustdoc: -check-custom-code-classes collect-trait-impls check_doc_test_visibility strip-aliased-non-local diff --git a/tests/rustdoc-ui/unable-fulfill-trait.rs b/tests/rustdoc-ui/unable-fulfill-trait.rs index a69f74b09ac0..f3b6256346f0 100644 --- a/tests/rustdoc-ui/unable-fulfill-trait.rs +++ b/tests/rustdoc-ui/unable-fulfill-trait.rs @@ -1,13 +1,16 @@ // This test ensures that it's not crashing rustdoc. pub struct Foo<'a, 'b, T> { - field1: dyn Bar<'a, 'b,>, + field1: dyn Bar<'a, 'b>, //~^ ERROR //~| ERROR + //~| ERROR } pub trait Bar<'x, 's, U> - where U: 'x, - Self:'x, - Self:'s -{} +where + U: 'x, + Self: 'x, + Self: 's, +{ +} diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr index 72f35cb92244..40d103f2a62e 100644 --- a/tests/rustdoc-ui/unable-fulfill-trait.stderr +++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr @@ -1,26 +1,43 @@ error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/unable-fulfill-trait.rs:4:17 | -LL | field1: dyn Bar<'a, 'b,>, +LL | field1: dyn Bar<'a, 'b>, | ^^^ expected 1 generic argument | note: trait defined here, with 1 generic parameter: `U` - --> $DIR/unable-fulfill-trait.rs:9:11 + --> $DIR/unable-fulfill-trait.rs:10:11 | LL | pub trait Bar<'x, 's, U> | ^^^ - help: add missing generic argument | -LL | field1: dyn Bar<'a, 'b, U,>, +LL | field1: dyn Bar<'a, 'b, U>, | +++ error[E0227]: ambiguous lifetime bound, explicit lifetime bound required --> $DIR/unable-fulfill-trait.rs:4:13 | -LL | field1: dyn Bar<'a, 'b,>, - | ^^^^^^^^^^^^^^^^ +LL | field1: dyn Bar<'a, 'b>, + | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0478]: lifetime bound not satisfied + --> $DIR/unable-fulfill-trait.rs:4:13 + | +LL | field1: dyn Bar<'a, 'b>, + | ^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'b` as defined here + --> $DIR/unable-fulfill-trait.rs:3:20 + | +LL | pub struct Foo<'a, 'b, T> { + | ^^ +note: but lifetime parameter must outlive the lifetime `'a` as defined here + --> $DIR/unable-fulfill-trait.rs:3:16 + | +LL | pub struct Foo<'a, 'b, T> { + | ^^ -Some errors have detailed explanations: E0107, E0227. +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0227, E0478. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/rustdoc/custom_code_classes.rs b/tests/rustdoc/custom_code_classes.rs index cd20d8b7d6c9..569857a09cbe 100644 --- a/tests/rustdoc/custom_code_classes.rs +++ b/tests/rustdoc/custom_code_classes.rs @@ -1,6 +1,5 @@ // Test for `custom_code_classes_in_docs` feature. -#![feature(custom_code_classes_in_docs)] #![crate_name = "foo"] #![feature(no_core)] #![no_core] diff --git a/tests/ui-fulldeps/stable-mir/check_transform.rs b/tests/ui-fulldeps/stable-mir/check_transform.rs index 6345ee24f789..b203e76e54f4 100644 --- a/tests/ui-fulldeps/stable-mir/check_transform.rs +++ b/tests/ui-fulldeps/stable-mir/check_transform.rs @@ -22,7 +22,7 @@ use rustc_smir::rustc_internal; use stable_mir::mir::alloc::GlobalAlloc; use stable_mir::mir::mono::Instance; use stable_mir::mir::{Body, Constant, Operand, Rvalue, StatementKind, TerminatorKind}; -use stable_mir::ty::{Const, ConstantKind}; +use stable_mir::ty::{ConstantKind, MirConst}; use stable_mir::{CrateDef, CrateItems, ItemKind}; use std::convert::TryFrom; use std::io::Write; @@ -77,7 +77,7 @@ fn check_msg(body: &Body, expected: &str) { }; assert_eq!(alloc.provenance.ptrs.len(), 1); - let alloc_prov_id = alloc.provenance.ptrs[0].1 .0; + let alloc_prov_id = alloc.provenance.ptrs[0].1.0; let GlobalAlloc::Memory(val) = GlobalAlloc::from(alloc_prov_id) else { unreachable!() }; @@ -95,7 +95,7 @@ fn change_panic_msg(mut body: Body, new_msg: &str) -> Body { for bb in &mut body.blocks { match &mut bb.terminator.kind { TerminatorKind::Call { args, .. } => { - let new_const = Const::from_str(new_msg); + let new_const = MirConst::from_str(new_msg); args[0] = Operand::Constant(Constant { literal: new_const, span: bb.terminator.span, diff --git a/tests/ui/associated-consts/issue-102335-const.rs b/tests/ui/associated-consts/issue-102335-const.rs index 969c2c43b716..fd922cd0f1d8 100644 --- a/tests/ui/associated-consts/issue-102335-const.rs +++ b/tests/ui/associated-consts/issue-102335-const.rs @@ -2,8 +2,8 @@ trait T { type A: S = 34>; - //~^ ERROR associated type bindings are not allowed here - //~| ERROR associated type bindings are not allowed here + //~^ ERROR associated item constraints are not allowed here + //~| ERROR associated item constraints are not allowed here } trait S { diff --git a/tests/ui/associated-consts/issue-102335-const.stderr b/tests/ui/associated-consts/issue-102335-const.stderr index 905d7c75c200..dc1631220e2a 100644 --- a/tests/ui/associated-consts/issue-102335-const.stderr +++ b/tests/ui/associated-consts/issue-102335-const.stderr @@ -1,22 +1,22 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-const.rs:4:17 | LL | type A: S = 34>; - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = 34>; | ~~~~~~~~~~ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-const.rs:4:17 | LL | type A: S = 34>; - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = 34>; | ~~~~~~~~~~ diff --git a/tests/ui/associated-inherent-types/issue-109071.rs b/tests/ui/associated-inherent-types/issue-109071.rs index 29eef081a327..97803ae7191e 100644 --- a/tests/ui/associated-inherent-types/issue-109071.rs +++ b/tests/ui/associated-inherent-types/issue-109071.rs @@ -13,7 +13,7 @@ impl Windows { //~ ERROR: missing generics for struct `Windows` impl Windows { fn T() -> Option {} - //~^ ERROR: ambiguous associated type + //[no_gate]~^ ERROR: ambiguous associated type } fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-109071.with_gate.stderr b/tests/ui/associated-inherent-types/issue-109071.with_gate.stderr index a7d17e2d5ebb..1324cb9bb9b5 100644 --- a/tests/ui/associated-inherent-types/issue-109071.with_gate.stderr +++ b/tests/ui/associated-inherent-types/issue-109071.with_gate.stderr @@ -20,20 +20,7 @@ help: add missing generic argument LL | impl Windows { | +++ -error[E0223]: ambiguous associated type - --> $DIR/issue-109071.rs:15:22 - | -LL | fn T() -> Option {} - | ^^^^^^^^^^ - | -help: use fully-qualified syntax - | -LL | fn T() -> Option< as IntoAsyncIterator>::Item> {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LL | fn T() -> Option< as IntoIterator>::Item> {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +error: aborting due to 2 previous errors -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0107, E0223, E0637. +Some errors have detailed explanations: E0107, E0637. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/associated-inherent-types/issue-109299.rs b/tests/ui/associated-inherent-types/issue-109299.rs index b6c010c34e44..84e4f9e72527 100644 --- a/tests/ui/associated-inherent-types/issue-109299.rs +++ b/tests/ui/associated-inherent-types/issue-109299.rs @@ -8,6 +8,5 @@ impl Lexer<'d> { //~ ERROR use of undeclared lifetime name `'d` } fn test(_: Lexer::Cursor) {} -//~^ ERROR: lifetime may not live long enough fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-109299.stderr b/tests/ui/associated-inherent-types/issue-109299.stderr index f108a52b92c0..1e11c0e8c2af 100644 --- a/tests/ui/associated-inherent-types/issue-109299.stderr +++ b/tests/ui/associated-inherent-types/issue-109299.stderr @@ -6,15 +6,6 @@ LL | impl Lexer<'d> { | | | help: consider introducing lifetime `'d` here: `<'d>` -error: lifetime may not live long enough - --> $DIR/issue-109299.rs:10:1 - | -LL | fn test(_: Lexer::Cursor) {} - | ^^^^^^^^-^^^^^^^^^^^^^^^^ - | | | - | | has type `Lexer<'1>::Cursor` - | requires that `'1` must outlive `'static` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/associated-type-bounds/issue-102335-ty.rs b/tests/ui/associated-type-bounds/issue-102335-ty.rs index b2df68b18ae4..86bde6367a4c 100644 --- a/tests/ui/associated-type-bounds/issue-102335-ty.rs +++ b/tests/ui/associated-type-bounds/issue-102335-ty.rs @@ -1,13 +1,13 @@ trait T { type A: S = ()>; // Just one erroneous equality constraint - //~^ ERROR associated type bindings are not allowed here - //~| ERROR associated type bindings are not allowed here + //~^ ERROR associated item constraints are not allowed here + //~| ERROR associated item constraints are not allowed here } trait T2 { type A: S = ()>; // More than one erroneous equality constraints - //~^ ERROR associated type bindings are not allowed here - //~| ERROR associated type bindings are not allowed here + //~^ ERROR associated item constraints are not allowed here + //~| ERROR associated item constraints are not allowed here } trait Q {} diff --git a/tests/ui/associated-type-bounds/issue-102335-ty.stderr b/tests/ui/associated-type-bounds/issue-102335-ty.stderr index cf30b0a4f6ca..cd585f7f7d8f 100644 --- a/tests/ui/associated-type-bounds/issue-102335-ty.stderr +++ b/tests/ui/associated-type-bounds/issue-102335-ty.stderr @@ -1,45 +1,45 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-ty.rs:2:17 | LL | type A: S = ()>; // Just one erroneous equality constraint - | ^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = ()>; // Just one erroneous equality constraint | ~~~~~~~~~~~ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-ty.rs:2:17 | LL | type A: S = ()>; // Just one erroneous equality constraint - | ^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^ associated item constraint not allowed here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = ()>; // Just one erroneous equality constraint | ~~~~~~~~~~~ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-ty.rs:8:17 | LL | type A: S = ()>; // More than one erroneous equality constraints - | ^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = ()>; // More than one erroneous equality constraints | ~~~~~~~~~~ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-ty.rs:8:17 | LL | type A: S = ()>; // More than one erroneous equality constraints - | ^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^ associated item constraint not allowed here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = ()>; // More than one erroneous equality constraints | ~~~~~~~~~~ diff --git a/tests/ui/associated-type-bounds/no-gat-position.rs b/tests/ui/associated-type-bounds/no-gat-position.rs index 5005c5027f42..cb62c8824681 100644 --- a/tests/ui/associated-type-bounds/no-gat-position.rs +++ b/tests/ui/associated-type-bounds/no-gat-position.rs @@ -4,7 +4,7 @@ pub trait Iter { type Item<'a>: 'a where Self: 'a; fn next<'a>(&'a mut self) -> Option>; - //~^ ERROR associated type bindings are not allowed here + //~^ ERROR associated item constraints are not allowed here } impl Iter for () { diff --git a/tests/ui/associated-type-bounds/no-gat-position.stderr b/tests/ui/associated-type-bounds/no-gat-position.stderr index c348d33c3a9a..e167ac1fda45 100644 --- a/tests/ui/associated-type-bounds/no-gat-position.stderr +++ b/tests/ui/associated-type-bounds/no-gat-position.stderr @@ -1,8 +1,8 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/no-gat-position.rs:6:56 | LL | fn next<'a>(&'a mut self) -> Option>; - | ^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^ associated item constraint not allowed here error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/associated-types-eq-2.rs b/tests/ui/associated-types/associated-types-eq-2.rs index 43b0208461e4..f0a7d1e46b1b 100644 --- a/tests/ui/associated-types/associated-types-eq-2.rs +++ b/tests/ui/associated-types/associated-types-eq-2.rs @@ -18,14 +18,14 @@ impl Tr1 for isize { // Test for when the assoc type is // specified as an equality constraint impl Tr1 for usize { -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR not all trait items implemented, missing: `A` fn boo(&self) -> usize { 42 } } // Test for a wronngly used equality constraint in a func arg fn baz(_x: &>::A) {} -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here @@ -38,28 +38,28 @@ trait Tr2 { // (Note: E0229 is emitted only for the first erroneous equality // constraint (T2) not for any subequent ones (e.g. T3)) impl Tr2 for Bar { -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied } // Test for when equality constraint's ident matches a // generic param's ident but has different case impl Tr2 for Qux { -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied } // Test for when equality constraint's ident // matches none of the generic param idents impl Tr2 for Bar { -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied } // Test for when the term in equality constraint is itself generic struct GenericTerm { _t: T } impl Tr2> for Bar { -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR trait takes 3 generic arguments but 2 generic arguments were supplied } @@ -74,7 +74,7 @@ trait Tr3 { // (Deliberately spread over multiple lines to test that // our suggestion spans are kosher in the face of such formatting) impl Tr3 for Bar { @@ -83,7 +83,7 @@ impl Tr3 for Qux { -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR associated const equality is incomplete //~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied } @@ -91,14 +91,14 @@ impl Tr3 for Qux { // Test for when equality constraint's ident // matches the const param ident but the constraint is a type arg impl Tr3 for Bar { -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied } // Test for when equality constraint's ident // matches a type param ident but the constraint is a const arg impl Tr3<42, T2 = 42, T3 = usize> for Bar { -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR associated const equality is incomplete //~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied } @@ -106,7 +106,7 @@ impl Tr3<42, T2 = 42, T3 = usize> for Bar { // Test for when equality constraint's ident // matches none of the param idents impl Tr3 for Bar { -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR associated const equality is incomplete //~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied } @@ -117,7 +117,7 @@ impl Tr3 for Bar { struct St<'a, T> { v: &'a T } impl<'a, T> St<'a , T = Qux> { -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR struct takes 1 generic argument but 0 generic arguments were supplied } diff --git a/tests/ui/associated-types/associated-types-eq-2.stderr b/tests/ui/associated-types/associated-types-eq-2.stderr index b68c82f590c1..53e4e59128ea 100644 --- a/tests/ui/associated-types/associated-types-eq-2.stderr +++ b/tests/ui/associated-types/associated-types-eq-2.stderr @@ -43,13 +43,13 @@ LL | impl Tr3 for Bar { = help: add `#![feature(associated_const_equality)]` 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[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:20:10 | LL | impl Tr1 for usize { - | ^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | impl Tr1 for usize { | ~~~~~~~~~~~ @@ -63,13 +63,13 @@ LL | type A; LL | impl Tr1 for usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `A` in implementation -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:27:31 | LL | fn baz(_x: &>::A) {} - | ^^^^^ associated type not allowed here + | ^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | fn baz(_x: &>::A) {} | ~~~~~~~ @@ -92,11 +92,11 @@ help: add missing generic arguments LL | impl Tr2 for Bar { | ++++++++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:40:15 | LL | impl Tr2 for Bar { - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | help: to use `Qux` as a generic argument specify it directly | @@ -121,13 +121,13 @@ help: add missing generic arguments LL | impl Tr2 for Qux { | ++++++++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:47:15 | LL | impl Tr2 for Qux { - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | impl Tr2 for Qux { | ~~~~~~~~~~ @@ -150,13 +150,13 @@ help: add missing generic arguments LL | impl Tr2 for Bar { | ++++++++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:54:15 | LL | impl Tr2 for Bar { - | ^^^^^^^ associated type not allowed here + | ^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | impl Tr2 for Bar { | ~~~~~~~~~ @@ -179,11 +179,11 @@ help: add missing generic argument LL | impl Tr2> for Bar { | ++++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:61:20 | LL | impl Tr2> for Bar { - | ^^^^^^^^^^^^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^^^^^^^^^^^^ associated item constraint not allowed here | help: to use `GenericTerm` as a generic argument specify it directly | @@ -206,7 +206,7 @@ help: add missing generic arguments LL | impl Tr3 $DIR/associated-types-eq-2.rs:76:10 | LL | impl Tr3 for Bar { - | |____^ associated type not allowed here + | |____^ associated item constraint not allowed here | help: to use `42` as a generic argument specify it directly | @@ -238,13 +238,13 @@ help: add missing generic arguments LL | impl Tr3 for Qux { | ++++++++++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:85:10 | LL | impl Tr3 for Qux { - | ^^^^^^ associated type not allowed here + | ^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | impl Tr3 for Qux { | ~~~~~~~ @@ -265,13 +265,13 @@ help: add missing generic arguments LL | impl Tr3 for Bar { | ++++++++++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:93:10 | LL | impl Tr3 for Bar { - | ^^^^^^^ associated type not allowed here + | ^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | impl Tr3 for Bar { | ~~~~~~~~ @@ -294,13 +294,13 @@ help: add missing generic arguments LL | impl Tr3<42, T2, T3, T2 = 42, T3 = usize> for Bar { | ++++++++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:100:14 | LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { - | ^^^^^^^ associated type not allowed here + | ^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { | ~~~~~~~~~ @@ -321,13 +321,13 @@ help: add missing generic arguments LL | impl Tr3 for Bar { | ++++++++++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:108:10 | LL | impl Tr3 for Bar { - | ^^^^^^ associated type not allowed here + | ^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | impl Tr3 for Bar { | ~~~~~~~ @@ -348,11 +348,11 @@ help: add missing generic argument LL | impl<'a, T> St<'a, T , T = Qux> { | +++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:119:21 | LL | impl<'a, T> St<'a , T = Qux> { - | ^^^^^^^ associated type not allowed here + | ^^^^^^^ associated item constraint not allowed here | help: to use `Qux` as a generic argument specify it directly | diff --git a/tests/ui/associated-types/associated-types-eq-expr-path.rs b/tests/ui/associated-types/associated-types-eq-expr-path.rs index 143992f29f19..4561e596c665 100644 --- a/tests/ui/associated-types/associated-types-eq-expr-path.rs +++ b/tests/ui/associated-types/associated-types-eq-expr-path.rs @@ -11,6 +11,6 @@ impl Foo for isize { } pub fn main() { - let x: isize = Foo::::bar(); - //~^ ERROR associated type bindings are not allowed here + let x: isize = Foo::::bar(); + //~^ ERROR associated item constraints are not allowed here } diff --git a/tests/ui/associated-types/associated-types-eq-expr-path.stderr b/tests/ui/associated-types/associated-types-eq-expr-path.stderr index 7559f3b7c2e5..3d0e3e61eca9 100644 --- a/tests/ui/associated-types/associated-types-eq-expr-path.stderr +++ b/tests/ui/associated-types/associated-types-eq-expr-path.stderr @@ -1,8 +1,8 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-expr-path.rs:14:26 | -LL | let x: isize = Foo::::bar(); - | ^^^^^^^ associated type not allowed here +LL | let x: isize = Foo::::bar(); + | ^^^^^^^^^ associated item constraint not allowed here error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/defaults-suitability.stderr b/tests/ui/associated-types/defaults-suitability.current.stderr similarity index 88% rename from tests/ui/associated-types/defaults-suitability.stderr rename to tests/ui/associated-types/defaults-suitability.current.stderr index 82b35a486378..3cdeaa93a340 100644 --- a/tests/ui/associated-types/defaults-suitability.stderr +++ b/tests/ui/associated-types/defaults-suitability.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `NotClone: Clone` is not satisfied - --> $DIR/defaults-suitability.rs:13:22 + --> $DIR/defaults-suitability.rs:16:22 | LL | type Ty: Clone = NotClone; | ^^^^^^^^ the trait `Clone` is not implemented for `NotClone` | note: required by a bound in `Tr::Ty` - --> $DIR/defaults-suitability.rs:13:14 + --> $DIR/defaults-suitability.rs:16:14 | LL | type Ty: Clone = NotClone; | ^^^^^ required by this bound in `Tr::Ty` @@ -16,13 +16,13 @@ LL | struct NotClone; | error[E0277]: the trait bound `NotClone: Clone` is not satisfied - --> $DIR/defaults-suitability.rs:22:15 + --> $DIR/defaults-suitability.rs:25:15 | LL | type Ty = NotClone; | ^^^^^^^^ the trait `Clone` is not implemented for `NotClone` | note: required by a bound in `Tr2::Ty` - --> $DIR/defaults-suitability.rs:20:15 + --> $DIR/defaults-suitability.rs:23:15 | LL | Self::Ty: Clone, | ^^^^^ required by this bound in `Tr2::Ty` @@ -36,14 +36,14 @@ LL | struct NotClone; | error[E0277]: the trait bound `T: Clone` is not satisfied - --> $DIR/defaults-suitability.rs:28:23 + --> $DIR/defaults-suitability.rs:31:23 | LL | type Bar: Clone = Vec; | ^^^^^^ the trait `Clone` is not implemented for `T`, which is required by `Vec: Clone` | = note: required for `Vec` to implement `Clone` note: required by a bound in `Foo::Bar` - --> $DIR/defaults-suitability.rs:28:15 + --> $DIR/defaults-suitability.rs:31:15 | LL | type Bar: Clone = Vec; | ^^^^^ required by this bound in `Foo::Bar` @@ -53,30 +53,30 @@ LL | trait Foo { | +++++++++++++++++++ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/defaults-suitability.rs:34:29 + --> $DIR/defaults-suitability.rs:37:29 | LL | type Assoc: Foo = (); | ^^ the trait `Foo` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/defaults-suitability.rs:27:1 + --> $DIR/defaults-suitability.rs:30:1 | LL | trait Foo { | ^^^^^^^^^^^^ note: required by a bound in `Bar::Assoc` - --> $DIR/defaults-suitability.rs:34:17 + --> $DIR/defaults-suitability.rs:37:17 | LL | type Assoc: Foo = (); | ^^^^^^^^^ required by this bound in `Bar::Assoc` error[E0277]: the trait bound `NotClone: IsU8` is not satisfied - --> $DIR/defaults-suitability.rs:56:18 + --> $DIR/defaults-suitability.rs:59:18 | LL | type Assoc = NotClone; | ^^^^^^^^ the trait `IsU8` is not implemented for `NotClone` | note: required by a bound in `D::Assoc` - --> $DIR/defaults-suitability.rs:53:18 + --> $DIR/defaults-suitability.rs:56:18 | LL | Self::Assoc: IsU8, | ^^^^^^^^^^^^^^^^^ required by this bound in `D::Assoc` @@ -85,14 +85,14 @@ LL | type Assoc = NotClone; | ----- required by a bound in this associated type error[E0277]: the trait bound `>::Baz: Clone` is not satisfied - --> $DIR/defaults-suitability.rs:65:23 + --> $DIR/defaults-suitability.rs:68:23 | LL | type Bar: Clone = Vec; | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `>::Baz`, which is required by `Vec<>::Baz>: Clone` | = note: required for `Vec<>::Baz>` to implement `Clone` note: required by a bound in `Foo2::Bar` - --> $DIR/defaults-suitability.rs:65:15 + --> $DIR/defaults-suitability.rs:68:15 | LL | type Bar: Clone = Vec; | ^^^^^ required by this bound in `Foo2::Bar` @@ -102,14 +102,14 @@ LL | trait Foo2 where >::Baz: Clone { | +++++++++++++++++++++++++++++++++++ error[E0277]: the trait bound `>::Baz: Clone` is not satisfied - --> $DIR/defaults-suitability.rs:74:23 + --> $DIR/defaults-suitability.rs:77:23 | LL | type Bar: Clone = Vec; | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `>::Baz`, which is required by `Vec<>::Baz>: Clone` | = note: required for `Vec<>::Baz>` to implement `Clone` note: required by a bound in `Foo25::Bar` - --> $DIR/defaults-suitability.rs:74:15 + --> $DIR/defaults-suitability.rs:77:15 | LL | type Bar: Clone = Vec; | ^^^^^ required by this bound in `Foo25::Bar` @@ -119,13 +119,13 @@ LL | trait Foo25 where >::Baz: Clone { | ++++++++++++++++++++++++++++++++++++ error[E0277]: the trait bound `T: Clone` is not satisfied - --> $DIR/defaults-suitability.rs:87:16 + --> $DIR/defaults-suitability.rs:90:16 | LL | type Baz = T; | ^ the trait `Clone` is not implemented for `T` | note: required by a bound in `Foo3::Baz` - --> $DIR/defaults-suitability.rs:84:16 + --> $DIR/defaults-suitability.rs:87:16 | LL | Self::Baz: Clone, | ^^^^^ required by this bound in `Foo3::Baz` diff --git a/tests/ui/associated-types/defaults-suitability.next.stderr b/tests/ui/associated-types/defaults-suitability.next.stderr new file mode 100644 index 000000000000..3cdeaa93a340 --- /dev/null +++ b/tests/ui/associated-types/defaults-suitability.next.stderr @@ -0,0 +1,142 @@ +error[E0277]: the trait bound `NotClone: Clone` is not satisfied + --> $DIR/defaults-suitability.rs:16:22 + | +LL | type Ty: Clone = NotClone; + | ^^^^^^^^ the trait `Clone` is not implemented for `NotClone` + | +note: required by a bound in `Tr::Ty` + --> $DIR/defaults-suitability.rs:16:14 + | +LL | type Ty: Clone = NotClone; + | ^^^^^ required by this bound in `Tr::Ty` +help: consider annotating `NotClone` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct NotClone; + | + +error[E0277]: the trait bound `NotClone: Clone` is not satisfied + --> $DIR/defaults-suitability.rs:25:15 + | +LL | type Ty = NotClone; + | ^^^^^^^^ the trait `Clone` is not implemented for `NotClone` + | +note: required by a bound in `Tr2::Ty` + --> $DIR/defaults-suitability.rs:23:15 + | +LL | Self::Ty: Clone, + | ^^^^^ required by this bound in `Tr2::Ty` +LL | { +LL | type Ty = NotClone; + | -- required by a bound in this associated type +help: consider annotating `NotClone` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct NotClone; + | + +error[E0277]: the trait bound `T: Clone` is not satisfied + --> $DIR/defaults-suitability.rs:31:23 + | +LL | type Bar: Clone = Vec; + | ^^^^^^ the trait `Clone` is not implemented for `T`, which is required by `Vec: Clone` + | + = note: required for `Vec` to implement `Clone` +note: required by a bound in `Foo::Bar` + --> $DIR/defaults-suitability.rs:31:15 + | +LL | type Bar: Clone = Vec; + | ^^^^^ required by this bound in `Foo::Bar` +help: consider restricting type parameter `T` + | +LL | trait Foo { + | +++++++++++++++++++ + +error[E0277]: the trait bound `(): Foo` is not satisfied + --> $DIR/defaults-suitability.rs:37:29 + | +LL | type Assoc: Foo = (); + | ^^ the trait `Foo` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/defaults-suitability.rs:30:1 + | +LL | trait Foo { + | ^^^^^^^^^^^^ +note: required by a bound in `Bar::Assoc` + --> $DIR/defaults-suitability.rs:37:17 + | +LL | type Assoc: Foo = (); + | ^^^^^^^^^ required by this bound in `Bar::Assoc` + +error[E0277]: the trait bound `NotClone: IsU8` is not satisfied + --> $DIR/defaults-suitability.rs:59:18 + | +LL | type Assoc = NotClone; + | ^^^^^^^^ the trait `IsU8` is not implemented for `NotClone` + | +note: required by a bound in `D::Assoc` + --> $DIR/defaults-suitability.rs:56:18 + | +LL | Self::Assoc: IsU8, + | ^^^^^^^^^^^^^^^^^ required by this bound in `D::Assoc` +... +LL | type Assoc = NotClone; + | ----- required by a bound in this associated type + +error[E0277]: the trait bound `>::Baz: Clone` is not satisfied + --> $DIR/defaults-suitability.rs:68:23 + | +LL | type Bar: Clone = Vec; + | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `>::Baz`, which is required by `Vec<>::Baz>: Clone` + | + = note: required for `Vec<>::Baz>` to implement `Clone` +note: required by a bound in `Foo2::Bar` + --> $DIR/defaults-suitability.rs:68:15 + | +LL | type Bar: Clone = Vec; + | ^^^^^ required by this bound in `Foo2::Bar` +help: consider further restricting the associated type + | +LL | trait Foo2 where >::Baz: Clone { + | +++++++++++++++++++++++++++++++++++ + +error[E0277]: the trait bound `>::Baz: Clone` is not satisfied + --> $DIR/defaults-suitability.rs:77:23 + | +LL | type Bar: Clone = Vec; + | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `>::Baz`, which is required by `Vec<>::Baz>: Clone` + | + = note: required for `Vec<>::Baz>` to implement `Clone` +note: required by a bound in `Foo25::Bar` + --> $DIR/defaults-suitability.rs:77:15 + | +LL | type Bar: Clone = Vec; + | ^^^^^ required by this bound in `Foo25::Bar` +help: consider further restricting the associated type + | +LL | trait Foo25 where >::Baz: Clone { + | ++++++++++++++++++++++++++++++++++++ + +error[E0277]: the trait bound `T: Clone` is not satisfied + --> $DIR/defaults-suitability.rs:90:16 + | +LL | type Baz = T; + | ^ the trait `Clone` is not implemented for `T` + | +note: required by a bound in `Foo3::Baz` + --> $DIR/defaults-suitability.rs:87:16 + | +LL | Self::Baz: Clone, + | ^^^^^ required by this bound in `Foo3::Baz` +... +LL | type Baz = T; + | --- required by a bound in this associated type +help: consider further restricting type parameter `T` + | +LL | Self::Baz: Clone, T: std::clone::Clone + | ~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/defaults-suitability.rs b/tests/ui/associated-types/defaults-suitability.rs index 504c957d9875..bab2f004ac75 100644 --- a/tests/ui/associated-types/defaults-suitability.rs +++ b/tests/ui/associated-types/defaults-suitability.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver //! Checks that associated type defaults are properly validated. //! //! This means: diff --git a/tests/ui/associated-types/defaults-unsound-62211-1.current.stderr b/tests/ui/associated-types/defaults-unsound-62211-1.current.stderr index 9d52e923aded..8b6f0a47aed9 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-1.current.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-1.current.stderr @@ -1,12 +1,12 @@ error[E0277]: `Self` doesn't implement `std::fmt::Display` - --> $DIR/defaults-unsound-62211-1.rs:26:96 + --> $DIR/defaults-unsound-62211-1.rs:24:96 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^ `Self` cannot be formatted with the default formatter | = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-1.rs:26:86 + --> $DIR/defaults-unsound-62211-1.rs:24:86 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^^^^ required by this bound in `UncheckedCopy::Output` @@ -16,13 +16,13 @@ LL | trait UncheckedCopy: Sized + std::fmt::Display { | +++++++++++++++++++ error[E0277]: cannot add-assign `&'static str` to `Self` - --> $DIR/defaults-unsound-62211-1.rs:26:96 + --> $DIR/defaults-unsound-62211-1.rs:24:96 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^ no implementation for `Self += &'static str` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-1.rs:26:47 + --> $DIR/defaults-unsound-62211-1.rs:24:47 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` @@ -32,13 +32,13 @@ LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { | +++++++++++++++++++++++++ error[E0277]: the trait bound `Self: Deref` is not satisfied - --> $DIR/defaults-unsound-62211-1.rs:26:96 + --> $DIR/defaults-unsound-62211-1.rs:24:96 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^ the trait `Deref` is not implemented for `Self` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-1.rs:26:25 + --> $DIR/defaults-unsound-62211-1.rs:24:25 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` @@ -48,13 +48,13 @@ LL | trait UncheckedCopy: Sized + Deref { | +++++++ error[E0277]: the trait bound `Self: Copy` is not satisfied - --> $DIR/defaults-unsound-62211-1.rs:26:96 + --> $DIR/defaults-unsound-62211-1.rs:24:96 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^ the trait `Copy` is not implemented for `Self` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-1.rs:26:18 + --> $DIR/defaults-unsound-62211-1.rs:24:18 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^ required by this bound in `UncheckedCopy::Output` diff --git a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr index ffb02eccc77d..0fc1bb0b00f3 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr @@ -1,17 +1,81 @@ -warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing - --> $DIR/defaults-unsound-62211-1.rs:52:5 +error[E0277]: `Self` doesn't implement `std::fmt::Display` + --> $DIR/defaults-unsound-62211-1.rs:24:96 | -LL | drop(origin); - | ^^^^^------^ - | | - | argument has type `::Output` +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ `Self` cannot be formatted with the default formatter | - = note: `#[warn(dropping_copy_types)]` on by default -help: use `let _ = ...` to ignore the expression or result + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-1.rs:24:86 | -LL - drop(origin); -LL + let _ = origin; +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^ required by this bound in `UncheckedCopy::Output` +help: consider further restricting `Self` | +LL | trait UncheckedCopy: Sized + std::fmt::Display { + | +++++++++++++++++++ -warning: 1 warning emitted +error[E0277]: cannot add-assign `&'static str` to `Self` + --> $DIR/defaults-unsound-62211-1.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ no implementation for `Self += &'static str` + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-1.rs:24:47 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { + | +++++++++++++++++++++++++ +error[E0271]: type mismatch resolving `::Target == str` + --> $DIR/defaults-unsound-62211-1.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ types differ + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-1.rs:24:31 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + +error[E0277]: the trait bound `Self: Deref` is not satisfied + --> $DIR/defaults-unsound-62211-1.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ the trait `Deref` is not implemented for `Self` + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-1.rs:24:25 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + Deref { + | +++++++ + +error[E0277]: the trait bound `Self: Copy` is not satisfied + --> $DIR/defaults-unsound-62211-1.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ the trait `Copy` is not implemented for `Self` + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-1.rs:24:18 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ required by this bound in `UncheckedCopy::Output` +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + Copy { + | ++++++ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/defaults-unsound-62211-1.rs b/tests/ui/associated-types/defaults-unsound-62211-1.rs index d9cf5aa97acd..f054611ed780 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-1.rs +++ b/tests/ui/associated-types/defaults-unsound-62211-1.rs @@ -1,8 +1,6 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver //@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] known-bug: rust-lang/trait-system-refactor-initiative#46 -//@[next] check-pass //! Regression test for https://github.com/rust-lang/rust/issues/62211 //! @@ -24,10 +22,11 @@ trait UncheckedCopy: Sized { // This Output is said to be Copy. Yet we default to Self // and it's accepted, not knowing if Self ineed is Copy type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - //[current]~^ ERROR the trait bound `Self: Copy` is not satisfied - //[current]~| ERROR the trait bound `Self: Deref` is not satisfied - //[current]~| ERROR cannot add-assign `&'static str` to `Self` - //[current]~| ERROR `Self` doesn't implement `std::fmt::Display` + //~^ ERROR the trait bound `Self: Copy` is not satisfied + //~| ERROR the trait bound `Self: Deref` is not satisfied + //~| ERROR cannot add-assign `&'static str` to `Self` + //~| ERROR `Self` doesn't implement `std::fmt::Display` + //[next]~| ERROR type mismatch resolving `::Target == str` // We said the Output type was Copy, so we can Copy it freely! fn unchecked_copy(other: &Self::Output) -> Self::Output { diff --git a/tests/ui/associated-types/defaults-unsound-62211-2.current.stderr b/tests/ui/associated-types/defaults-unsound-62211-2.current.stderr index 4fd2ca6408a1..7552b0891333 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-2.current.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-2.current.stderr @@ -1,12 +1,12 @@ error[E0277]: `Self` doesn't implement `std::fmt::Display` - --> $DIR/defaults-unsound-62211-2.rs:26:96 + --> $DIR/defaults-unsound-62211-2.rs:24:96 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^ `Self` cannot be formatted with the default formatter | = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-2.rs:26:86 + --> $DIR/defaults-unsound-62211-2.rs:24:86 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^^^^ required by this bound in `UncheckedCopy::Output` @@ -16,13 +16,13 @@ LL | trait UncheckedCopy: Sized + std::fmt::Display { | +++++++++++++++++++ error[E0277]: cannot add-assign `&'static str` to `Self` - --> $DIR/defaults-unsound-62211-2.rs:26:96 + --> $DIR/defaults-unsound-62211-2.rs:24:96 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^ no implementation for `Self += &'static str` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-2.rs:26:47 + --> $DIR/defaults-unsound-62211-2.rs:24:47 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` @@ -32,13 +32,13 @@ LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { | +++++++++++++++++++++++++ error[E0277]: the trait bound `Self: Deref` is not satisfied - --> $DIR/defaults-unsound-62211-2.rs:26:96 + --> $DIR/defaults-unsound-62211-2.rs:24:96 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^ the trait `Deref` is not implemented for `Self` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-2.rs:26:25 + --> $DIR/defaults-unsound-62211-2.rs:24:25 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` @@ -48,13 +48,13 @@ LL | trait UncheckedCopy: Sized + Deref { | +++++++ error[E0277]: the trait bound `Self: Copy` is not satisfied - --> $DIR/defaults-unsound-62211-2.rs:26:96 + --> $DIR/defaults-unsound-62211-2.rs:24:96 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^ the trait `Copy` is not implemented for `Self` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-2.rs:26:18 + --> $DIR/defaults-unsound-62211-2.rs:24:18 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; | ^^^^ required by this bound in `UncheckedCopy::Output` diff --git a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr index e6ae8183e77d..751352d7c16d 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr @@ -1,17 +1,81 @@ -warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing - --> $DIR/defaults-unsound-62211-2.rs:52:5 +error[E0277]: `Self` doesn't implement `std::fmt::Display` + --> $DIR/defaults-unsound-62211-2.rs:24:96 | -LL | drop(origin); - | ^^^^^------^ - | | - | argument has type `::Output` +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ `Self` cannot be formatted with the default formatter | - = note: `#[warn(dropping_copy_types)]` on by default -help: use `let _ = ...` to ignore the expression or result + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-2.rs:24:86 | -LL - drop(origin); -LL + let _ = origin; +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^ required by this bound in `UncheckedCopy::Output` +help: consider further restricting `Self` | +LL | trait UncheckedCopy: Sized + std::fmt::Display { + | +++++++++++++++++++ -warning: 1 warning emitted +error[E0277]: cannot add-assign `&'static str` to `Self` + --> $DIR/defaults-unsound-62211-2.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ no implementation for `Self += &'static str` + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-2.rs:24:47 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { + | +++++++++++++++++++++++++ +error[E0271]: type mismatch resolving `::Target == str` + --> $DIR/defaults-unsound-62211-2.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ types differ + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-2.rs:24:31 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + +error[E0277]: the trait bound `Self: Deref` is not satisfied + --> $DIR/defaults-unsound-62211-2.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ the trait `Deref` is not implemented for `Self` + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-2.rs:24:25 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + Deref { + | +++++++ + +error[E0277]: the trait bound `Self: Copy` is not satisfied + --> $DIR/defaults-unsound-62211-2.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ the trait `Copy` is not implemented for `Self` + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-2.rs:24:18 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ required by this bound in `UncheckedCopy::Output` +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + Copy { + | ++++++ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/defaults-unsound-62211-2.rs b/tests/ui/associated-types/defaults-unsound-62211-2.rs index 6cbac1bf2364..956f14df0d54 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-2.rs +++ b/tests/ui/associated-types/defaults-unsound-62211-2.rs @@ -1,8 +1,6 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver //@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] known-bug: rust-lang/trait-system-refactor-initiative#46 -//@[next] check-pass //! Regression test for https://github.com/rust-lang/rust/issues/62211 //! @@ -24,10 +22,11 @@ trait UncheckedCopy: Sized { // This Output is said to be Copy. Yet we default to Self // and it's accepted, not knowing if Self ineed is Copy type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - //[current]~^ ERROR the trait bound `Self: Copy` is not satisfied - //[current]~| ERROR the trait bound `Self: Deref` is not satisfied - //[current]~| ERROR cannot add-assign `&'static str` to `Self` - //[current]~| ERROR `Self` doesn't implement `std::fmt::Display` + //~^ ERROR the trait bound `Self: Copy` is not satisfied + //~| ERROR the trait bound `Self: Deref` is not satisfied + //~| ERROR cannot add-assign `&'static str` to `Self` + //~| ERROR `Self` doesn't implement `std::fmt::Display` + //[next]~| ERROR type mismatch resolving `::Target == str` // We said the Output type was Copy, so we can Copy it freely! fn unchecked_copy(other: &Self::Output) -> Self::Output { diff --git a/tests/ui/associated-types/issue-54108.stderr b/tests/ui/associated-types/issue-54108.current.stderr similarity index 93% rename from tests/ui/associated-types/issue-54108.stderr rename to tests/ui/associated-types/issue-54108.current.stderr index f300208fcc87..8850b4548e33 100644 --- a/tests/ui/associated-types/issue-54108.stderr +++ b/tests/ui/associated-types/issue-54108.current.stderr @@ -1,12 +1,12 @@ error[E0277]: cannot add `::ActualSize` to `::ActualSize` - --> $DIR/issue-54108.rs:19:17 + --> $DIR/issue-54108.rs:23:17 | LL | type Size = ::ActualSize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `::ActualSize + ::ActualSize` | = help: the trait `Add` is not implemented for `::ActualSize` note: required by a bound in `Encoder::Size` - --> $DIR/issue-54108.rs:4:16 + --> $DIR/issue-54108.rs:8:16 | LL | type Size: Add; | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` diff --git a/tests/ui/associated-types/issue-54108.next.stderr b/tests/ui/associated-types/issue-54108.next.stderr new file mode 100644 index 000000000000..9f6f00e7ca8f --- /dev/null +++ b/tests/ui/associated-types/issue-54108.next.stderr @@ -0,0 +1,33 @@ +error[E0271]: type mismatch resolving `<::ActualSize as Add>::Output == ::ActualSize` + --> $DIR/issue-54108.rs:23:17 + | +LL | type Size = ::ActualSize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | +note: required by a bound in `Encoder::Size` + --> $DIR/issue-54108.rs:8:20 + | +LL | type Size: Add; + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` + +error[E0277]: cannot add `::ActualSize` to `::ActualSize` + --> $DIR/issue-54108.rs:23:17 + | +LL | type Size = ::ActualSize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `::ActualSize + ::ActualSize` + | + = help: the trait `Add` is not implemented for `::ActualSize` +note: required by a bound in `Encoder::Size` + --> $DIR/issue-54108.rs:8:16 + | +LL | type Size: Add; + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` +help: consider further restricting the associated type + | +LL | T: SubEncoder, ::ActualSize: Add + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/issue-54108.rs b/tests/ui/associated-types/issue-54108.rs index 87f67ce4b527..7c652fd7f49b 100644 --- a/tests/ui/associated-types/issue-54108.rs +++ b/tests/ui/associated-types/issue-54108.rs @@ -1,3 +1,7 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + use std::ops::Add; pub trait Encoder { @@ -18,6 +22,7 @@ where { type Size = ::ActualSize; //~^ ERROR: cannot add `::ActualSize` to `::ActualSize` + //[next]~| ERROR type mismatch resolving `<::ActualSize as Add>::Output == ::ActualSize` fn foo(&self) -> Self::Size { self.bar() + self.bar() diff --git a/tests/ui/associated-types/issue-63593.stderr b/tests/ui/associated-types/issue-63593.current.stderr similarity index 89% rename from tests/ui/associated-types/issue-63593.stderr rename to tests/ui/associated-types/issue-63593.current.stderr index 67151431a67a..76fdefeb4e52 100644 --- a/tests/ui/associated-types/issue-63593.stderr +++ b/tests/ui/associated-types/issue-63593.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-63593.rs:9:17 + --> $DIR/issue-63593.rs:13:17 | LL | type This = Self; | ^^^^ doesn't have a size known at compile-time | note: required by a bound in `MyTrait::This` - --> $DIR/issue-63593.rs:9:5 + --> $DIR/issue-63593.rs:13:5 | LL | type This = Self; | ^^^^^^^^^^^^^^^^^ required by this bound in `MyTrait::This` diff --git a/tests/ui/associated-types/issue-63593.next.stderr b/tests/ui/associated-types/issue-63593.next.stderr new file mode 100644 index 000000000000..76fdefeb4e52 --- /dev/null +++ b/tests/ui/associated-types/issue-63593.next.stderr @@ -0,0 +1,19 @@ +error[E0277]: the size for values of type `Self` cannot be known at compilation time + --> $DIR/issue-63593.rs:13:17 + | +LL | type This = Self; + | ^^^^ doesn't have a size known at compile-time + | +note: required by a bound in `MyTrait::This` + --> $DIR/issue-63593.rs:13:5 + | +LL | type This = Self; + | ^^^^^^^^^^^^^^^^^ required by this bound in `MyTrait::This` +help: consider further restricting `Self` + | +LL | trait MyTrait: Sized { + | +++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/issue-63593.rs b/tests/ui/associated-types/issue-63593.rs index 8dbc24c06732..dea81f729b4e 100644 --- a/tests/ui/associated-types/issue-63593.rs +++ b/tests/ui/associated-types/issue-63593.rs @@ -1,3 +1,7 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + #![feature(associated_type_defaults)] // Tests that `Self` is not assumed to implement `Sized` when used as an diff --git a/tests/ui/async-await/async-drop.rs b/tests/ui/async-await/async-drop.rs index 6d02dcebc0b6..12f120a0b121 100644 --- a/tests/ui/async-await/async-drop.rs +++ b/tests/ui/async-await/async-drop.rs @@ -1,6 +1,10 @@ //@ run-pass //@ check-run-results +// WARNING: If you would ever want to modify this test, +// please consider modifying miri's async drop test at +// `src/tools/miri/tests/pass/async-drop.rs`. + #![feature(async_drop, impl_trait_in_assoc_type, noop_waker, async_closure)] #![allow(incomplete_features, dead_code)] @@ -13,9 +17,21 @@ use core::mem::{self, ManuallyDrop}; use core::pin::{pin, Pin}; use core::task::{Context, Poll, Waker}; -async fn test_async_drop(x: T) { +async fn test_async_drop(x: T, _size: usize) { let mut x = mem::MaybeUninit::new(x); let dtor = pin!(unsafe { async_drop_in_place(x.as_mut_ptr()) }); + + // FIXME(zetanumbers): This check fully depends on the layout of + // the coroutine state, since async destructor combinators are just + // async functions. + #[cfg(target_pointer_width = "64")] + assert_eq!( + mem::size_of_val(&*dtor), + _size, + "sizes did not match for async destructor of type {}", + core::any::type_name::(), + ); + test_idempotency(dtor).await; } @@ -36,51 +52,58 @@ fn main() { let i = 13; let fut = pin!(async { - test_async_drop(Int(0)).await; - test_async_drop(AsyncInt(0)).await; - test_async_drop([AsyncInt(1), AsyncInt(2)]).await; - test_async_drop((AsyncInt(3), AsyncInt(4))).await; - test_async_drop(5).await; + test_async_drop(Int(0), 0).await; + test_async_drop(AsyncInt(0), 104).await; + test_async_drop([AsyncInt(1), AsyncInt(2)], 152).await; + test_async_drop((AsyncInt(3), AsyncInt(4)), 488).await; + test_async_drop(5, 0).await; let j = 42; - test_async_drop(&i).await; - test_async_drop(&j).await; - test_async_drop(AsyncStruct { b: AsyncInt(8), a: AsyncInt(7), i: 6 }).await; - test_async_drop(ManuallyDrop::new(AsyncInt(9))).await; + test_async_drop(&i, 0).await; + test_async_drop(&j, 0).await; + test_async_drop(AsyncStruct { b: AsyncInt(8), a: AsyncInt(7), i: 6 }, 1688).await; + test_async_drop(ManuallyDrop::new(AsyncInt(9)), 0).await; let foo = AsyncInt(10); - test_async_drop(AsyncReference { foo: &foo }).await; + test_async_drop(AsyncReference { foo: &foo }, 104).await; let foo = AsyncInt(11); - test_async_drop(|| { - black_box(foo); - let foo = AsyncInt(10); - foo - }).await; + test_async_drop( + || { + black_box(foo); + let foo = AsyncInt(10); + foo + }, + 120, + ) + .await; - test_async_drop(AsyncEnum::A(AsyncInt(12))).await; - test_async_drop(AsyncEnum::B(SyncInt(13))).await; + test_async_drop(AsyncEnum::A(AsyncInt(12)), 680).await; + test_async_drop(AsyncEnum::B(SyncInt(13)), 680).await; - test_async_drop(SyncInt(14)).await; - test_async_drop(SyncThenAsync { - i: 15, - a: AsyncInt(16), - b: SyncInt(17), - c: AsyncInt(18), - }).await; + test_async_drop(SyncInt(14), 16).await; + test_async_drop( + SyncThenAsync { i: 15, a: AsyncInt(16), b: SyncInt(17), c: AsyncInt(18) }, + 3064, + ) + .await; let async_drop_fut = pin!(core::future::async_drop(AsyncInt(19))); test_idempotency(async_drop_fut).await; let foo = AsyncInt(20); - test_async_drop(async || { - black_box(foo); - let foo = AsyncInt(19); - // Await point there, but this is async closure so it's fine - black_box(core::future::ready(())).await; - foo - }).await; + test_async_drop( + async || { + black_box(foo); + let foo = AsyncInt(19); + // Await point there, but this is async closure so it's fine + black_box(core::future::ready(())).await; + foo + }, + 120, + ) + .await; - test_async_drop(AsyncUnion { signed: 21 }).await; + test_async_drop(AsyncUnion { signed: 21 }, 32).await; }); let res = fut.poll(&mut cx); assert_eq!(res, Poll::Ready(())); diff --git a/tests/ui/async-await/async-fn/impl-header.stderr b/tests/ui/async-await/async-fn/impl-header.stderr index 2fb862af04e4..64a98aab17b2 100644 --- a/tests/ui/async-await/async-fn/impl-header.stderr +++ b/tests/ui/async-await/async-fn/impl-header.stderr @@ -28,7 +28,7 @@ error[E0277]: expected a `FnMut()` closure, found `F` LL | impl async Fn<()> for F {} | ^ expected an `FnMut()` closure, found `F` | - = help: the trait `FnMut<()>` is not implemented for `F` + = help: the trait `FnMut()` is not implemented for `F` = note: wrap the `F` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs index 68a750778ada..637678692bd1 100644 --- a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs +++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs @@ -8,7 +8,7 @@ trait Super1<'a> { } impl Super1<'_, bar(): Send> for () {} -//~^ ERROR associated type bindings are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR not all trait items implemented fn main() {} diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr index d925c7316b6e..b07c5735dff6 100644 --- a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr +++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr @@ -7,11 +7,11 @@ LL | #![feature(return_type_notation)] = note: see issue #109417 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/rtn-in-impl-signature.rs:10:17 | LL | impl Super1<'_, bar(): Send> for () {} - | ^^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^^ associated item constraint not allowed here error[E0046]: not all trait items implemented, missing: `bar` --> $DIR/rtn-in-impl-signature.rs:10:1 diff --git a/tests/ui/borrowck/generic_const_early_param.rs b/tests/ui/borrowck/generic_const_early_param.rs index f601e45d21fe..0d07b6869f12 100644 --- a/tests/ui/borrowck/generic_const_early_param.rs +++ b/tests/ui/borrowck/generic_const_early_param.rs @@ -5,7 +5,6 @@ struct DataWrapper<'static> { //~^ ERROR invalid lifetime parameter name: `'static` data: &'a [u8; Self::SIZE], //~^ ERROR use of undeclared lifetime name `'a` - //~^^ ERROR lifetime may not live long enough } impl DataWrapper<'a> { diff --git a/tests/ui/borrowck/generic_const_early_param.stderr b/tests/ui/borrowck/generic_const_early_param.stderr index a71ab09396e7..3f56d6a33251 100644 --- a/tests/ui/borrowck/generic_const_early_param.stderr +++ b/tests/ui/borrowck/generic_const_early_param.stderr @@ -14,7 +14,7 @@ LL | data: &'a [u8; Self::SIZE], | ^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/generic_const_early_param.rs:11:18 + --> $DIR/generic_const_early_param.rs:10:18 | LL | impl DataWrapper<'a> { | - ^^ undeclared lifetime @@ -30,13 +30,7 @@ LL | #![feature(generic_const_exprs)] = note: see issue #76560 for more information = note: `#[warn(incomplete_features)]` on by default -error: lifetime may not live long enough - --> $DIR/generic_const_early_param.rs:6:20 - | -LL | data: &'a [u8; Self::SIZE], - | ^^^^^^^^^^ requires that `'_` must outlive `'static` - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted Some errors have detailed explanations: E0261, E0262. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/closures/closure-expected.stderr b/tests/ui/closures/closure-expected.stderr index 6b309d70bdf1..53a93e1e84dd 100644 --- a/tests/ui/closures/closure-expected.stderr +++ b/tests/ui/closures/closure-expected.stderr @@ -6,7 +6,7 @@ LL | let y = x.or_else(4); | | | required by a bound introduced by this call | - = help: the trait `FnOnce<()>` is not implemented for `{integer}` + = help: the trait `FnOnce()` is not implemented for `{integer}` = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `Option::::or_else` --> $SRC_DIR/core/src/option.rs:LL:COL diff --git a/tests/ui/closures/coerce-unsafe-to-closure.stderr b/tests/ui/closures/coerce-unsafe-to-closure.stderr index 4841ff32e701..cb718ca160f8 100644 --- a/tests/ui/closures/coerce-unsafe-to-closure.stderr +++ b/tests/ui/closures/coerce-unsafe-to-closure.stderr @@ -6,7 +6,7 @@ LL | let x: Option<&[u8]> = Some("foo").map(std::mem::transmute); | | | required by a bound introduced by this call | - = help: the trait `FnOnce<(&str,)>` is not implemented for fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` + = help: the trait `FnOnce(&str)` is not implemented for fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `Option::::map` --> $SRC_DIR/core/src/option.rs:LL:COL diff --git a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs index 89d0b74d4030..fa0b0fdc136a 100644 --- a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs +++ b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs @@ -8,5 +8,6 @@ impl Trait for [(); N] {} //~^ ERROR: mismatched types impl Trait for [(); N] {} //~^ ERROR: mismatched types +//~| ERROR: conflicting implementations of trait `Trait` fn main() {} diff --git a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr index d19502546602..d65450845bc1 100644 --- a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr +++ b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr @@ -1,3 +1,12 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `[(); _]` + --> $DIR/generic_const_type_mismatch.rs:9:1 + | +LL | impl Trait for [(); N] {} + | ----------------------------------- first implementation here +LL | +LL | impl Trait for [(); N] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); _]` + error[E0308]: mismatched types --> $DIR/generic_const_type_mismatch.rs:7:34 | @@ -10,6 +19,7 @@ error[E0308]: mismatched types LL | impl Trait for [(); N] {} | ^ expected `usize`, found `i8` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0119, E0308. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index 7443459b8300..d809a6948f3e 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr @@ -1,7 +1,7 @@ -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:31:1 | diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index 38a02c906d4f..329086ab7dfd 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr @@ -1,11 +1,11 @@ -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` --> $DIR/associated-type.rs:31:1 | diff --git a/tests/crashes/114456.rs b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.rs similarity index 69% rename from tests/crashes/114456.rs rename to tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.rs index e347327e7386..8035fce09147 100644 --- a/tests/crashes/114456.rs +++ b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.rs @@ -1,5 +1,7 @@ -//@ known-bug: #114456 +//@ check-pass #![feature(adt_const_params, lazy_type_alias)] +//~^ WARN: the feature `adt_const_params` is incomplete +//~| WARN: the feature `lazy_type_alias` is incomplete pub type Matrix = [usize; 1]; const EMPTY_MATRIX: Matrix = [0; 1]; diff --git a/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.stderr b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.stderr new file mode 100644 index 000000000000..5c6981077b2d --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-1.stderr @@ -0,0 +1,19 @@ +warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/alias_const_param_ty-1.rs:2:12 + | +LL | #![feature(adt_const_params, lazy_type_alias)] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #95174 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/alias_const_param_ty-1.rs:2:30 + | +LL | #![feature(adt_const_params, lazy_type_alias)] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #112792 for more information + +warning: 2 warnings emitted + diff --git a/tests/crashes/114456-2.rs b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-2.rs similarity index 64% rename from tests/crashes/114456-2.rs rename to tests/ui/const-generics/adt_const_params/alias_const_param_ty-2.rs index eca27febb968..a576b75341cf 100644 --- a/tests/crashes/114456-2.rs +++ b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-2.rs @@ -1,5 +1,6 @@ -//@ known-bug: #114456 +//@ check-pass #![feature(adt_const_params)] +//~^ WARN: the feature `adt_const_params` is incomplete const EMPTY_MATRIX: ::Matrix = [0; 1]; @@ -12,8 +13,12 @@ impl Walk { } pub enum Type {} -pub trait Trait { type Matrix; } -impl Trait for Type { type Matrix = [usize; 1]; } +pub trait Trait { + type Matrix; +} +impl Trait for Type { + type Matrix = [usize; 1]; +} fn main() { let _ = Walk::new(); diff --git a/tests/ui/const-generics/adt_const_params/alias_const_param_ty-2.stderr b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-2.stderr new file mode 100644 index 000000000000..dbc8ab716365 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/alias_const_param_ty-2.stderr @@ -0,0 +1,11 @@ +warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/alias_const_param_ty-2.rs:2:12 + | +LL | #![feature(adt_const_params)] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #95174 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs index 68b8b4898168..569e57fa3262 100644 --- a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs +++ b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs @@ -24,7 +24,6 @@ fn via_associated_const() { trait Trait { const FALSE: bool = assert::is_transmutable::(); //~^ ERROR mismatched types - //~| ERROR `Src` cannot be safely transmuted into `Dst` //~| ERROR mismatched types } } diff --git a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr index 1dbacaee3c2d..a8fc742e89f5 100644 --- a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr +++ b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr @@ -12,28 +12,13 @@ error[E0308]: mismatched types LL | const FALSE: bool = assert::is_transmutable::(); | ^^ expected `Assume`, found `()` -error[E0277]: `Src` cannot be safely transmuted into `Dst` - --> $DIR/transmutable-ice-110969.rs:25:60 - | -LL | const FALSE: bool = assert::is_transmutable::(); - | ^^^ `Dst` may carry safety invariants - | -note: required by a bound in `is_transmutable` - --> $DIR/transmutable-ice-110969.rs:11:14 - | -LL | pub fn is_transmutable() - | --------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` - error[E0308]: mismatched types --> $DIR/transmutable-ice-110969.rs:25:29 | LL | const FALSE: bool = assert::is_transmutable::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0107, E0277, E0308. +Some errors have detailed explanations: E0107, E0308. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/const-generics/bad-subst-const-kind.rs b/tests/ui/const-generics/bad-subst-const-kind.rs index 88f98a54b6e6..d5913879191e 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.rs +++ b/tests/ui/const-generics/bad-subst-const-kind.rs @@ -10,5 +10,7 @@ impl Q for [u8; N] { const ASSOC: usize = 1; } -pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() } -//~^ ERROR: `[u8; 13]: Q` is not satisfied +pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { + //~^ ERROR: the constant `13` is not of type `u64` + todo!() +} diff --git a/tests/ui/const-generics/bad-subst-const-kind.stderr b/tests/ui/const-generics/bad-subst-const-kind.stderr index 6cf9fa743b34..6725f6762e45 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.stderr +++ b/tests/ui/const-generics/bad-subst-const-kind.stderr @@ -1,10 +1,16 @@ -error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied +error: the constant `13` is not of type `u64` --> $DIR/bad-subst-const-kind.rs:13:24 | -LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() } - | ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]` +LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { + | ^^^^^^^^ expected `u64`, found `usize` | - = help: the trait `Q` is implemented for `[u8; N]` +note: required for `[u8; 13]` to implement `Q` + --> $DIR/bad-subst-const-kind.rs:8:20 + | +LL | impl Q for [u8; N] { + | ------------ ^ ^^^^^^^ + | | + | unsatisfied trait bound introduced here error[E0308]: mismatched types --> $DIR/bad-subst-const-kind.rs:8:31 @@ -14,5 +20,4 @@ LL | impl Q for [u8; N] { error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/defaults/doesnt_infer.rs b/tests/ui/const-generics/defaults/doesnt_infer.rs index e14c08fc1487..016685eee9df 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.rs +++ b/tests/ui/const-generics/defaults/doesnt_infer.rs @@ -3,7 +3,9 @@ struct Foo; impl Foo { - fn foo() -> Self { loop {} } + fn foo() -> Self { + loop {} + } } fn main() { diff --git a/tests/ui/const-generics/defaults/doesnt_infer.stderr b/tests/ui/const-generics/defaults/doesnt_infer.stderr index 93d586033971..1e779f75ce08 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.stderr +++ b/tests/ui/const-generics/defaults/doesnt_infer.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed for `Foo<_>` - --> $DIR/doesnt_infer.rs:11:9 + --> $DIR/doesnt_infer.rs:13:9 | LL | let foo = Foo::foo(); | ^^^ diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.rs b/tests/ui/const-generics/generic_arg_infer/issue-91614.rs index b45e2cbc7372..cfbc5faecd9c 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.rs +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.rs @@ -4,5 +4,5 @@ use std::simd::Mask; fn main() { let y = Mask::<_, _>::splat(false); - //~^ ERROR: type annotations needed for + //~^ ERROR: type annotations needed } diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs index 8023b998a409..af17a37bf23a 100644 --- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs +++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs @@ -15,6 +15,7 @@ where { type AssocTy = Const<{ my_const_fn(U) }>; //~^ ERROR private type + //~| ERROR private type fn assoc_fn() -> Self::AssocTy { Const } diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr index 043fa34d605a..df0d43bef876 100644 --- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr +++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr @@ -7,6 +7,17 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>; LL | const fn my_const_fn(val: u8) -> u8 { | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private -error: aborting due to 1 previous error +error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface + --> $DIR/eval-privacy.rs:16:5 + | +LL | type AssocTy = Const<{ my_const_fn(U) }>; + | ^^^^^^^^^^^^ can't leak private type +... +LL | const fn my_const_fn(val: u8) -> u8 { + | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/const-generics/generic_const_exprs/ice-125520-layout-mismatch-mulwithoverflow.rs b/tests/ui/const-generics/generic_const_exprs/ice-125520-layout-mismatch-mulwithoverflow.rs deleted file mode 100644 index cd2dc3f4fe85..000000000000 --- a/tests/ui/const-generics/generic_const_exprs/ice-125520-layout-mismatch-mulwithoverflow.rs +++ /dev/null @@ -1,27 +0,0 @@ -// issue: rust-lang/rust#125520 -#![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - -struct Outer(); -impl Outer -//~^ ERROR the constant `A` is not of type `i64` -//~| ERROR the constant `B` is not of type `i64` -//~| ERROR mismatched types -//~| ERROR mismatched types -where - [(); A + (B * 2)]:, -{ - fn i() -> Self { - //~^ ERROR the constant `A` is not of type `i64` - //~| ERROR the constant `B` is not of type `i64` - Self - //~^ ERROR mismatched types - //~| ERROR the constant `A` is not of type `i64` - //~| ERROR the constant `B` is not of type `i64` - } -} - -fn main() { - Outer::<1, 1>::o(); - //~^ ERROR no function or associated item named `o` found for struct `Outer` in the current scope -} diff --git a/tests/ui/const-generics/generic_const_exprs/ice-125520-layout-mismatch-mulwithoverflow.stderr b/tests/ui/const-generics/generic_const_exprs/ice-125520-layout-mismatch-mulwithoverflow.stderr deleted file mode 100644 index 2dbd69fd3bc1..000000000000 --- a/tests/ui/const-generics/generic_const_exprs/ice-125520-layout-mismatch-mulwithoverflow.stderr +++ /dev/null @@ -1,125 +0,0 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:2:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: the constant `A` is not of type `i64` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:6:38 - | -LL | impl Outer - | ^^^^^^^^^^^ expected `i64`, found `usize` - | -note: required by a bound in `Outer` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:14 - | -LL | struct Outer(); - | ^^^^^^^^^^^^ required by this bound in `Outer` - -error: the constant `B` is not of type `i64` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:6:38 - | -LL | impl Outer - | ^^^^^^^^^^^ expected `i64`, found `usize` - | -note: required by a bound in `Outer` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:28 - | -LL | struct Outer(); - | ^^^^^^^^^^^^ required by this bound in `Outer` - -error: the constant `A` is not of type `i64` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:14:15 - | -LL | fn i() -> Self { - | ^^^^ expected `i64`, found `usize` - | -note: required by a bound in `Outer` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:14 - | -LL | struct Outer(); - | ^^^^^^^^^^^^ required by this bound in `Outer` - -error: the constant `B` is not of type `i64` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:14:15 - | -LL | fn i() -> Self { - | ^^^^ expected `i64`, found `usize` - | -note: required by a bound in `Outer` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:28 - | -LL | struct Outer(); - | ^^^^^^^^^^^^ required by this bound in `Outer` - -error[E0308]: mismatched types - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:17:9 - | -LL | struct Outer(); - | ---------------------------------------- `Outer` defines a struct constructor here, which should be called -... -LL | fn i() -> Self { - | ---- expected `Outer` because of return type -... -LL | Self - | ^^^^ expected `Outer`, found struct constructor - | - = note: expected struct `Outer` - found struct constructor `fn() -> Outer {Outer::}` -help: use parentheses to construct this tuple struct - | -LL | Self() - | ++ - -error: the constant `A` is not of type `i64` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:17:9 - | -LL | Self - | ^^^^ expected `i64`, found `usize` - | -note: required by a bound in `Outer` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:14 - | -LL | struct Outer(); - | ^^^^^^^^^^^^ required by this bound in `Outer` - -error: the constant `B` is not of type `i64` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:17:9 - | -LL | Self - | ^^^^ expected `i64`, found `usize` - | -note: required by a bound in `Outer` - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:5:28 - | -LL | struct Outer(); - | ^^^^^^^^^^^^ required by this bound in `Outer` - -error[E0599]: no function or associated item named `o` found for struct `Outer` in the current scope - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:25:20 - | -LL | struct Outer(); - | ---------------------------------------- function or associated item `o` not found for this struct -... -LL | Outer::<1, 1>::o(); - | ^ function or associated item not found in `Outer<1, 1>` - -error[E0308]: mismatched types - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:6:44 - | -LL | impl Outer - | ^ expected `i64`, found `usize` - -error[E0308]: mismatched types - --> $DIR/ice-125520-layout-mismatch-mulwithoverflow.rs:6:47 - | -LL | impl Outer - | ^ expected `i64`, found `usize` - -error: aborting due to 10 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0308, E0599. -For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs b/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs index 42c1cc507b5c..b3bbb8426386 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs @@ -1,14 +1,11 @@ #![feature(generic_const_exprs)] #![allow(incomplete_features)] -#![deny(where_clauses_object_safety)] const fn bar() -> usize { 7 } trait Foo { fn test(&self) where [u8; bar::()]: Sized; - //~^ ERROR the trait `Foo` cannot be made into an object - //~| WARN this was previously accepted by the compiler but is being phased out } impl Foo for () { @@ -16,7 +13,9 @@ impl Foo for () { } fn use_dyn(v: &dyn Foo) { + //~^ ERROR the trait `Foo` cannot be made into an object v.test(); + //~^ ERROR the trait `Foo` cannot be made into an object } fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr index 9e480ce9b856..fde5d3ce7725 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr @@ -1,24 +1,35 @@ -error: the trait `Foo` cannot be made into an object - --> $DIR/object-safety-err-where-bounds.rs:9:8 +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety-err-where-bounds.rs:15:16 | -LL | fn test(&self) where [u8; bar::()]: Sized; - | ^^^^ +LL | fn use_dyn(v: &dyn Foo) { + | ^^^^^^^ `Foo` cannot be made into an object | - = 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 #51443 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety-err-where-bounds.rs:9:8 + --> $DIR/object-safety-err-where-bounds.rs:8:8 | LL | trait Foo { | --- this trait cannot be made into an object... LL | fn test(&self) where [u8; bar::()]: Sized; | ^^^^ ...because method `test` references the `Self` type in its `where` clause = help: consider moving `test` to another trait -note: the lint level is defined here - --> $DIR/object-safety-err-where-bounds.rs:3:9 + = help: only type `()` implements the trait, consider using it directly instead + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety-err-where-bounds.rs:17:5 | -LL | #![deny(where_clauses_object_safety)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | v.test(); + | ^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-err-where-bounds.rs:8:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn test(&self) where [u8; bar::()]: Sized; + | ^^^^ ...because method `test` references the `Self` type in its `where` clause + = help: consider moving `test` to another trait + = help: only type `()` implements the trait, consider using it directly instead -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs index 285f9dee6c27..6b0d9e047dbc 100644 --- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs +++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs @@ -10,7 +10,7 @@ impl Q for [u8; N] {} //~| ERROR mismatched types pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {} -//~^ ERROR `[u8; 13]: Q` is not satisfied +//~^ ERROR the constant `13` is not of type `u64` //~| ERROR mismatched types pub fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr index a63a56dd6753..bb6d650b7ab2 100644 --- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr +++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr @@ -7,13 +7,19 @@ LL | const ASSOC: usize; LL | impl Q for [u8; N] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation -error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied +error: the constant `13` is not of type `u64` --> $DIR/type_mismatch.rs:12:26 | LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {} - | ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]` + | ^^^^^^^^ expected `u64`, found `usize` | - = help: the trait `Q` is implemented for `[u8; N]` +note: required for `[u8; 13]` to implement `Q` + --> $DIR/type_mismatch.rs:8:20 + | +LL | impl Q for [u8; N] {} + | ------------ ^ ^^^^^^^ + | | + | unsatisfied trait bound introduced here error[E0308]: mismatched types --> $DIR/type_mismatch.rs:12:20 @@ -31,5 +37,5 @@ LL | impl Q for [u8; N] {} error: aborting due to 4 previous errors -Some errors have detailed explanations: E0046, E0277, E0308. +Some errors have detailed explanations: E0046, E0308. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/const-generics/issues/issue-105821.rs b/tests/ui/const-generics/issues/issue-105821.rs index e55da461605e..ecbae4d9f35c 100644 --- a/tests/ui/const-generics/issues/issue-105821.rs +++ b/tests/ui/const-generics/issues/issue-105821.rs @@ -1,10 +1,7 @@ -//@ failure-status: 101 -//@ known-bug: rust-lang/rust#125451 -//@ normalize-stderr-test "note: .*\n\n" -> "" -//@ normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> "" -//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@ normalize-stderr-test "delayed at .*" -> "" -//@ rustc-env:RUST_BACKTRACE=0 +//@ check-pass +// If this test starts failing because it ICEs due to not being able to convert a `ReErased` to +// something then feel free to just convert this to a known-bug. I'm pretty sure this is still +// a failing test, we just started masking the bug. #![allow(incomplete_features)] #![feature(adt_const_params, generic_const_exprs)] diff --git a/tests/ui/const-generics/issues/issue-105821.stderr b/tests/ui/const-generics/issues/issue-105821.stderr deleted file mode 100644 index 1f0fc0f33ce4..000000000000 --- a/tests/ui/const-generics/issues/issue-105821.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: internal compiler error: compiler/rustc_borrowck/src/universal_regions.rs:LL:CC: cannot convert `'{erased}` to a region vid - -query stack during panic: -#0 [mir_borrowck] borrow-checking `::R` -#1 [analysis] running analysis passes on this crate -end of query stack -error: aborting due to 1 previous error - diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr index 5d7800746961..b6460e0017fa 100644 --- a/tests/ui/const-generics/issues/issue-71381.full.stderr +++ b/tests/ui/const-generics/issues/issue-71381.full.stderr @@ -7,7 +7,7 @@ LL | pub fn call_me $DIR/issue-71381.rs:22:40 + --> $DIR/issue-71381.rs:23:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr index 5d7800746961..e16d3b7a8a46 100644 --- a/tests/ui/const-generics/issues/issue-71381.min.stderr +++ b/tests/ui/const-generics/issues/issue-71381.min.stderr @@ -7,13 +7,29 @@ LL | pub fn call_me $DIR/issue-71381.rs:22:40 + --> $DIR/issue-71381.rs:23:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` | = note: type parameters may not be used in the type of const parameters -error: aborting due to 2 previous errors +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71381.rs:14:61 + | +LL | pub fn call_me(&self) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71381.rs:23:19 + | +LL | const FN: unsafe extern "C" fn(Args), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/issues/issue-71381.rs b/tests/ui/const-generics/issues/issue-71381.rs index 7f2e14944e29..e472ef31fcdd 100644 --- a/tests/ui/const-generics/issues/issue-71381.rs +++ b/tests/ui/const-generics/issues/issue-71381.rs @@ -13,6 +13,7 @@ unsafe extern "C" fn pass(args: PassArg) { impl Test { pub fn call_me(&self) { //~^ ERROR: the type of const parameters must not depend on other generic parameters + //[min]~^^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline:: as _ } @@ -21,6 +22,7 @@ impl Test { const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: the type of const parameters must not depend on other generic parameters + //[min]~^^ ERROR: using function pointers as const generic parameters is forbidden >( args: Args, ) { diff --git a/tests/ui/const-generics/issues/issue-71611.min.stderr b/tests/ui/const-generics/issues/issue-71611.min.stderr index 6f6a9fc21a69..b01936f4d251 100644 --- a/tests/ui/const-generics/issues/issue-71611.min.stderr +++ b/tests/ui/const-generics/issues/issue-71611.min.stderr @@ -6,6 +6,14 @@ LL | fn func(outer: A) { | = note: type parameters may not be used in the type of const parameters -error: aborting due to 1 previous error +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71611.rs:5:21 + | +LL | fn func(outer: A) { + | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/issues/issue-71611.rs b/tests/ui/const-generics/issues/issue-71611.rs index 0e0c08146b2e..c6c1e267171f 100644 --- a/tests/ui/const-generics/issues/issue-71611.rs +++ b/tests/ui/const-generics/issues/issue-71611.rs @@ -4,6 +4,7 @@ fn func(outer: A) { //~^ ERROR: the type of const parameters must not depend on other generic parameters + //[min]~| ERROR: using function pointers as const generic parameters is forbidden F(outer); } diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs index 79743abe4093..fbf1553c182c 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs @@ -8,7 +8,7 @@ const T: usize = 42; impl Foo for Bar { //~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied -//~| ERROR associated type bindings are not allowed here +//~| ERROR associated item constraints are not allowed here //~| ERROR associated const equality is incomplete fn do_x(&self) -> [u8; 3] { [0u8; 3] diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr index 941764a575e6..a132859b412f 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr @@ -24,11 +24,11 @@ help: add missing generic argument LL | impl Foo for Bar { | ++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-89013-no-kw.rs:9:10 | LL | impl Foo for Bar { - | ^^^^^ associated type not allowed here + | ^^^^^ associated item constraint not allowed here | help: to use `3` as a generic argument specify it directly | diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs index 335d0d94e83c..c9c7ff3a1704 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs @@ -9,7 +9,7 @@ const T: usize = 42; impl Foo for Bar { //~^ ERROR expected lifetime, type, or constant, found keyword `const` //~| ERROR trait takes 1 generic -//~| ERROR associated type bindings are not allowed here +//~| ERROR associated item constraints are not allowed here //~| ERROR associated const equality is incomplete fn do_x(&self) -> [u8; 3] { [0u8; 3] diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr index a4c9e065c15c..2fdd12085652 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -36,11 +36,11 @@ help: add missing generic argument LL | impl Foo for Bar { | ++ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-89013.rs:9:10 | LL | impl Foo for Bar { - | ^^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^^ associated item constraint not allowed here | help: to use `3` as a generic argument specify it directly | 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 a41a159c1fd7..09f7e2ba5b1d 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 @@ -13,6 +13,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 } } 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 d95a8861230e..9442eac0cf54 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,7 +17,13 @@ help: you might be missing a type parameter LL | pub struct Opcode2(&'a S); | +++ -error: aborting due to 2 previous errors +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 Some errors have detailed explanations: E0261, E0412. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/consts/eval_type_mismatch.stderr b/tests/ui/consts/eval_type_mismatch.stderr deleted file mode 100644 index 38d6e33d4067..000000000000 --- a/tests/ui/consts/eval_type_mismatch.stderr +++ /dev/null @@ -1,34 +0,0 @@ -error: the constant `A` is not of type `i64` - --> $DIR/eval_type_mismatch.rs:5:38 - | -LL | impl Outer - | ^^^^^^^^^^^ expected `i64`, found `usize` - | -note: required by a bound in `Outer` - --> $DIR/eval_type_mismatch.rs:4:14 - | -LL | struct Outer(); - | ^^^^^^^^^^^^ required by this bound in `Outer` - -error[E0599]: no function or associated item named `o` found for struct `Outer<1, 1>` in the current scope - --> $DIR/eval_type_mismatch.rs:15:20 - | -LL | struct Outer(); - | ------------------------------------------ function or associated item `o` not found for this struct -... -LL | Outer::<1, 1>::o(); - | ^ function or associated item not found in `Outer<1, 1>` - | - = note: the function or associated item was found for - - `Outer` - -error[E0308]: mismatched types - --> $DIR/eval_type_mismatch.rs:5:44 - | -LL | impl Outer - | ^ expected `i64`, found `usize` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0308, E0599. -For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr index aad0ae64e858..4fb82c0683dc 100644 --- a/tests/ui/consts/fn_trait_refs.stderr +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -107,8 +107,8 @@ LL | f() = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | T: ~const Fn<()> + ~const Destruct + ~const std::ops::Fn<()>, - | +++++++++++++++++++++++++ +LL | T: ~const Fn<()> + ~const Destruct + ~const Fn(), + | +++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] @@ -132,8 +132,8 @@ LL | f() = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | T: ~const FnMut<()> + ~const Destruct + ~const std::ops::FnMut<()>, - | ++++++++++++++++++++++++++++ +LL | T: ~const FnMut<()> + ~const Destruct + ~const FnMut(), + | ++++++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] @@ -157,8 +157,8 @@ LL | f() = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | T: ~const FnOnce<()> + ~const std::ops::FnOnce<()>, - | +++++++++++++++++++++++++++++ +LL | T: ~const FnOnce<()> + ~const FnOnce(), + | +++++++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] diff --git a/tests/ui/consts/unstable-const-fn-in-libcore.stderr b/tests/ui/consts/unstable-const-fn-in-libcore.stderr index 9590b3372e32..6c83eff4de01 100644 --- a/tests/ui/consts/unstable-const-fn-in-libcore.stderr +++ b/tests/ui/consts/unstable-const-fn-in-libcore.stderr @@ -13,8 +13,8 @@ LL | Opt::None => f(), = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | const fn unwrap_or_else T + ~const std::ops::FnOnce<()>>(self, f: F) -> T { - | +++++++++++++++++++++++++++++ +LL | const fn unwrap_or_else T + ~const FnOnce()>(self, f: F) -> T { + | +++++++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr new file mode 100644 index 000000000000..bcede8a255f2 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr @@ -0,0 +1,15 @@ +error[E0277]: Very important message! + --> $DIR/type_mismatch.rs:25:14 + | +LL | verify::(); + | ^^ the trait `TheImportantOne` is not implemented for `u8` + | +note: required by a bound in `verify` + --> $DIR/type_mismatch.rs:22:14 + | +LL | fn verify() {} + | ^^^^^^^^^^^^^^^ required by this bound in `verify` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr new file mode 100644 index 000000000000..bcede8a255f2 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr @@ -0,0 +1,15 @@ +error[E0277]: Very important message! + --> $DIR/type_mismatch.rs:25:14 + | +LL | verify::(); + | ^^ the trait `TheImportantOne` is not implemented for `u8` + | +note: required by a bound in `verify` + --> $DIR/type_mismatch.rs:22:14 + | +LL | fn verify() {} + | ^^^^^^^^^^^^^^^ required by this bound in `verify` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs new file mode 100644 index 000000000000..d6721ccc848f --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs @@ -0,0 +1,27 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(do_not_recommend)] + +#[diagnostic::on_unimplemented(message = "Very important message!")] +trait TheImportantOne {} + +trait ImplementationDetail { + type Restriction; +} + +#[diagnostic::do_not_recommend] +impl> TheImportantOne for T {} + +// Comment out this `impl` to show the expected error message. +impl ImplementationDetail for u8 { + type Restriction = u8; +} + +fn verify() {} + +pub fn main() { + verify::(); + //~^ERROR: Very important message! [E0277] +} diff --git a/tests/ui/error-codes/E0229.rs b/tests/ui/error-codes/E0229.rs index 558baae37f76..da2758dfba8f 100644 --- a/tests/ui/error-codes/E0229.rs +++ b/tests/ui/error-codes/E0229.rs @@ -10,10 +10,10 @@ impl Foo for isize { fn boo(&self) -> usize { 42 } } -fn baz(x: &>::A) {} -//~^ ERROR associated type bindings are not allowed here [E0229] -//~| ERROR associated type bindings are not allowed here [E0229] -//~| ERROR associated type bindings are not allowed here [E0229] +fn baz(x: &>::A) {} +//~^ ERROR associated item constraints are not allowed here [E0229] +//~| ERROR associated item constraints are not allowed here [E0229] +//~| ERROR associated item constraints are not allowed here [E0229] //~| ERROR the trait bound `I: Foo` is not satisfied //~| ERROR the trait bound `I: Foo` is not satisfied diff --git a/tests/ui/error-codes/E0229.stderr b/tests/ui/error-codes/E0229.stderr index ae7dc9ac2659..7d9cedc3bdc4 100644 --- a/tests/ui/error-codes/E0229.stderr +++ b/tests/ui/error-codes/E0229.stderr @@ -1,58 +1,58 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/E0229.rs:13:25 | -LL | fn baz(x: &>::A) {} - | ^^^^^ associated type not allowed here +LL | fn baz(x: &>::A) {} + | ^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | -LL | fn baz(x: &>::A) {} - | ~~~~~~~ +LL | fn baz(x: &>::A) {} + | ~~~~~~~~~ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/E0229.rs:13:25 | -LL | fn baz(x: &>::A) {} - | ^^^^^ associated type not allowed here +LL | fn baz(x: &>::A) {} + | ^^^^^^^ associated item constraint not allowed here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider removing this type binding +help: consider removing this associated item binding | -LL | fn baz(x: &>::A) {} - | ~~~~~~~ +LL | fn baz(x: &>::A) {} + | ~~~~~~~~~ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/E0229.rs:13:25 | -LL | fn baz(x: &>::A) {} - | ^^^^^ associated type not allowed here +LL | fn baz(x: &>::A) {} + | ^^^^^^^ associated item constraint not allowed here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider removing this type binding +help: consider removing this associated item binding | -LL | fn baz(x: &>::A) {} - | ~~~~~~~ +LL | fn baz(x: &>::A) {} + | ~~~~~~~~~ error[E0277]: the trait bound `I: Foo` is not satisfied --> $DIR/E0229.rs:13:15 | -LL | fn baz(x: &>::A) {} - | ^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `I` +LL | fn baz(x: &>::A) {} + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `I` | help: consider restricting type parameter `I` | -LL | fn baz(x: &>::A) {} +LL | fn baz(x: &>::A) {} | +++++ error[E0277]: the trait bound `I: Foo` is not satisfied - --> $DIR/E0229.rs:13:37 + --> $DIR/E0229.rs:13:39 | -LL | fn baz(x: &>::A) {} - | ^^ the trait `Foo` is not implemented for `I` +LL | fn baz(x: &>::A) {} + | ^^ the trait `Foo` is not implemented for `I` | help: consider restricting type parameter `I` | -LL | fn baz(x: &>::A) {} +LL | fn baz(x: &>::A) {} | +++++ error: aborting due to 5 previous errors diff --git a/tests/ui/expr/malformed_closure/block_instead_of_closure_in_arg.stderr b/tests/ui/expr/malformed_closure/block_instead_of_closure_in_arg.stderr index 1264d9693425..c4c1c830afa6 100644 --- a/tests/ui/expr/malformed_closure/block_instead_of_closure_in_arg.stderr +++ b/tests/ui/expr/malformed_closure/block_instead_of_closure_in_arg.stderr @@ -14,7 +14,7 @@ LL | || } LL | | }); | |______^ expected an `FnOnce(&bool)` closure, found `bool` | - = help: the trait `for<'a> FnOnce<(&'a bool,)>` is not implemented for `bool` + = help: the trait `for<'a> FnOnce(&'a bool)` is not implemented for `bool` note: required by a bound in `Option::::filter` --> $SRC_DIR/core/src/option.rs:LL:COL help: you might have meant to create the closure instead of a block diff --git a/tests/ui/expr/malformed_closure/ruby_style_closure_successful_parse.stderr b/tests/ui/expr/malformed_closure/ruby_style_closure_successful_parse.stderr index a7ed9f5880b6..54d3c6727f77 100644 --- a/tests/ui/expr/malformed_closure/ruby_style_closure_successful_parse.stderr +++ b/tests/ui/expr/malformed_closure/ruby_style_closure_successful_parse.stderr @@ -11,7 +11,7 @@ LL | | Some(x * 2) LL | | }); | |_____^ expected an `FnOnce({integer})` closure, found `Option` | - = help: the trait `FnOnce<({integer},)>` is not implemented for `Option` + = help: the trait `FnOnce({integer})` is not implemented for `Option` note: required by a bound in `Option::::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL help: you might have meant to open the closure body instead of placing a closure within a block diff --git a/tests/ui/extern/extern-wrong-value-type.stderr b/tests/ui/extern/extern-wrong-value-type.stderr index 1c08aa1717f4..692a66011711 100644 --- a/tests/ui/extern/extern-wrong-value-type.stderr +++ b/tests/ui/extern/extern-wrong-value-type.stderr @@ -6,7 +6,7 @@ LL | is_fn(f); | | | required by a bound introduced by this call | - = help: the trait `Fn<()>` is not implemented for fn item `extern "C" fn() {f}` + = help: the trait `Fn()` is not implemented for fn item `extern "C" fn() {f}` = note: wrap the `extern "C" fn() {f}` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `is_fn` --> $DIR/extern-wrong-value-type.rs:4:28 diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs index b8ce9c85b727..ff528274c59b 100644 --- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs +++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs @@ -16,7 +16,7 @@ impl Fn<()> for Foo { } struct Foo1; impl FnOnce() for Foo1 { - //~^ ERROR associated type bindings are not allowed here + //~^ ERROR associated item constraints are not allowed here //~| ERROR manual implementations of `FnOnce` are experimental //~| ERROR not all trait items implemented extern "rust-call" fn call_once(self, args: ()) -> () {} diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr index c3f161469e30..1b9febd431d6 100644 --- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr +++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr @@ -80,7 +80,7 @@ error[E0277]: expected a `FnMut()` closure, found `Foo` LL | impl Fn<()> for Foo { | ^^^ expected an `FnMut()` closure, found `Foo` | - = help: the trait `FnMut<()>` is not implemented for `Foo` + = help: the trait `FnMut()` is not implemented for `Foo` = note: wrap the `Foo` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -105,11 +105,11 @@ LL | impl FnOnce() for Foo1 { | = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6 | LL | impl FnOnce() for Foo1 { - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | help: parenthesized trait syntax expands to `FnOnce<(), Output=()>` --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6 @@ -149,7 +149,7 @@ error[E0277]: expected a `FnOnce()` closure, found `Bar` LL | impl FnMut<()> for Bar { | ^^^ expected an `FnOnce()` closure, found `Bar` | - = help: the trait `FnOnce<()>` is not implemented for `Bar` + = help: the trait `FnOnce()` is not implemented for `Bar` = note: wrap the `Bar` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `FnMut` --> $SRC_DIR/core/src/ops/function.rs:LL:COL diff --git a/tests/ui/feature-gates/feature-gate-vectorcall.stderr b/tests/ui/feature-gates/feature-gate-vectorcall.stderr index df93e8812c1e..b20e41887b9b 100644 --- a/tests/ui/feature-gates/feature-gate-vectorcall.stderr +++ b/tests/ui/feature-gates/feature-gate-vectorcall.stderr @@ -4,6 +4,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" fn f() {} | ^^^^^^^^^^^^ | + = note: see issue #124485 for more information = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -13,6 +14,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" fn m(); | ^^^^^^^^^^^^ | + = note: see issue #124485 for more information = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -22,6 +24,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" fn dm() {} | ^^^^^^^^^^^^ | + = note: see issue #124485 for more information = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -31,6 +34,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" fn m() {} | ^^^^^^^^^^^^ | + = note: see issue #124485 for more information = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -40,6 +44,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" fn im() {} | ^^^^^^^^^^^^ | + = note: see issue #124485 for more information = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -49,6 +54,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | type TA = extern "vectorcall" fn(); | ^^^^^^^^^^^^ | + = note: see issue #124485 for more information = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -58,6 +64,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" {} | ^^^^^^^^^^^^ | + = note: see issue #124485 for more information = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/fn/fn-trait-formatting.stderr b/tests/ui/fn/fn-trait-formatting.stderr index c5e2f41691fa..9fdef49c5ef9 100644 --- a/tests/ui/fn/fn-trait-formatting.stderr +++ b/tests/ui/fn/fn-trait-formatting.stderr @@ -47,7 +47,7 @@ LL | needs_fn(1); | | | required by a bound introduced by this call | - = help: the trait `Fn<(isize,)>` is not implemented for `{integer}` + = help: the trait `Fn(isize)` is not implemented for `{integer}` note: required by a bound in `needs_fn` --> $DIR/fn-trait-formatting.rs:1:31 | diff --git a/tests/ui/fn/issue-39259.rs b/tests/ui/fn/issue-39259.rs index 16983b652fc8..d4569a9094b2 100644 --- a/tests/ui/fn/issue-39259.rs +++ b/tests/ui/fn/issue-39259.rs @@ -4,7 +4,7 @@ struct S; impl Fn(u32) -> u32 for S { - //~^ ERROR associated type bindings are not allowed here [E0229] + //~^ ERROR associated item constraints are not allowed here [E0229] //~| ERROR expected a `FnMut(u32)` closure, found `S` fn call(&self) -> u32 { //~^ ERROR method `call` has 1 parameter but the declaration in trait `call` has 2 diff --git a/tests/ui/fn/issue-39259.stderr b/tests/ui/fn/issue-39259.stderr index 47150a3c155c..a923d7b26efa 100644 --- a/tests/ui/fn/issue-39259.stderr +++ b/tests/ui/fn/issue-39259.stderr @@ -1,8 +1,8 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-39259.rs:6:17 | LL | impl Fn(u32) -> u32 for S { - | ^^^ associated type not allowed here + | ^^^ associated item constraint not allowed here | help: parenthesized trait syntax expands to `Fn<(u32,), Output=u32>` --> $DIR/issue-39259.rs:6:6 @@ -16,7 +16,7 @@ error[E0277]: expected a `FnMut(u32)` closure, found `S` LL | impl Fn(u32) -> u32 for S { | ^ expected an `FnMut(u32)` closure, found `S` | - = help: the trait `FnMut<(u32,)>` is not implemented for `S` + = help: the trait `FnMut(u32)` is not implemented for `S` note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL diff --git a/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.current.stderr b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.current.stderr index 2097115af009..c5c4f2c4d231 100644 --- a/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.current.stderr +++ b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.current.stderr @@ -1,16 +1,16 @@ error[E0277]: the trait bound `::Bar<()>: Eq` is not satisfied - --> $DIR/assume-gat-normalization-for-nested-goals.rs:10:30 + --> $DIR/assume-gat-normalization-for-nested-goals.rs:9:30 | LL | type Bar: Baz = i32; | ^^^ the trait `Eq` is not implemented for `::Bar<()>`, which is required by `i32: Baz` | note: required for `i32` to implement `Baz` - --> $DIR/assume-gat-normalization-for-nested-goals.rs:17:23 + --> $DIR/assume-gat-normalization-for-nested-goals.rs:16:23 | LL | impl Baz for i32 where T::Bar<()>: Eq {} | ^^^^^^ ^^^ ------- unsatisfied trait bound introduced here note: required by a bound in `Foo::Bar` - --> $DIR/assume-gat-normalization-for-nested-goals.rs:10:18 + --> $DIR/assume-gat-normalization-for-nested-goals.rs:9:18 | LL | type Bar: Baz = i32; | ^^^^^^^^^ required by this bound in `Foo::Bar` diff --git a/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.next.stderr b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.next.stderr new file mode 100644 index 000000000000..2c372b6c3a78 --- /dev/null +++ b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.next.stderr @@ -0,0 +1,24 @@ +error[E0277]: the trait bound `i32: Baz` is not satisfied + --> $DIR/assume-gat-normalization-for-nested-goals.rs:9:30 + | +LL | type Bar: Baz = i32; + | ^^^ the trait `Eq` is not implemented for `i32`, which is required by `i32: Baz` + | +note: required for `i32` to implement `Baz` + --> $DIR/assume-gat-normalization-for-nested-goals.rs:16:23 + | +LL | impl Baz for i32 where T::Bar<()>: Eq {} + | ^^^^^^ ^^^ ------- unsatisfied trait bound introduced here +note: required by a bound in `Foo::Bar` + --> $DIR/assume-gat-normalization-for-nested-goals.rs:9:18 + | +LL | type Bar: Baz = i32; + | ^^^^^^^^^ required by this bound in `Foo::Bar` +help: consider further restricting the associated type + | +LL | trait Foo where ::Bar<()>: Eq { + | +++++++++++++++++++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.rs b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.rs index 56b50594e523..4050b6fc4258 100644 --- a/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.rs +++ b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.rs @@ -1,8 +1,7 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver //@ ignore-compare-mode-next-solver (explicit revisions) -//@[current] known-bug: #117606 -//@[next] check-pass +//@ known-bug: #117606 #![feature(associated_type_defaults)] diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs index 671d17f36f13..285493132b64 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs +++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs @@ -9,7 +9,6 @@ impl X for T { //~ ERROR: not all trait items implemented //~^ ERROR missing generics for associated type //~^^ ERROR missing generics for associated type //~| ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters - //~| ERROR may not live long enough t } } diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr index 65854ed71587..6a600aee11f2 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr @@ -51,16 +51,7 @@ help: add missing lifetime argument LL | fn foo<'a, T1: X = T1>>(t : T1) -> T1::Y<'a> { | ++++ -error: lifetime may not live long enough - --> $DIR/gat-trait-path-missing-lifetime.rs:8:3 - | -LL | fn foo<'a, T1: X>(t : T1) -> T1::Y<'a> { - | ^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | lifetime `'a` defined here - | requires that `'a` must outlive `'static` - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0046, E0049, E0107. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/generic-associated-types/issue-102335-gat.rs b/tests/ui/generic-associated-types/issue-102335-gat.rs index 3a4a0c107715..0be6ee3930f1 100644 --- a/tests/ui/generic-associated-types/issue-102335-gat.rs +++ b/tests/ui/generic-associated-types/issue-102335-gat.rs @@ -1,7 +1,7 @@ trait T { type A: S = ()>; - //~^ ERROR associated type bindings are not allowed here - //~| ERROR associated type bindings are not allowed here + //~^ ERROR associated item constraints are not allowed here + //~| ERROR associated item constraints are not allowed here } trait Q {} diff --git a/tests/ui/generic-associated-types/issue-102335-gat.stderr b/tests/ui/generic-associated-types/issue-102335-gat.stderr index 23b114a3a55e..b4772486e6e4 100644 --- a/tests/ui/generic-associated-types/issue-102335-gat.stderr +++ b/tests/ui/generic-associated-types/issue-102335-gat.stderr @@ -1,22 +1,22 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-gat.rs:2:21 | LL | type A: S = ()>; - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = ()>; | ~~~~~~~~~~ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-gat.rs:2:21 | LL | type A: S = ()>; - | ^^^^^^^^ associated type not allowed here + | ^^^^^^^^ associated item constraint not allowed here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider removing this type binding +help: consider removing this associated item binding | LL | type A: S = ()>; | ~~~~~~~~~~ diff --git a/tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr b/tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr index 6bf832bb9e2a..3929e66a25a3 100644 --- a/tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr +++ b/tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr @@ -12,8 +12,8 @@ LL | type F<'a>: Fn() -> u32; | ^^^^^^^^^^^ required by this bound in `Fun::F` help: consider restricting type parameter `T` | -LL | impl> Fun for T { - | ++++++++++++++++++ +LL | impl Fun for T { + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/issue-68643-broken-mir.stderr b/tests/ui/generic-associated-types/issue-68643-broken-mir.stderr index d9f26ee6c291..662726b89935 100644 --- a/tests/ui/generic-associated-types/issue-68643-broken-mir.stderr +++ b/tests/ui/generic-associated-types/issue-68643-broken-mir.stderr @@ -12,8 +12,8 @@ LL | type F<'a>: Fn() -> u32; | ^^^^^^^^^^^ required by this bound in `Fun::F` help: consider restricting type parameter `T` | -LL | impl> Fun for T { - | ++++++++++++++++++ +LL | impl Fun for T { + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/issue-68644-codegen-selection.stderr b/tests/ui/generic-associated-types/issue-68644-codegen-selection.stderr index 3dc9ff10243f..34278249e35d 100644 --- a/tests/ui/generic-associated-types/issue-68644-codegen-selection.stderr +++ b/tests/ui/generic-associated-types/issue-68644-codegen-selection.stderr @@ -12,8 +12,8 @@ LL | type F<'a>: Fn() -> u32; | ^^^^^^^^^^^ required by this bound in `Fun::F` help: consider restricting type parameter `T` | -LL | impl> Fun for T { - | ++++++++++++++++++ +LL | impl Fun for T { + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr b/tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr index 45fb65f6cf1e..dafe1c1d3950 100644 --- a/tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr +++ b/tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr @@ -12,8 +12,8 @@ LL | type F<'a>: Fn() -> u32; | ^^^^^^^^^^^ required by this bound in `Fun::F` help: consider restricting type parameter `T` | -LL | impl> Fun for T { - | ++++++++++++++++++ +LL | impl Fun for T { + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/issue-70304.rs b/tests/ui/generic-associated-types/issue-70304.rs index 935d3f7a4ba8..8898d4c7d135 100644 --- a/tests/ui/generic-associated-types/issue-70304.rs +++ b/tests/ui/generic-associated-types/issue-70304.rs @@ -52,5 +52,4 @@ fn create_doc() -> impl Document = DocCursorImpl<'_>> { pub fn main() { let doc = create_doc(); let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc); - //~^ ERROR: `doc` does not live long enough } diff --git a/tests/ui/generic-associated-types/issue-70304.stderr b/tests/ui/generic-associated-types/issue-70304.stderr index 8e012cc6d936..9b02c1b07683 100644 --- a/tests/ui/generic-associated-types/issue-70304.stderr +++ b/tests/ui/generic-associated-types/issue-70304.stderr @@ -27,21 +27,7 @@ LL | type Cursor<'a>: DocCursor<'a>; = note: this bound is currently required to ensure that impls have maximum flexibility = note: we are soliciting feedback, see issue #87479 for more information -error[E0597]: `doc` does not live long enough - --> $DIR/issue-70304.rs:54:59 - | -LL | let doc = create_doc(); - | --- binding `doc` declared here -LL | let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc); - | ------------^^^^- - | | | - | | borrowed value does not live long enough - | argument requires that `doc` is borrowed for `'static` -LL | -LL | } - | - `doc` dropped here while still borrowed +error: aborting due to 3 previous errors -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0106, E0597, E0637. +Some errors have detailed explanations: E0106, E0637. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/generic-associated-types/issue-71176.rs b/tests/ui/generic-associated-types/issue-71176.rs index f0e162d825f9..e58b6f6091e7 100644 --- a/tests/ui/generic-associated-types/issue-71176.rs +++ b/tests/ui/generic-associated-types/issue-71176.rs @@ -9,6 +9,9 @@ impl Provider for () { struct Holder { inner: Box>, //~^ ERROR: missing generics for associated type + //~| ERROR: missing generics for associated type + //~| ERROR: missing generics for associated type + //~| ERROR: the trait `Provider` cannot be made into an object } fn main() { diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr index ed837f347533..a1913bb618bc 100644 --- a/tests/ui/generic-associated-types/issue-71176.stderr +++ b/tests/ui/generic-associated-types/issue-71176.stderr @@ -14,6 +14,57 @@ help: add missing lifetime argument LL | inner: Box = B>>, | ++++ -error: aborting due to 1 previous error +error[E0107]: missing generics for associated type `Provider::A` + --> $DIR/issue-71176.rs:10:27 + | +LL | inner: Box>, + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-71176.rs:2:10 + | +LL | type A<'a>; + | ^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | inner: Box = B>>, + | ++++ -For more information about this error, try `rustc --explain E0107`. +error[E0107]: missing generics for associated type `Provider::A` + --> $DIR/issue-71176.rs:10:27 + | +LL | inner: Box>, + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-71176.rs:2:10 + | +LL | type A<'a>; + | ^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | inner: Box = B>>, + | ++++ + +error[E0038]: the trait `Provider` cannot be made into an object + --> $DIR/issue-71176.rs:10:14 + | +LL | inner: Box>, + | ^^^^^^^^^^^^^^^^^^^ `Provider` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-71176.rs:2:10 + | +LL | trait Provider { + | -------- this trait cannot be made into an object... +LL | type A<'a>; + | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait + = help: only type `()` implements the trait, consider using it directly instead + +error: aborting due to 4 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-74816.stderr b/tests/ui/generic-associated-types/issue-74816.current.stderr similarity index 89% rename from tests/ui/generic-associated-types/issue-74816.stderr rename to tests/ui/generic-associated-types/issue-74816.current.stderr index 45018e6976cf..335486c6538c 100644 --- a/tests/ui/generic-associated-types/issue-74816.stderr +++ b/tests/ui/generic-associated-types/issue-74816.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Self: Trait1` is not satisfied - --> $DIR/issue-74816.rs:8:31 + --> $DIR/issue-74816.rs:12:31 | LL | type Associated: Trait1 = Self; | ^^^^ the trait `Trait1` is not implemented for `Self` | note: required by a bound in `Trait2::Associated` - --> $DIR/issue-74816.rs:8:22 + --> $DIR/issue-74816.rs:12:22 | LL | type Associated: Trait1 = Self; | ^^^^^^ required by this bound in `Trait2::Associated` @@ -15,13 +15,13 @@ LL | trait Trait2: Trait1 { | ++++++++ error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-74816.rs:8:31 + --> $DIR/issue-74816.rs:12:31 | LL | type Associated: Trait1 = Self; | ^^^^ doesn't have a size known at compile-time | note: required by a bound in `Trait2::Associated` - --> $DIR/issue-74816.rs:8:5 + --> $DIR/issue-74816.rs:12:5 | LL | type Associated: Trait1 = Self; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated` diff --git a/tests/ui/generic-associated-types/issue-74816.next.stderr b/tests/ui/generic-associated-types/issue-74816.next.stderr new file mode 100644 index 000000000000..335486c6538c --- /dev/null +++ b/tests/ui/generic-associated-types/issue-74816.next.stderr @@ -0,0 +1,35 @@ +error[E0277]: the trait bound `Self: Trait1` is not satisfied + --> $DIR/issue-74816.rs:12:31 + | +LL | type Associated: Trait1 = Self; + | ^^^^ the trait `Trait1` is not implemented for `Self` + | +note: required by a bound in `Trait2::Associated` + --> $DIR/issue-74816.rs:12:22 + | +LL | type Associated: Trait1 = Self; + | ^^^^^^ required by this bound in `Trait2::Associated` +help: consider further restricting `Self` + | +LL | trait Trait2: Trait1 { + | ++++++++ + +error[E0277]: the size for values of type `Self` cannot be known at compilation time + --> $DIR/issue-74816.rs:12:31 + | +LL | type Associated: Trait1 = Self; + | ^^^^ doesn't have a size known at compile-time + | +note: required by a bound in `Trait2::Associated` + --> $DIR/issue-74816.rs:12:5 + | +LL | type Associated: Trait1 = Self; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated` +help: consider further restricting `Self` + | +LL | trait Trait2: Sized { + | +++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/generic-associated-types/issue-74816.rs b/tests/ui/generic-associated-types/issue-74816.rs index 344afb87f99c..e2f4ddc7485c 100644 --- a/tests/ui/generic-associated-types/issue-74816.rs +++ b/tests/ui/generic-associated-types/issue-74816.rs @@ -1,3 +1,7 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + #![feature(associated_type_defaults)] trait Trait1 { diff --git a/tests/ui/generic-associated-types/issue-74824.stderr b/tests/ui/generic-associated-types/issue-74824.current.stderr similarity index 90% rename from tests/ui/generic-associated-types/issue-74824.stderr rename to tests/ui/generic-associated-types/issue-74824.current.stderr index 942d9583be1b..b06c7f127ac0 100644 --- a/tests/ui/generic-associated-types/issue-74824.stderr +++ b/tests/ui/generic-associated-types/issue-74824.current.stderr @@ -1,17 +1,17 @@ error[E0277]: the trait bound `Box: Copy` is not satisfied - --> $DIR/issue-74824.rs:6:26 + --> $DIR/issue-74824.rs:10:26 | LL | type Copy: Copy = Box; | ^^^^^^ the trait `Copy` is not implemented for `Box` | note: required by a bound in `UnsafeCopy::Copy` - --> $DIR/issue-74824.rs:6:19 + --> $DIR/issue-74824.rs:10:19 | LL | type Copy: Copy = Box; | ^^^^ required by this bound in `UnsafeCopy::Copy` error[E0277]: the trait bound `T: Clone` is not satisfied - --> $DIR/issue-74824.rs:6:26 + --> $DIR/issue-74824.rs:10:26 | LL | type Copy: Copy = Box; | ^^^^^^ the trait `Clone` is not implemented for `T`, which is required by `::Copy: Copy` @@ -19,7 +19,7 @@ LL | type Copy: Copy = Box; = note: required for `Box` to implement `Clone` = note: required for `::Copy` to implement `Copy` note: required by a bound in `UnsafeCopy::Copy` - --> $DIR/issue-74824.rs:6:19 + --> $DIR/issue-74824.rs:10:19 | LL | type Copy: Copy = Box; | ^^^^ required by this bound in `UnsafeCopy::Copy` diff --git a/tests/ui/generic-associated-types/issue-74824.next.stderr b/tests/ui/generic-associated-types/issue-74824.next.stderr new file mode 100644 index 000000000000..b06c7f127ac0 --- /dev/null +++ b/tests/ui/generic-associated-types/issue-74824.next.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `Box: Copy` is not satisfied + --> $DIR/issue-74824.rs:10:26 + | +LL | type Copy: Copy = Box; + | ^^^^^^ the trait `Copy` is not implemented for `Box` + | +note: required by a bound in `UnsafeCopy::Copy` + --> $DIR/issue-74824.rs:10:19 + | +LL | type Copy: Copy = Box; + | ^^^^ required by this bound in `UnsafeCopy::Copy` + +error[E0277]: the trait bound `T: Clone` is not satisfied + --> $DIR/issue-74824.rs:10:26 + | +LL | type Copy: Copy = Box; + | ^^^^^^ the trait `Clone` is not implemented for `T`, which is required by `::Copy: Copy` + | + = note: required for `Box` to implement `Clone` + = note: required for `::Copy` to implement `Copy` +note: required by a bound in `UnsafeCopy::Copy` + --> $DIR/issue-74824.rs:10:19 + | +LL | type Copy: Copy = Box; + | ^^^^ required by this bound in `UnsafeCopy::Copy` +help: consider restricting type parameter `T` + | +LL | type Copy: Copy = Box; + | +++++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/generic-associated-types/issue-74824.rs b/tests/ui/generic-associated-types/issue-74824.rs index 10c45d133642..7cfb862abed0 100644 --- a/tests/ui/generic-associated-types/issue-74824.rs +++ b/tests/ui/generic-associated-types/issue-74824.rs @@ -1,3 +1,7 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + #![feature(associated_type_defaults)] use std::ops::Deref; diff --git a/tests/ui/generic-associated-types/issue-80433.rs b/tests/ui/generic-associated-types/issue-80433.rs index 530575424402..bdba78c2ccd2 100644 --- a/tests/ui/generic-associated-types/issue-80433.rs +++ b/tests/ui/generic-associated-types/issue-80433.rs @@ -22,8 +22,7 @@ fn test_simpler<'a>(dst: &'a mut impl TestMut) //~^ ERROR missing generics for associated type { for n in 0i16..100 { - *dst.test_mut() = n.into(); //~ ERROR: cannot borrow - //~^ ERROR: borrowed data escapes outside of function + *dst.test_mut() = n.into(); } } diff --git a/tests/ui/generic-associated-types/issue-80433.stderr b/tests/ui/generic-associated-types/issue-80433.stderr index a9a14d3f51ce..8ab6fdcb8157 100644 --- a/tests/ui/generic-associated-types/issue-80433.stderr +++ b/tests/ui/generic-associated-types/issue-80433.stderr @@ -25,30 +25,6 @@ help: add missing lifetime argument LL | fn test_simpler<'a>(dst: &'a mut impl TestMut = &'a mut f32>) | ++++ -error[E0499]: cannot borrow `*dst` as mutable more than once at a time - --> $DIR/issue-80433.rs:25:10 - | -LL | *dst.test_mut() = n.into(); - | ^^^----------- - | | - | `*dst` was mutably borrowed here in the previous iteration of the loop - | argument requires that `*dst` is borrowed for `'static` +error: aborting due to 2 previous errors -error[E0521]: borrowed data escapes outside of function - --> $DIR/issue-80433.rs:25:10 - | -LL | fn test_simpler<'a>(dst: &'a mut impl TestMut) - | -- --- `dst` is a reference that is only valid in the function body - | | - | lifetime `'a` defined here -... -LL | *dst.test_mut() = n.into(); - | ^^^^^^^^^^^^^^ - | | - | `dst` escapes the function body here - | argument requires that `'a` must outlive `'static` - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0107, E0499, E0521. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr index 59fab52b221e..2f1dfd19c483 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.stderr +++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr @@ -1,5 +1,5 @@ -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, !2_0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, !2_0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied --> $DIR/structually-relate-aliases.rs:13:36 | diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs index 5b3a4eb53ff1..14b1ebea8db2 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs @@ -1,11 +1,9 @@ // issue: 114146 - trait Foo { fn bar<'other: 'a>() -> impl Sized + 'a {} //~^ ERROR use of undeclared lifetime name `'a` //~| ERROR use of undeclared lifetime name `'a` - //~| ERROR expected generic lifetime parameter, found `'static` } fn main() {} diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr index 8975578dabd8..f1b006da1db5 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/bad-item-bound-within-rpitit-2.rs:5:20 + --> $DIR/bad-item-bound-within-rpitit-2.rs:4:20 | LL | fn bar<'other: 'a>() -> impl Sized + 'a {} | ^^ undeclared lifetime @@ -14,7 +14,7 @@ LL | trait Foo<'a> { | ++++ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/bad-item-bound-within-rpitit-2.rs:5:42 + --> $DIR/bad-item-bound-within-rpitit-2.rs:4:42 | LL | fn bar<'other: 'a>() -> impl Sized + 'a {} | ^^ undeclared lifetime @@ -28,15 +28,6 @@ help: consider introducing lifetime `'a` here LL | trait Foo<'a> { | ++++ -error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/bad-item-bound-within-rpitit-2.rs:5:45 - | -LL | fn bar<'other: 'a>() -> impl Sized + 'a {} - | ------ ^^ - | | - | cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +error: aborting due to 2 previous errors -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0261, E0792. -For more information about an error, try `rustc --explain E0261`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/impl-trait/issues/issue-67830.rs b/tests/ui/impl-trait/issues/issue-67830.rs index 939eca82a8f6..28772fa52720 100644 --- a/tests/ui/impl-trait/issues/issue-67830.rs +++ b/tests/ui/impl-trait/issues/issue-67830.rs @@ -7,7 +7,7 @@ struct Wrap(F); impl MyFn for Wrap where - F: Fn(A) -> B + F: Fn(A) -> B, { type Output = B; @@ -16,13 +16,10 @@ where } } - struct A; -fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { +fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` Wrap(|a| Some(a).into_iter()) - //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `FnOnce` is not general enough } fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-67830.stderr b/tests/ui/impl-trait/issues/issue-67830.stderr index ef513a40cf39..a7633c7f20b6 100644 --- a/tests/ui/impl-trait/issues/issue-67830.stderr +++ b/tests/ui/impl-trait/issues/issue-67830.stderr @@ -1,34 +1,15 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-67830.rs:21:62 + --> $DIR/issue-67830.rs:20:64 | -LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { - | ^^ +LL | fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> { + | ^^ | note: lifetime declared here - --> $DIR/issue-67830.rs:21:23 + --> $DIR/issue-67830.rs:20:23 | -LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { +LL | fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> { | ^^ -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-67830.rs:23:5 - | -LL | Wrap(|a| Some(a).into_iter()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` - -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-67830.rs:23:5 - | -LL | Wrap(|a| Some(a).into_iter()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/issues/issue-88236-2.rs b/tests/ui/impl-trait/issues/issue-88236-2.rs index 7ff08d8174f8..5005af46ee18 100644 --- a/tests/ui/impl-trait/issues/issue-88236-2.rs +++ b/tests/ui/impl-trait/issues/issue-88236-2.rs @@ -18,16 +18,11 @@ fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` &() - //~^ ERROR implementation of `Hrtb` is not general enough - //~| ERROR implementation of `Hrtb` is not general enough } fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` x - //~^ ERROR implementation of `Hrtb` is not general enough - //~| ERROR implementation of `Hrtb` is not general enough - //~| ERROR lifetime may not live long enough } fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-88236-2.stderr b/tests/ui/impl-trait/issues/issue-88236-2.stderr index 09fd58056a56..4ded9ed386fa 100644 --- a/tests/ui/impl-trait/issues/issue-88236-2.stderr +++ b/tests/ui/impl-trait/issues/issue-88236-2.stderr @@ -22,72 +22,18 @@ note: lifetime declared here LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:20:5 - | -LL | &() - | ^^^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:20:5 - | -LL | &() - | ^^^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'a>` would have to be implemented for the type `&()` - = note: ...but `Hrtb<'0>` is actually implemented for the type `&'0 ()`, for some specific lifetime `'0` - error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-88236-2.rs:25:78 + --> $DIR/issue-88236-2.rs:23:78 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ | note: lifetime declared here - --> $DIR/issue-88236-2.rs:25:45 + --> $DIR/issue-88236-2.rs:23:45 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ -error: lifetime may not live long enough - --> $DIR/issue-88236-2.rs:27:5 - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - | -- lifetime `'b` defined here -LL | -LL | x - | ^ returning this value requires that `'b` must outlive `'static` - | -help: to declare that `impl for<'a> Hrtb<'a, Assoc = impl Send + '_>` captures data from argument `x`, you can add an explicit `'b` lifetime bound - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b { - | ++++ -help: to declare that `impl Send + 'a` captures data from argument `x`, you can add an explicit `'b` lifetime bound - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a + 'b> { - | ++++ - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:27:5 - | -LL | x - | ^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:27:5 - | -LL | x - | ^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'a>` would have to be implemented for the type `&()` - = note: ...but `Hrtb<'0>` is actually implemented for the type `&'0 ()`, for some specific lifetime `'0` - -error: aborting due to 8 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.rs b/tests/ui/impl-trait/nested-rpit-hrtb.rs index 9b18aceb4a73..11d79bcff737 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.rs +++ b/tests/ui/impl-trait/nested-rpit-hrtb.rs @@ -31,7 +31,6 @@ fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` -//~| ERROR implementation of `Bar` is not general enough fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` @@ -64,6 +63,5 @@ fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux< // `'b` is not in scope for the outlives bound. fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} //~^ ERROR use of undeclared lifetime name `'b` [E0261] -//~| ERROR implementation of `Bar` is not general enough fn main() {} diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr index 2fa036f35fab..d98de650d0d8 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:57:77 + --> $DIR/nested-rpit-hrtb.rs:56:77 | LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -15,7 +15,7 @@ LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Siz | ++++ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:65:82 + --> $DIR/nested-rpit-hrtb.rs:64:82 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -65,29 +65,20 @@ note: lifetime declared here LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} | ^^ -error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:32:78 - | -LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} - | ^^ implementation of `Bar` is not general enough - | - = note: `()` must implement `Bar<'a>` - = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` - error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:36:73 + --> $DIR/nested-rpit-hrtb.rs:35:73 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ | note: lifetime declared here - --> $DIR/nested-rpit-hrtb.rs:36:44 + --> $DIR/nested-rpit-hrtb.rs:35:44 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ error[E0277]: the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:46:79 + --> $DIR/nested-rpit-hrtb.rs:45:79 | LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} | ^^^^^^^^^^^^ the trait `for<'a> Qux<'b>` is not implemented for `&'a ()` @@ -96,7 +87,7 @@ LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = help: for that trait implementation, expected `()`, found `&'a ()` error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:50:93 + --> $DIR/nested-rpit-hrtb.rs:49:93 | LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} | ^^ implementation of `Bar` is not general enough @@ -105,7 +96,7 @@ LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` error[E0277]: the trait bound `for<'a, 'b> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:61:64 + --> $DIR/nested-rpit-hrtb.rs:60:64 | LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Qux<'b>` is not implemented for `&'a ()` @@ -113,16 +104,7 @@ LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> = help: the trait `Qux<'_>` is implemented for `()` = help: for that trait implementation, expected `()`, found `&'a ()` -error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:65:86 - | -LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} - | ^^ implementation of `Bar` is not general enough - | - = note: `()` must implement `Bar<'a>` - = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` - -error: aborting due to 11 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0261, E0277, E0657. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr index fbd41b61730e..9ea4ff7cc70a 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.stderr +++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr @@ -13,8 +13,8 @@ LL | fun(filter_positive()); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | const fn with_positive Fn(&'a Alias<'a>) + ~const Destruct + ~const std::ops::Fn<(&Alias<'_>,)>>(fun: F) { - | ++++++++++++++++++++++++++++++++++++ +LL | const fn with_positive Fn(&'a Alias<'a>) + ~const Destruct + ~const Fn(&Alias<'_>)>(fun: F) { + | +++++++++++++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] diff --git a/tests/ui/indexing/index-bounds.rs b/tests/ui/indexing/index-bounds.rs new file mode 100644 index 000000000000..2b318beeeaa7 --- /dev/null +++ b/tests/ui/indexing/index-bounds.rs @@ -0,0 +1,10 @@ +//@ build-fail + +fn main() { + let _n = [64][200]; + //~^ ERROR this operation will panic at runtime [unconditional_panic] + + // issue #121126, test index value between 0xFFFF_FF00 and u32::MAX + let _n = [64][u32::MAX as usize - 1]; + //~^ ERROR this operation will panic at runtime [unconditional_panic] +} diff --git a/tests/ui/indexing/index-bounds.stderr b/tests/ui/indexing/index-bounds.stderr new file mode 100644 index 000000000000..51d8c7567a46 --- /dev/null +++ b/tests/ui/indexing/index-bounds.stderr @@ -0,0 +1,16 @@ +error: this operation will panic at runtime + --> $DIR/index-bounds.rs:4:14 + | +LL | let _n = [64][200]; + | ^^^^^^^^^ index out of bounds: the length is 1 but the index is 200 + | + = note: `#[deny(unconditional_panic)]` on by default + +error: this operation will panic at runtime + --> $DIR/index-bounds.rs:8:14 + | +LL | let _n = [64][u32::MAX as usize - 1]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 4294967294 + +error: aborting due to 2 previous errors + diff --git a/tests/ui/inference/issue-83606.rs b/tests/ui/inference/issue-83606.rs index 4454b5e60f06..e6e291c3a920 100644 --- a/tests/ui/inference/issue-83606.rs +++ b/tests/ui/inference/issue-83606.rs @@ -6,5 +6,5 @@ fn foo(_: impl std::fmt::Display) -> [usize; N] { fn main() { let _ = foo("foo"); - //~^ ERROR type annotations needed for `[usize; _]` + //~^ ERROR type annotations needed } diff --git a/tests/ui/inline-const/uninit_local.rs b/tests/ui/inline-const/uninit_local.rs new file mode 100644 index 000000000000..548c053affc7 --- /dev/null +++ b/tests/ui/inline-const/uninit_local.rs @@ -0,0 +1,6 @@ +fn main() { + let _my_usize = const { + let x: bool; + while x {} //~ ERROR: `x` isn't initialized + }; +} diff --git a/tests/ui/inline-const/uninit_local.stderr b/tests/ui/inline-const/uninit_local.stderr new file mode 100644 index 000000000000..37b78e337e7b --- /dev/null +++ b/tests/ui/inline-const/uninit_local.stderr @@ -0,0 +1,16 @@ +error[E0381]: used binding `x` isn't initialized + --> $DIR/uninit_local.rs:4:15 + | +LL | let x: bool; + | - binding declared here but left uninitialized +LL | while x {} + | ^ `x` used here but it isn't initialized + | +help: consider assigning a value + | +LL | let x: bool = false; + | +++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0381`. diff --git a/tests/ui/instrument-coverage/mcdc-condition-limit.bad.stderr b/tests/ui/instrument-coverage/mcdc-condition-limit.bad.stderr index 4d8d7e1560d0..5df6aaf98041 100644 --- a/tests/ui/instrument-coverage/mcdc-condition-limit.bad.stderr +++ b/tests/ui/instrument-coverage/mcdc-condition-limit.bad.stderr @@ -1,4 +1,4 @@ -warning: Conditions number of the decision (7) exceeds limit (6). MCDC analysis will not count this expression. +warning: Number of conditions in decision (7) exceeds limit (6). MC/DC analysis will not count this expression. --> $DIR/mcdc-condition-limit.rs:29:8 | LL | if a && b && c && d && e && f && g { diff --git a/tests/ui/instrument-coverage/mcdc-condition-limit.rs b/tests/ui/instrument-coverage/mcdc-condition-limit.rs index 64c5f8e9b779..de3770b5709d 100644 --- a/tests/ui/instrument-coverage/mcdc-condition-limit.rs +++ b/tests/ui/instrument-coverage/mcdc-condition-limit.rs @@ -26,7 +26,7 @@ fn main() { fn main() { // 7 conditions is too many, so issue a diagnostic. let [a, b, c, d, e, f, g] = <[bool; 7]>::default(); - if a && b && c && d && e && f && g { //[bad]~ WARNING Conditions number of the decision + if a && b && c && d && e && f && g { //[bad]~ WARNING Number of conditions in decision core::hint::black_box("hello"); } } diff --git a/tests/ui/intrinsics/const-eval-select-bad.stderr b/tests/ui/intrinsics/const-eval-select-bad.stderr index 85e22178c4a6..50092edda4f7 100644 --- a/tests/ui/intrinsics/const-eval-select-bad.stderr +++ b/tests/ui/intrinsics/const-eval-select-bad.stderr @@ -24,7 +24,7 @@ LL | const_eval_select((), 42, 0xDEADBEEF); | | | required by a bound introduced by this call | - = help: the trait `FnOnce<()>` is not implemented for `{integer}` + = help: the trait `FnOnce()` is not implemented for `{integer}` = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `const_eval_select` --> $SRC_DIR/core/src/intrinsics.rs:LL:COL @@ -37,7 +37,7 @@ LL | const_eval_select((), 42, 0xDEADBEEF); | | | required by a bound introduced by this call | - = help: the trait `FnOnce<()>` is not implemented for `{integer}` + = help: the trait `FnOnce()` is not implemented for `{integer}` = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `const_eval_select` --> $SRC_DIR/core/src/intrinsics.rs:LL:COL diff --git a/tests/ui/issues/issue-22034.stderr b/tests/ui/issues/issue-22034.stderr index 75ddcd478992..68202085e77d 100644 --- a/tests/ui/issues/issue-22034.stderr +++ b/tests/ui/issues/issue-22034.stderr @@ -4,7 +4,7 @@ error[E0277]: expected a `Fn()` closure, found `()` LL | &mut *(ptr as *mut dyn Fn()) | ^^^ expected an `Fn()` closure, found `()` | - = help: the trait `Fn<()>` is not implemented for `()` + = help: the trait `Fn()` is not implemented for `()` = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` = note: required for the cast from `*mut ()` to `*mut dyn Fn()` diff --git a/tests/ui/issues/issue-23543.rs b/tests/ui/issues/issue-23543.rs index 843e1a8a83ae..248bf77a7083 100644 --- a/tests/ui/issues/issue-23543.rs +++ b/tests/ui/issues/issue-23543.rs @@ -5,7 +5,7 @@ struct Foo; pub trait D { fn f(self) where T: A; - //~^ ERROR associated type bindings are not allowed here [E0229] + //~^ ERROR associated item constraints are not allowed here [E0229] } fn main() {} diff --git a/tests/ui/issues/issue-23543.stderr b/tests/ui/issues/issue-23543.stderr index d917a4c51d59..17243aefbbcd 100644 --- a/tests/ui/issues/issue-23543.stderr +++ b/tests/ui/issues/issue-23543.stderr @@ -1,8 +1,8 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-23543.rs:7:17 | LL | where T: A; - | ^^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^^ associated item constraint not allowed here error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-23544.rs b/tests/ui/issues/issue-23544.rs index 6ad00b2fba4b..bbd05a59353d 100644 --- a/tests/ui/issues/issue-23544.rs +++ b/tests/ui/issues/issue-23544.rs @@ -3,7 +3,7 @@ pub trait A: Copy {} pub trait D { fn f(self) where T: A; - //~^ ERROR associated type bindings are not allowed here [E0229] + //~^ ERROR associated item constraints are not allowed here [E0229] } fn main() {} diff --git a/tests/ui/issues/issue-23544.stderr b/tests/ui/issues/issue-23544.stderr index 2a7e93f0eb71..8d652a9da279 100644 --- a/tests/ui/issues/issue-23544.stderr +++ b/tests/ui/issues/issue-23544.stderr @@ -1,8 +1,8 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-23544.rs:5:17 | LL | where T: A; - | ^^^^^^^^^^^^^^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^^^^^^^^^^^^^^ associated item constraint not allowed here error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-23966.stderr b/tests/ui/issues/issue-23966.stderr index c29e88614442..3f7a4fa312f1 100644 --- a/tests/ui/issues/issue-23966.stderr +++ b/tests/ui/issues/issue-23966.stderr @@ -6,7 +6,7 @@ LL | "".chars().fold(|_, _| (), ()); | | | required by a bound introduced by this call | - = help: the trait `FnMut<(_, char)>` is not implemented for `()` + = help: the trait `FnMut(_, char)` is not implemented for `()` note: required by a bound in `fold` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL diff --git a/tests/ui/issues/issue-24682.rs b/tests/ui/issues/issue-24682.rs index 0d1ab73417c0..1bd42f3cbe3e 100644 --- a/tests/ui/issues/issue-24682.rs +++ b/tests/ui/issues/issue-24682.rs @@ -2,17 +2,17 @@ trait A: Sized { type N; fn x() -> Self< - N= //~ ERROR associated type bindings are not allowed here + N= //~ ERROR associated item constraints are not allowed here Self::N> { loop {} } fn y(&self) -> std - //~ ERROR associated type bindings are not allowed here + //~ ERROR associated item constraints are not allowed here ::option::Option<()> { None } fn z(&self) -> - u32 //~ ERROR associated type bindings are not allowed here + u32 //~ ERROR associated item constraints are not allowed here { 42 } } diff --git a/tests/ui/issues/issue-24682.stderr b/tests/ui/issues/issue-24682.stderr index e1943bf4d683..a107e8b52cd5 100644 --- a/tests/ui/issues/issue-24682.stderr +++ b/tests/ui/issues/issue-24682.stderr @@ -1,21 +1,21 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-24682.rs:5:11 | LL | / N= LL | | Self::N> { - | |_________________^ associated type not allowed here + | |_________________^ associated item constraint not allowed here -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-24682.rs:11:13 | LL | - | ^^^^ associated type not allowed here + | ^^^^ associated item constraint not allowed here -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-24682.rs:15:13 | LL | u32 - | ^^^^ associated type not allowed here + | ^^^^ associated item constraint not allowed here error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-39687.rs b/tests/ui/issues/issue-39687.rs index cbb721fbb57c..58f981b63d11 100644 --- a/tests/ui/issues/issue-39687.rs +++ b/tests/ui/issues/issue-39687.rs @@ -2,5 +2,5 @@ fn main() { ::call; - //~^ ERROR associated type bindings are not allowed here [E0229] + //~^ ERROR associated item constraints are not allowed here [E0229] } diff --git a/tests/ui/issues/issue-39687.stderr b/tests/ui/issues/issue-39687.stderr index f4742115a199..87e5fdc2d8f2 100644 --- a/tests/ui/issues/issue-39687.stderr +++ b/tests/ui/issues/issue-39687.stderr @@ -1,8 +1,8 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-39687.rs:4:14 | LL | ::call; - | ^^^^ associated type not allowed here + | ^^^^ associated item constraint not allowed here error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-43431.rs b/tests/ui/issues/issue-43431.rs index e7ec35105f75..0286336910e1 100644 --- a/tests/ui/issues/issue-43431.rs +++ b/tests/ui/issues/issue-43431.rs @@ -7,7 +7,7 @@ trait CallSingle { impl B> CallSingle for F { fn call(&self, a: A) -> B { B>::call(self, (a,)) - //~^ ERROR associated type bindings are not allowed here + //~^ ERROR associated item constraints are not allowed here } } diff --git a/tests/ui/issues/issue-43431.stderr b/tests/ui/issues/issue-43431.stderr index 6d47ba271624..27a720408e4b 100644 --- a/tests/ui/issues/issue-43431.stderr +++ b/tests/ui/issues/issue-43431.stderr @@ -1,8 +1,8 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-43431.rs:9:27 | LL | B>::call(self, (a,)) - | ^ associated type not allowed here + | ^ associated item constraint not allowed here error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-50781.rs b/tests/ui/issues/issue-50781.rs index 3c5e5a9f69af..32253c3c2360 100644 --- a/tests/ui/issues/issue-50781.rs +++ b/tests/ui/issues/issue-50781.rs @@ -1,10 +1,7 @@ -#![deny(where_clauses_object_safety)] - trait Trait {} trait X { - fn foo(&self) where Self: Trait; //~ ERROR the trait `X` cannot be made into an object - //~^ WARN this was previously accepted by the compiler but is being phased out + fn foo(&self) where Self: Trait; } impl X for () { @@ -12,8 +9,11 @@ impl X for () { } impl Trait for dyn X {} +//~^ ERROR the trait `X` cannot be made into an object pub fn main() { // Check that this does not segfault. ::foo(&()); + //~^ ERROR the trait `X` cannot be made into an object + //~| ERROR the trait `X` cannot be made into an object } diff --git a/tests/ui/issues/issue-50781.stderr b/tests/ui/issues/issue-50781.stderr index beaea1e634ce..6b0b42ca53a6 100644 --- a/tests/ui/issues/issue-50781.stderr +++ b/tests/ui/issues/issue-50781.stderr @@ -1,24 +1,52 @@ -error: the trait `X` cannot be made into an object - --> $DIR/issue-50781.rs:6:8 +error[E0038]: the trait `X` cannot be made into an object + --> $DIR/issue-50781.rs:11:16 | -LL | fn foo(&self) where Self: Trait; - | ^^^ +LL | impl Trait for dyn X {} + | ^^^^^ `X` cannot be made into an object | - = 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 #51443 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-50781.rs:6:8 + --> $DIR/issue-50781.rs:4:8 | LL | trait X { | - this trait cannot be made into an object... LL | fn foo(&self) where Self: Trait; | ^^^ ...because method `foo` references the `Self` type in its `where` clause = help: consider moving `foo` to another trait -note: the lint level is defined here - --> $DIR/issue-50781.rs:1:9 + = help: only type `()` implements the trait, consider using it directly instead + +error[E0038]: the trait `X` cannot be made into an object + --> $DIR/issue-50781.rs:16:23 | -LL | #![deny(where_clauses_object_safety)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ::foo(&()); + | ^^^ `X` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-50781.rs:4:8 + | +LL | trait X { + | - this trait cannot be made into an object... +LL | fn foo(&self) where Self: Trait; + | ^^^ ...because method `foo` references the `Self` type in its `where` clause + = help: consider moving `foo` to another trait + = help: only type `()` implements the trait, consider using it directly instead + = note: required for the cast from `&()` to `&dyn X` -error: aborting due to 1 previous error +error[E0038]: the trait `X` cannot be made into an object + --> $DIR/issue-50781.rs:16:6 + | +LL | ::foo(&()); + | ^^^^^ `X` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-50781.rs:4:8 + | +LL | trait X { + | - this trait cannot be made into an object... +LL | fn foo(&self) where Self: Trait; + | ^^^ ...because method `foo` references the `Self` type in its `where` clause + = help: consider moving `foo` to another trait + = help: only type `()` implements the trait, consider using it directly instead +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/layout/issue-84108.rs b/tests/ui/layout/issue-84108.rs index 425da65b9905..974d5310f6bb 100644 --- a/tests/ui/layout/issue-84108.rs +++ b/tests/ui/layout/issue-84108.rs @@ -8,6 +8,9 @@ static FOO: (dyn AsRef, u8) = ("hello", 42); const BAR: (&Path, [u8], usize) = ("hello", [], 42); //~^ ERROR cannot find type `Path` in this scope +//~| ERROR the size for values of type `[u8]` cannot be known at compilation time +//~| ERROR the size for values of type `[u8]` cannot be known at compilation time +//~| ERROR mismatched types static BAZ: ([u8], usize) = ([], 0); //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index 6c168cc5fa84..8ddce285e23f 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -21,7 +21,35 @@ LL + use std::path::Path; | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:12:13 + --> $DIR/issue-84108.rs:9:12 + | +LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/issue-84108.rs:9:12 + | +LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0308]: mismatched types + --> $DIR/issue-84108.rs:9:45 + | +LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); + | ^^ expected `[u8]`, found `[_; 0]` + | + = note: expected slice `[u8]` + found array `[_; 0]` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/issue-84108.rs:15:13 | LL | static BAZ: ([u8], usize) = ([], 0); | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -30,7 +58,7 @@ LL | static BAZ: ([u8], usize) = ([], 0); = note: only the last element of a tuple may have a dynamically sized type error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:12:13 + --> $DIR/issue-84108.rs:15:13 | LL | static BAZ: ([u8], usize) = ([], 0); | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -40,7 +68,7 @@ LL | static BAZ: ([u8], usize) = ([], 0); = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0308]: mismatched types - --> $DIR/issue-84108.rs:12:30 + --> $DIR/issue-84108.rs:15:30 | LL | static BAZ: ([u8], usize) = ([], 0); | ^^ expected `[u8]`, found `[_; 0]` @@ -48,7 +76,7 @@ LL | static BAZ: ([u8], usize) = ([], 0); = note: expected slice `[u8]` found array `[_; 0]` -error: aborting due to 5 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0277, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/lifetimes/issue-69314.fixed b/tests/ui/lifetimes/issue-69314.fixed index 285d192b44c7..ee1675724fb1 100644 --- a/tests/ui/lifetimes/issue-69314.fixed +++ b/tests/ui/lifetimes/issue-69314.fixed @@ -11,7 +11,7 @@ impl A { } async fn f() { let mut buf = [0; 512]; - let m2 = &buf[..]; //~ ERROR `buf` does not live long enough + let m2 = &buf[..]; let m = Self::g(m2).await; Self::f2(m).await; } diff --git a/tests/ui/lifetimes/issue-69314.rs b/tests/ui/lifetimes/issue-69314.rs index 345f77850608..f9e5196b2c74 100644 --- a/tests/ui/lifetimes/issue-69314.rs +++ b/tests/ui/lifetimes/issue-69314.rs @@ -11,7 +11,7 @@ impl A { } async fn f() { let mut buf = [0; 512]; - let m2 = &buf[..]; //~ ERROR `buf` does not live long enough + let m2 = &buf[..]; let m = Self::g(m2).await; Self::f2(m).await; } diff --git a/tests/ui/lifetimes/issue-69314.stderr b/tests/ui/lifetimes/issue-69314.stderr index 3879f35505c2..67da54e8dcd7 100644 --- a/tests/ui/lifetimes/issue-69314.stderr +++ b/tests/ui/lifetimes/issue-69314.stderr @@ -9,20 +9,6 @@ help: indicate the anonymous lifetime LL | async fn f2(m: Msg<'_>) {} | ++++ -error[E0597]: `buf` does not live long enough - --> $DIR/issue-69314.rs:14:19 - | -LL | let mut buf = [0; 512]; - | ------- binding `buf` declared here -LL | let m2 = &buf[..]; - | ^^^ borrowed value does not live long enough -LL | let m = Self::g(m2).await; - | ----------- argument requires that `buf` is borrowed for `'static` -LL | Self::f2(m).await; -LL | } - | - `buf` dropped here while still borrowed +error: aborting due to 1 previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0597, E0726. -For more information about an error, try `rustc --explain E0597`. +For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr index e9f97d1d93bd..e8c3ab00226e 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr @@ -10,7 +10,7 @@ LL | | F:, LL | | for<'a> >::Output: Future + 'a, | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | - = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` + = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` --> $DIR/issue-76168-hr-outlives-3.rs:6:10 @@ -18,7 +18,7 @@ error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` LL | async fn wrapper(f: F) | ^^^^^^^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | - = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` + = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` --> $DIR/issue-76168-hr-outlives-3.rs:6:1 @@ -32,7 +32,7 @@ LL | | F:, LL | | for<'a> >::Output: Future + 'a, | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | - = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` + = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` --> $DIR/issue-76168-hr-outlives-3.rs:6:1 @@ -46,7 +46,7 @@ LL | | F:, LL | | for<'a> >::Output: Future + 'a, | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | - = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` + = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` @@ -59,7 +59,7 @@ LL | | &mut i; LL | | } | |_^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | - = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` + = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` error: aborting due to 5 previous errors diff --git a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs index a47e71afcf0b..78069e682c13 100644 --- a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs +++ b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs @@ -3,6 +3,6 @@ struct Foo {} impl Foo { fn bar(foo: Foo) {} - //~^ associated type bindings are not allowed here + //~^ associated item constraints are not allowed here } fn main() {} diff --git a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr index d6da842e6aba..f8d919fd68b6 100644 --- a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr +++ b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr @@ -1,10 +1,10 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-83753-invalid-associated-type-supertrait-hrtb.rs:5:21 | LL | fn bar(foo: Foo) {} - | ^^^^^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^^^^^ associated item constraint not allowed here | -help: consider removing this type binding +help: consider removing this associated item binding | LL | fn bar(foo: Foo) {} | ~~~~~~~~~~~~~~~~ diff --git a/tests/ui/lifetimes/issue-95023.rs b/tests/ui/lifetimes/issue-95023.rs index ee39a8c49c05..7a67297c7632 100644 --- a/tests/ui/lifetimes/issue-95023.rs +++ b/tests/ui/lifetimes/issue-95023.rs @@ -2,7 +2,7 @@ struct ErrorKind; struct Error(ErrorKind); impl Fn(&isize) for Error { //~^ ERROR manual implementations of `Fn` are experimental [E0183] - //~^^ ERROR associated type bindings are not allowed here [E0229] + //~^^ ERROR associated item constraints are not allowed here [E0229] //~| ERROR not all trait items implemented //~| ERROR expected a `FnMut(&isize)` closure, found `Error` fn foo(&self) -> Self::B<{ N }>; diff --git a/tests/ui/lifetimes/issue-95023.stderr b/tests/ui/lifetimes/issue-95023.stderr index c4285dbf4bdb..310dee514060 100644 --- a/tests/ui/lifetimes/issue-95023.stderr +++ b/tests/ui/lifetimes/issue-95023.stderr @@ -20,11 +20,11 @@ LL | impl Fn(&isize) for Error { | = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/issue-95023.rs:3:6 | LL | impl Fn(&isize) for Error { - | ^^^^^^^^^^ associated type not allowed here + | ^^^^^^^^^^ associated item constraint not allowed here | help: parenthesized trait syntax expands to `Fn<(&isize,), Output=()>` --> $DIR/issue-95023.rs:3:6 @@ -38,7 +38,7 @@ error[E0277]: expected a `FnMut(&isize)` closure, found `Error` LL | impl Fn(&isize) for Error { | ^^^^^ expected an `FnMut(&isize)` closure, found `Error` | - = help: the trait `FnMut<(&isize,)>` is not implemented for `Error` + = help: the trait `FnMut(&isize)` is not implemented for `Error` note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL diff --git a/tests/ui/lifetimes/noisy-follow-up-erro.rs b/tests/ui/lifetimes/noisy-follow-up-erro.rs new file mode 100644 index 000000000000..47a87068d8fb --- /dev/null +++ b/tests/ui/lifetimes/noisy-follow-up-erro.rs @@ -0,0 +1,23 @@ +struct Foo<'c, 'd>(&'c (), &'d ()); + +impl<'c, 'd> Foo<'c, 'd> { + fn acc(&mut self, _bar: &Bar) -> &'d () { + todo!() + } +} + +struct Bar; + +impl<'a> Bar { + fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> { + //~^ ERROR: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied + self.bar().map_err(|()| foo.acc(self))?; + //~^ ERROR: explicit lifetime required in the type of `foo` + Ok(()) + } + fn bar(&self) -> Result<(), &'a ()> { + todo!() + } +} + +fn main() {} diff --git a/tests/ui/lifetimes/noisy-follow-up-erro.stderr b/tests/ui/lifetimes/noisy-follow-up-erro.stderr new file mode 100644 index 000000000000..f549009a87c1 --- /dev/null +++ b/tests/ui/lifetimes/noisy-follow-up-erro.stderr @@ -0,0 +1,27 @@ +error[E0107]: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied + --> $DIR/noisy-follow-up-erro.rs:12:30 + | +LL | fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> { + | ^^^ -- help: remove this lifetime argument + | | + | expected 2 lifetime arguments + | +note: struct defined here, with 2 lifetime parameters: `'c`, `'d` + --> $DIR/noisy-follow-up-erro.rs:1:8 + | +LL | struct Foo<'c, 'd>(&'c (), &'d ()); + | ^^^ -- -- + +error[E0621]: explicit lifetime required in the type of `foo` + --> $DIR/noisy-follow-up-erro.rs:14:9 + | +LL | fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> { + | -------------------- help: add explicit lifetime `'a` to the type of `foo`: `&mut Foo<'_, 'a>` +LL | +LL | self.bar().map_err(|()| foo.acc(self))?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0107, E0621. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/lifetimes/unusual-rib-combinations.rs b/tests/ui/lifetimes/unusual-rib-combinations.rs index 3bc87b9d480b..0708a00d3715 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.rs +++ b/tests/ui/lifetimes/unusual-rib-combinations.rs @@ -2,9 +2,8 @@ struct S<'a>(&'a u8); fn foo() {} // Paren generic args in AnonConst -fn a() -> [u8; foo::()] { -//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait -//~| ERROR mismatched types +fn a() -> [u8; foo()] { + //~^ ERROR mismatched types panic!() } @@ -26,5 +25,6 @@ fn d() {} trait Foo<'a> {} struct Bar Foo<'a>)>; //~^ ERROR the type of const parameters must not depend on other generic parameters +//~| ERROR `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter fn main() {} diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr index 2857fc72ea14..70f06b4be603 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.stderr +++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr @@ -1,11 +1,11 @@ error[E0106]: missing lifetime specifier - --> $DIR/unusual-rib-combinations.rs:22:15 + --> $DIR/unusual-rib-combinations.rs:21:15 | LL | fn d() {} | ^ expected named lifetime parameter error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/unusual-rib-combinations.rs:27:22 + --> $DIR/unusual-rib-combinations.rs:26:22 | LL | struct Bar Foo<'a>)>; | ^^ the type must not depend on the parameter `'a` @@ -13,25 +13,19 @@ LL | struct Bar Foo<'a>)>; = note: lifetime parameters may not be used in the type of const parameters error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/unusual-rib-combinations.rs:5:16 - | -LL | fn a() -> [u8; foo::()] { - | ^^^^^^^ only `Fn` traits may use parentheses - -error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/unusual-rib-combinations.rs:12:15 + --> $DIR/unusual-rib-combinations.rs:11:15 | LL | fn b() {} | ^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/unusual-rib-combinations.rs:16:10 + --> $DIR/unusual-rib-combinations.rs:15:10 | LL | fn c() {} | ^^^^ only `Fn` traits may use parentheses error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/unusual-rib-combinations.rs:16:6 + --> $DIR/unusual-rib-combinations.rs:15:6 | LL | fn c() {} | ^^^^^^^^ @@ -43,14 +37,11 @@ LL | fn c() {} error[E0308]: mismatched types --> $DIR/unusual-rib-combinations.rs:5:16 | -LL | fn a() -> [u8; foo::()] { - | ^^^^^^^ expected `usize`, found fn item - | - = note: expected type `usize` - found fn item `fn() {foo}` +LL | fn a() -> [u8; foo()] { + | ^^^^^ expected `usize`, found `()` error: `S<'_>` is forbidden as the type of a const generic parameter - --> $DIR/unusual-rib-combinations.rs:22:15 + --> $DIR/unusual-rib-combinations.rs:21:15 | LL | fn d() {} | ^ @@ -61,6 +52,18 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more LL + #![feature(adt_const_params)] | +error: `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter + --> $DIR/unusual-rib-combinations.rs:26:21 + | +LL | struct Bar Foo<'a>)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` +help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + | +LL + #![feature(adt_const_params)] + | + error: aborting due to 8 previous errors Some errors have detailed explanations: E0106, E0214, E0308, E0770. diff --git a/tests/ui/macros/expand-full-no-resolution.stderr b/tests/ui/macros/expand-full-no-resolution.stderr index 2537a5032a92..df6f20332bfd 100644 --- a/tests/ui/macros/expand-full-no-resolution.stderr +++ b/tests/ui/macros/expand-full-no-resolution.stderr @@ -7,7 +7,7 @@ LL | macro_rules! _a { LL | format_args!(a!()); | ^ | -help: a macro with a similar name exists, consider renaming `_a` into `a` +help: the leading underscore in `_a` marks it as unused, consider renaming it to `a` | LL | macro_rules! a { | ~ @@ -21,7 +21,7 @@ LL | macro_rules! _a { LL | env!(a!()); | ^ | -help: a macro with a similar name exists, consider renaming `_a` into `a` +help: the leading underscore in `_a` marks it as unused, consider renaming it to `a` | LL | macro_rules! a { | ~ diff --git a/tests/ui/methods/method-call-type-binding.rs b/tests/ui/methods/method-call-type-binding.rs index f547ca8d1c2a..290c66fabe3b 100644 --- a/tests/ui/methods/method-call-type-binding.rs +++ b/tests/ui/methods/method-call-type-binding.rs @@ -1,3 +1,3 @@ fn main() { - 0.clone::(); //~ ERROR associated type bindings are not allowed here + 0.clone::(); //~ ERROR associated item constraints are not allowed here } diff --git a/tests/ui/methods/method-call-type-binding.stderr b/tests/ui/methods/method-call-type-binding.stderr index 54d855d340ea..1acb0b2e12b4 100644 --- a/tests/ui/methods/method-call-type-binding.stderr +++ b/tests/ui/methods/method-call-type-binding.stderr @@ -1,8 +1,8 @@ -error[E0229]: associated type bindings are not allowed here +error[E0229]: associated item constraints are not allowed here --> $DIR/method-call-type-binding.rs:2:15 | LL | 0.clone::(); - | ^^^^^^ associated type not allowed here + | ^^^^^^ associated item constraint not allowed here error: aborting due to 1 previous error diff --git a/tests/ui/mir/lint/assignment-overlap.rs b/tests/ui/mir/lint/assignment-overlap.rs index 806d09cda851..6396cccd4e88 100644 --- a/tests/ui/mir/lint/assignment-overlap.rs +++ b/tests/ui/mir/lint/assignment-overlap.rs @@ -9,11 +9,11 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn main() { - mir!( + mir! { let a: [u8; 1024]; { a = a; Return() } - ) + } } diff --git a/tests/ui/mir/lint/call-overlap.rs b/tests/ui/mir/lint/call-overlap.rs index eb806378fe54..def78ea1e3b1 100644 --- a/tests/ui/mir/lint/call-overlap.rs +++ b/tests/ui/mir/lint/call-overlap.rs @@ -9,7 +9,7 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn main() { - mir!( + mir! { let a: [u8; 1024]; { Call(a = f(Move(a)), ReturnTo(bb1), UnwindUnreachable()) @@ -17,7 +17,7 @@ pub fn main() { bb1 = { Return() } - ) + } } pub fn f(a: T) -> T { a } diff --git a/tests/ui/mir/lint/no-storage.rs b/tests/ui/mir/lint/no-storage.rs index 42dd1b963dc1..a6af8646f6ec 100644 --- a/tests/ui/mir/lint/no-storage.rs +++ b/tests/ui/mir/lint/no-storage.rs @@ -8,7 +8,7 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "built")] pub fn f(a: bool) { - mir!( + mir! { let b: (); { match a { true => bb1, _ => bb2 } @@ -26,5 +26,5 @@ pub fn f(a: bool) { StorageDead(b); Return() } - ) + } } diff --git a/tests/ui/mir/lint/storage-live.rs b/tests/ui/mir/lint/storage-live.rs index 5dea1cb3567e..8273544b56a1 100644 --- a/tests/ui/mir/lint/storage-live.rs +++ b/tests/ui/mir/lint/storage-live.rs @@ -15,14 +15,14 @@ use core::ptr::{addr_of, addr_of_mut}; #[custom_mir(dialect = "built")] fn multiple_storage() { - mir!( + mir! { let a: usize; { StorageLive(a); StorageLive(a); Return() } - ) + } } fn main() { diff --git a/tests/ui/mir/lint/storage-return.rs b/tests/ui/mir/lint/storage-return.rs index b6281d4b2a8e..d51aee9518fb 100644 --- a/tests/ui/mir/lint/storage-return.rs +++ b/tests/ui/mir/lint/storage-return.rs @@ -8,12 +8,12 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "built")] fn main() { - mir!( + mir! { let a: (); { StorageLive(a); RET = a; Return() } - ) + } } diff --git a/tests/ui/mir/mir_codegen_ssa.rs b/tests/ui/mir/mir_codegen_ssa.rs index bf01edcbaa84..1666b8293eba 100644 --- a/tests/ui/mir/mir_codegen_ssa.rs +++ b/tests/ui/mir/mir_codegen_ssa.rs @@ -5,7 +5,7 @@ use std::intrinsics::mir::*; #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn f(a: u32) -> u32 { - mir!( + mir! { let x: u32; { // Previously code generation failed with ICE "use of .. before def ..." because the @@ -15,5 +15,5 @@ pub fn f(a: u32) -> u32 { RET = x; Return() } - ) + } } diff --git a/tests/ui/mir/ssa_call_ret.rs b/tests/ui/mir/ssa_call_ret.rs index 9b2c78c737f1..baaa7326fd80 100644 --- a/tests/ui/mir/ssa_call_ret.rs +++ b/tests/ui/mir/ssa_call_ret.rs @@ -10,7 +10,7 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "runtime", phase = "optimized")] pub fn f() -> u32 { - mir!( + mir! { let a: u32; { Call(a = g(), ReturnTo(bb1), UnwindCleanup(bb2)) @@ -23,7 +23,7 @@ pub fn f() -> u32 { RET = a; UnwindResume() } - ) + } } #[inline(never)] diff --git a/tests/ui/mir/validate/critical-edge.rs b/tests/ui/mir/validate/critical-edge.rs index 0a548ae8e584..9048d08a22a7 100644 --- a/tests/ui/mir/validate/critical-edge.rs +++ b/tests/ui/mir/validate/critical-edge.rs @@ -12,7 +12,7 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "runtime", phase = "optimized")] #[inline(always)] pub fn f(a: u32) -> u32 { - mir!( + mir! { { match a { 0 => bb1, @@ -27,5 +27,5 @@ pub fn f(a: u32) -> u32 { RET = 2; Return() } - ) + } } diff --git a/tests/ui/mir/validate/noncleanup-cleanup.rs b/tests/ui/mir/validate/noncleanup-cleanup.rs index 744e71e99b10..b46bb46952b8 100644 --- a/tests/ui/mir/validate/noncleanup-cleanup.rs +++ b/tests/ui/mir/validate/noncleanup-cleanup.rs @@ -9,13 +9,12 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "built")] pub fn main() { - mir!( + mir! { { Call(RET = main(), ReturnTo(block), UnwindCleanup(block)) } block = { Return() } - ) - + } } diff --git a/tests/ui/mir/validate/noncleanup-resume.rs b/tests/ui/mir/validate/noncleanup-resume.rs index 5bf6b03c9e94..b2a0e92e0686 100644 --- a/tests/ui/mir/validate/noncleanup-resume.rs +++ b/tests/ui/mir/validate/noncleanup-resume.rs @@ -9,9 +9,9 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "built")] pub fn main() { - mir!( + mir! { { UnwindResume() } - ) + } } diff --git a/tests/ui/mir/validate/noncleanup-terminate.rs b/tests/ui/mir/validate/noncleanup-terminate.rs index b5bf2604cce6..24cf75e7d8e1 100644 --- a/tests/ui/mir/validate/noncleanup-terminate.rs +++ b/tests/ui/mir/validate/noncleanup-terminate.rs @@ -9,9 +9,9 @@ use core::intrinsics::mir::*; #[custom_mir(dialect = "built")] pub fn main() { - mir!( + mir! { { UnwindTerminate(ReasonAbi) } - ) + } } diff --git a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr index 99c9028ae1ef..a657a65c426d 100644 --- a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr +++ b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr @@ -26,7 +26,7 @@ LL | let _ = produces_string().and_then(takes_str_but_wrong_abi); | | | required by a bound introduced by this call | - = help: the trait `FnOnce<(String,)>` is not implemented for fn item `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}` + = help: the trait `FnOnce(String)` is not implemented for fn item `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}` note: required by a bound in `Option::::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL @@ -38,7 +38,7 @@ LL | let _ = produces_string().and_then(takes_str_but_unsafe); | | | required by a bound introduced by this call | - = help: the trait `FnOnce<(String,)>` is not implemented for fn item `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}` + = help: the trait `FnOnce(String)` is not implemented for fn item `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `Option::::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL diff --git a/tests/ui/object-safety/issue-106247.rs b/tests/ui/object-safety/issue-106247.rs index 78bae5681619..20a451a59a16 100644 --- a/tests/ui/object-safety/issue-106247.rs +++ b/tests/ui/object-safety/issue-106247.rs @@ -1,7 +1,5 @@ //@ check-pass -#![deny(where_clauses_object_safety)] - pub trait Trait { fn method(&self) where Self: Sync; } diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs index f6aa39df27d8..1c28c0632fa8 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs @@ -5,3 +5,4 @@ struct Apple((Apple, Option(Banana ? Citron))); //~| ERROR expected one of `)` or `,`, found `Citron` //~| ERROR cannot find type `Citron` in this scope [E0412] //~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214] +//~| ERROR `Apple` has infinite size diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr index 71d2d7b79758..b0d8b03ae08c 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr @@ -34,7 +34,18 @@ help: use angle brackets instead LL | struct Apple((Apple, Option)); | ~ ~ -error: aborting due to 4 previous errors +error[E0072]: recursive type `Apple` has infinite size + --> $DIR/issue-103748-ICE-wrong-braces.rs:3:1 + | +LL | struct Apple((Apple, Option(Banana ? Citron))); + | ^^^^^^^^^^^^ ----- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | struct Apple((Box, Option(Banana ? Citron))); + | ++++ + -Some errors have detailed explanations: E0214, E0412. -For more information about an error, try `rustc --explain E0214`. +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0072, E0214, E0412. +For more information about an error, try `rustc --explain E0072`. diff --git a/tests/ui/parser/macro/mbe-dotdotdot-may-not-begin-a-type.rs b/tests/ui/parser/macro/mbe-dotdotdot-may-not-begin-a-type.rs new file mode 100644 index 000000000000..8be99f22d2ee --- /dev/null +++ b/tests/ui/parser/macro/mbe-dotdotdot-may-not-begin-a-type.rs @@ -0,0 +1,11 @@ +// A bare `...` represents `CVarArgs` (`VaListImpl<'_>`) in function argument type +// position without being a proper type syntactically. +// This test ensures that we do not regress certain MBE calls would we ever promote +// `...` to a proper type syntactically. + +//@ check-pass + +macro_rules! ck { ($ty:ty) => { compile_error!(""); }; (...) => {}; } +ck!(...); + +fn main() {} diff --git a/tests/ui/parser/recover/recover-range-pats.stderr b/tests/ui/parser/recover/recover-range-pats.stderr index e0ea8ec24dcf..e29b6c1c666b 100644 --- a/tests/ui/parser/recover/recover-range-pats.stderr +++ b/tests/ui/parser/recover/recover-range-pats.stderr @@ -316,9 +316,6 @@ LL | if let X.. .0 = 0 {} | | | | | expected `u8`, found floating-point number | this is of type `u8` - | - = note: expected type `u8` - found type `{float}` error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:31:12 @@ -353,9 +350,6 @@ LL | if let X..=.0 = 0 {} | | | | | expected `u8`, found floating-point number | this is of type `u8` - | - = note: expected type `u8` - found type `{float}` error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:52:12 @@ -390,9 +384,6 @@ LL | if let X... .0 = 0 {} | | | | | expected `u8`, found floating-point number | this is of type `u8` - | - = note: expected type `u8` - found type `{float}` error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:71:12 diff --git a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs index 4da9ad84bab7..d9d3f9227a9e 100644 --- a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs +++ b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs @@ -4,6 +4,10 @@ fn f1<'a>(x: u8, y: &'a ...) {} fn f2<'a>(x: u8, y: Vec<&'a ...>) {} //~^ ERROR C-variadic type `...` may not be nested inside another type +// Regression test for issue #125847. +fn f3() where for<> ...: {} +//~^ ERROR C-variadic type `...` may not be nested inside another type + fn main() { let _recovery_witness: () = 0; //~^ ERROR: mismatched types diff --git a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr index 8b9d676a45da..38833d6555b1 100644 --- a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr +++ b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr @@ -10,15 +10,21 @@ error[E0743]: C-variadic type `...` may not be nested inside another type LL | fn f2<'a>(x: u8, y: Vec<&'a ...>) {} | ^^^ +error[E0743]: C-variadic type `...` may not be nested inside another type + --> $DIR/variadic-ffi-nested-syntactic-fail.rs:8:21 + | +LL | fn f3() where for<> ...: {} + | ^^^ + error[E0308]: mismatched types - --> $DIR/variadic-ffi-nested-syntactic-fail.rs:8:33 + --> $DIR/variadic-ffi-nested-syntactic-fail.rs:12:33 | LL | let _recovery_witness: () = 0; | -- ^ expected `()`, found integer | | | expected due to this -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0308, E0743. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/polymorphization/abi_mismatch.rs b/tests/ui/polymorphization/abi_mismatch.rs new file mode 100644 index 000000000000..22c2c162d1c1 --- /dev/null +++ b/tests/ui/polymorphization/abi_mismatch.rs @@ -0,0 +1,20 @@ +//! This test used to ICE: #123917 +//! The reason was that while the AST knows about two fields +//! named `ptr`, only one exists at the layout level, so accessing +//! `_extra_field` would use an oob index +//@ compile-flags: -Zmir-opt-level=5 -Zpolymorphize=on + +struct NonNull(*mut T); + +struct Token { + ptr: *mut T, + ptr: NonNull, + //~^ ERROR: `ptr` is already declared + _extra_field: (), +} + +fn tokenize(item: *mut T) -> Token { + Token { ptr: NonNull(item), _extra_field: () } +} + +fn main() {} diff --git a/tests/ui/polymorphization/abi_mismatch.stderr b/tests/ui/polymorphization/abi_mismatch.stderr new file mode 100644 index 000000000000..e96c737f7773 --- /dev/null +++ b/tests/ui/polymorphization/abi_mismatch.stderr @@ -0,0 +1,11 @@ +error[E0124]: field `ptr` is already declared + --> $DIR/abi_mismatch.rs:11:5 + | +LL | ptr: *mut T, + | ----------- `ptr` first declared here +LL | ptr: NonNull, + | ^^^^^^^^^^^^^^^ field already declared + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0124`. diff --git a/tests/ui/privacy/where-priv-type.rs b/tests/ui/privacy/where-priv-type.rs index cd9cce7ec3e8..a62feace2da2 100644 --- a/tests/ui/privacy/where-priv-type.rs +++ b/tests/ui/privacy/where-priv-type.rs @@ -74,6 +74,7 @@ where { type AssocTy = Const<{ my_const_fn(U) }>; //~^ ERROR private type + //~| ERROR private type fn assoc_fn() -> Self::AssocTy { Const } diff --git a/tests/ui/privacy/where-priv-type.stderr b/tests/ui/privacy/where-priv-type.stderr index 126330b14a63..8ea2e17c4361 100644 --- a/tests/ui/privacy/where-priv-type.stderr +++ b/tests/ui/privacy/where-priv-type.stderr @@ -77,6 +77,17 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>; LL | const fn my_const_fn(val: u8) -> u8 { | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private -error: aborting due to 1 previous error; 5 warnings emitted +error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface + --> $DIR/where-priv-type.rs:75:5 + | +LL | type AssocTy = Const<{ my_const_fn(U) }>; + | ^^^^^^^^^^^^ can't leak private type +... +LL | const fn my_const_fn(val: u8) -> u8 { + | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors; 5 warnings emitted For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/resolve/fn-new-doesnt-exist.rs b/tests/ui/resolve/fn-new-doesnt-exist.rs deleted file mode 100644 index 4f6290808fc0..000000000000 --- a/tests/ui/resolve/fn-new-doesnt-exist.rs +++ /dev/null @@ -1,5 +0,0 @@ -use std::net::TcpStream; - -fn main() { - let stream = TcpStream::new(); //~ ERROR no function or associated item named `new` found -} diff --git a/tests/ui/resolve/fn-new-doesnt-exist.stderr b/tests/ui/resolve/fn-new-doesnt-exist.stderr deleted file mode 100644 index 418dd9ea6b84..000000000000 --- a/tests/ui/resolve/fn-new-doesnt-exist.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0599]: no function or associated item named `new` found for struct `TcpStream` in the current scope - --> $DIR/fn-new-doesnt-exist.rs:4:28 - | -LL | let stream = TcpStream::new(); - | ^^^ function or associated item not found in `TcpStream` - | -note: if you're trying to build a new `TcpStream` consider using one of the following associated functions: - TcpStream::connect - TcpStream::connect_timeout - --> $SRC_DIR/std/src/net/tcp.rs:LL:COL - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/resolve/suggest-builder-fn.rs b/tests/ui/resolve/suggest-builder-fn.rs new file mode 100644 index 000000000000..0d9b35549a47 --- /dev/null +++ b/tests/ui/resolve/suggest-builder-fn.rs @@ -0,0 +1,64 @@ +// Tests that we suggest the right alternatives when +// a builder method cannot be resolved + +use std::net::TcpStream; + +trait SomeTrait {} + +struct Foo { + v : T +} + +impl Foo { + // Should not be suggested if constraint on the impl not met + fn new() -> Self { + Self { v: T::default() } + } +} + +struct Bar; + +impl Bar { + // Should be suggested + fn build() -> Self { + Self {} + } + + // Method with self can't be a builder. + // Should not be suggested + fn build_with_self(&self) -> Self { + Self {} + } +} + +mod SomeMod { + use Bar; + + impl Bar { + // Public method. Should be suggested + pub fn build_public() -> Self { + Self {} + } + + // Private method. Should not be suggested + fn build_private() -> Self { + Self {} + } + } +} + +fn main() { + // `new` not found on `TcpStream` and `connect` should be suggested + let _stream = TcpStream::new(); + //~^ ERROR no function or associated item named `new` found + + // Although `new` is found on `>` it should not be + // suggested because `u8` does not meet the `T: SomeTrait` constraint + let _foo = Foo::::new(); + //~^ ERROR the function or associated item `new` exists for struct `Foo`, but its trait bounds were not satisfied + + // Should suggest only `::build()` and `SomeMod::::build_public()`. + // Other methods should not suggested because they are private or are not a builder + let _bar = Bar::new(); + //~^ ERROR no function or associated item named `new` found +} diff --git a/tests/ui/resolve/suggest-builder-fn.stderr b/tests/ui/resolve/suggest-builder-fn.stderr new file mode 100644 index 000000000000..9c5eed35ccff --- /dev/null +++ b/tests/ui/resolve/suggest-builder-fn.stderr @@ -0,0 +1,51 @@ +error[E0599]: no function or associated item named `new` found for struct `TcpStream` in the current scope + --> $DIR/suggest-builder-fn.rs:52:29 + | +LL | let _stream = TcpStream::new(); + | ^^^ function or associated item not found in `TcpStream` + | +note: if you're trying to build a new `TcpStream` consider using one of the following associated functions: + TcpStream::connect + TcpStream::connect_timeout + --> $SRC_DIR/std/src/net/tcp.rs:LL:COL + +error[E0599]: the function or associated item `new` exists for struct `Foo`, but its trait bounds were not satisfied + --> $DIR/suggest-builder-fn.rs:57:27 + | +LL | struct Foo { + | ------------- function or associated item `new` not found for this struct +... +LL | let _foo = Foo::::new(); + | ^^^ function or associated item cannot be called on `Foo` due to unsatisfied trait bounds + | +note: trait bound `u8: SomeTrait` was not satisfied + --> $DIR/suggest-builder-fn.rs:12:9 + | +LL | impl Foo { + | ^^^^^^^^^ ------ + | | + | unsatisfied trait bound introduced here + +error[E0599]: no function or associated item named `new` found for struct `Bar` in the current scope + --> $DIR/suggest-builder-fn.rs:62:21 + | +LL | struct Bar; + | ---------- function or associated item `new` not found for this struct +... +LL | let _bar = Bar::new(); + | ^^^ function or associated item not found in `Bar` + | +note: if you're trying to build a new `Bar` consider using one of the following associated functions: + Bar::build + SomeMod::::build_public + --> $DIR/suggest-builder-fn.rs:23:5 + | +LL | fn build() -> Self { + | ^^^^^^^^^^^^^^^^^^ +... +LL | pub fn build_public() -> Self { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr index 67bfaa4c98c7..4c07f4d6b990 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr @@ -6,7 +6,7 @@ LL | call(foo); | | | required by a bound introduced by this call | - = help: the trait `Fn<()>` is not implemented for fn item `fn() {foo}` + = help: the trait `Fn()` is not implemented for fn item `fn() {foo}` = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits note: required by a bound in `call` @@ -23,7 +23,7 @@ LL | call_mut(foo); | | | required by a bound introduced by this call | - = help: the trait `FnMut<()>` is not implemented for fn item `fn() {foo}` + = help: the trait `FnMut()` is not implemented for fn item `fn() {foo}` = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits note: required by a bound in `call_mut` @@ -40,7 +40,7 @@ LL | call_once(foo); | | | required by a bound introduced by this call | - = help: the trait `FnOnce<()>` is not implemented for fn item `fn() {foo}` + = help: the trait `FnOnce()` is not implemented for fn item `fn() {foo}` = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits note: required by a bound in `call_once` @@ -57,7 +57,7 @@ LL | call(foo_unsafe); | | | required by a bound introduced by this call | - = help: the trait `Fn<()>` is not implemented for fn item `unsafe fn() {foo_unsafe}` + = help: the trait `Fn()` is not implemented for fn item `unsafe fn() {foo_unsafe}` = note: unsafe function cannot be called generically without an unsafe block = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits @@ -75,7 +75,7 @@ LL | call_mut(foo_unsafe); | | | required by a bound introduced by this call | - = help: the trait `FnMut<()>` is not implemented for fn item `unsafe fn() {foo_unsafe}` + = help: the trait `FnMut()` is not implemented for fn item `unsafe fn() {foo_unsafe}` = note: unsafe function cannot be called generically without an unsafe block = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits @@ -93,7 +93,7 @@ LL | call_once(foo_unsafe); | | | required by a bound introduced by this call | - = help: the trait `FnOnce<()>` is not implemented for fn item `unsafe fn() {foo_unsafe}` + = help: the trait `FnOnce()` is not implemented for fn item `unsafe fn() {foo_unsafe}` = note: unsafe function cannot be called generically without an unsafe block = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr index 151bd6facf72..fb2e66db1d48 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr @@ -13,8 +13,8 @@ LL | x(()) = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | const fn need_const_closure i32 + ~const std::ops::FnOnce<((),)>>(x: T) -> i32 { - | ++++++++++++++++++++++++++++++++ +LL | const fn need_const_closure i32 + ~const FnOnce(())>(x: T) -> i32 { + | +++++++++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr index e2b3e3527012..dede411e69c7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr @@ -13,8 +13,8 @@ LL | x(()) = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | const fn need_const_closure i32 + ~const std::ops::FnOnce<((),)>>(x: T) -> i32 { - | ++++++++++++++++++++++++++++++++ +LL | const fn need_const_closure i32 + ~const FnOnce(())>(x: T) -> i32 { + | +++++++++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr index e5a773123e90..a0f053253892 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr @@ -31,8 +31,8 @@ LL | f() + f() = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | const fn answer u8 + ~const std::ops::Fn<()>>(f: &F) -> u8 { - | +++++++++++++++++++++++++ +LL | const fn answer u8 + ~const Fn()>(f: &F) -> u8 { + | +++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] @@ -47,8 +47,8 @@ LL | f() + f() = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | const fn answer u8 + ~const std::ops::Fn<()>>(f: &F) -> u8 { - | +++++++++++++++++++++++++ +LL | const fn answer u8 + ~const Fn()>(f: &F) -> u8 { + | +++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] @@ -63,8 +63,8 @@ LL | f() * 7 = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | F: ~const FnOnce() -> u8 + ~const std::ops::Fn<()>, - | +++++++++++++++++++++++++ +LL | F: ~const FnOnce() -> u8 + ~const Fn(), + | +++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs new file mode 100644 index 000000000000..9778217d462d --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs @@ -0,0 +1,24 @@ +//@ check-fail +// Fixes #119830 + +#![feature(effects)] +#![feature(min_specialization)] +#![feature(const_trait_impl)] + +trait Specialize {} + +trait Foo {} + +impl const Foo for T {} +//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` +//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207] + +impl const Foo for T where T: const Specialize {} +//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` +//~| error: `const` can only be applied to `#[const_trait]` traits +//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207] +//~| error: specialization impl does not specialize any associated items +//~| error: could not resolve generic parameters on overridden impl + +fn main() { +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr new file mode 100644 index 000000000000..d18063f8d3d8 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr @@ -0,0 +1,69 @@ +error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` + --> $DIR/spec-effectvar-ice.rs:12:15 + | +LL | trait Foo {} + | - help: mark `Foo` as const: `#[const_trait]` +LL | +LL | impl const Foo 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: const `impl` for trait `Foo` which is not marked with `#[const_trait]` + --> $DIR/spec-effectvar-ice.rs:16:15 + | +LL | trait Foo {} + | - help: mark `Foo` as const: `#[const_trait]` +... +LL | impl const Foo for T where T: const Specialize {} + | ^^^ + | + = 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: `const` can only be applied to `#[const_trait]` traits + --> $DIR/spec-effectvar-ice.rs:16:40 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^ + +error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates + --> $DIR/spec-effectvar-ice.rs:12:9 + | +LL | impl const Foo for T {} + | ^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates + --> $DIR/spec-effectvar-ice.rs:16:9 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error: specialization impl does not specialize any associated items + --> $DIR/spec-effectvar-ice.rs:16:1 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl is a specialization of this impl + --> $DIR/spec-effectvar-ice.rs:12:1 + | +LL | impl const Foo for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: could not resolve generic parameters on overridden impl + --> $DIR/spec-effectvar-ice.rs:16:1 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/rust-2024/unsafe-env-suggestion.fixed b/tests/ui/rust-2024/unsafe-env-suggestion.fixed new file mode 100644 index 000000000000..d9c738edfacb --- /dev/null +++ b/tests/ui/rust-2024/unsafe-env-suggestion.fixed @@ -0,0 +1,20 @@ +//@ run-rustfix + +#![deny(deprecated_safe)] + +use std::env; + +#[deny(unused_unsafe)] +fn main() { + unsafe { env::set_var("FOO", "BAR") }; + //~^ ERROR call to deprecated safe function + //~| WARN this is accepted in the current edition + unsafe { env::remove_var("FOO") }; + //~^ ERROR call to deprecated safe function + //~| WARN this is accepted in the current edition + + unsafe { + env::set_var("FOO", "BAR"); + env::remove_var("FOO"); + } +} diff --git a/tests/ui/rust-2024/unsafe-env-suggestion.rs b/tests/ui/rust-2024/unsafe-env-suggestion.rs new file mode 100644 index 000000000000..3bd169973e38 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-env-suggestion.rs @@ -0,0 +1,20 @@ +//@ run-rustfix + +#![deny(deprecated_safe)] + +use std::env; + +#[deny(unused_unsafe)] +fn main() { + env::set_var("FOO", "BAR"); + //~^ ERROR call to deprecated safe function + //~| WARN this is accepted in the current edition + env::remove_var("FOO"); + //~^ ERROR call to deprecated safe function + //~| WARN this is accepted in the current edition + + unsafe { + env::set_var("FOO", "BAR"); + env::remove_var("FOO"); + } +} diff --git a/tests/ui/rust-2024/unsafe-env-suggestion.stderr b/tests/ui/rust-2024/unsafe-env-suggestion.stderr new file mode 100644 index 000000000000..90c91c2a474a --- /dev/null +++ b/tests/ui/rust-2024/unsafe-env-suggestion.stderr @@ -0,0 +1,33 @@ +error: call to deprecated safe function `std::env::set_var` is unsafe and requires unsafe block + --> $DIR/unsafe-env-suggestion.rs:9:5 + | +LL | env::set_var("FOO", "BAR"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see issue #27970 +note: the lint level is defined here + --> $DIR/unsafe-env-suggestion.rs:3:9 + | +LL | #![deny(deprecated_safe)] + | ^^^^^^^^^^^^^^^ +help: you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code + | +LL | unsafe { env::set_var("FOO", "BAR") }; + | ++++++++ + + +error: call to deprecated safe function `std::env::remove_var` is unsafe and requires unsafe block + --> $DIR/unsafe-env-suggestion.rs:12:5 + | +LL | env::remove_var("FOO"); + | ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see issue #27970 +help: you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code + | +LL | unsafe { env::remove_var("FOO") }; + | ++++++++ + + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rust-2024/unsafe-env.e2021.stderr b/tests/ui/rust-2024/unsafe-env.e2021.stderr new file mode 100644 index 000000000000..cc40ec2e466b --- /dev/null +++ b/tests/ui/rust-2024/unsafe-env.e2021.stderr @@ -0,0 +1,23 @@ +error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe function or block + --> $DIR/unsafe-env.rs:23:5 + | +LL | unsafe_fn(); + | ^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: unnecessary `unsafe` block + --> $DIR/unsafe-env.rs:26:5 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/unsafe-env.rs:11:8 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/rust-2024/unsafe-env.e2024.stderr b/tests/ui/rust-2024/unsafe-env.e2024.stderr new file mode 100644 index 000000000000..b43f817cf72a --- /dev/null +++ b/tests/ui/rust-2024/unsafe-env.e2024.stderr @@ -0,0 +1,39 @@ +error[E0133]: call to unsafe function `set_var` is unsafe and requires unsafe block + --> $DIR/unsafe-env.rs:13:5 + | +LL | env::set_var("FOO", "BAR"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function `remove_var` is unsafe and requires unsafe block + --> $DIR/unsafe-env.rs:15:5 + | +LL | env::remove_var("FOO"); + | ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block + --> $DIR/unsafe-env.rs:23:5 + | +LL | unsafe_fn(); + | ^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: unnecessary `unsafe` block + --> $DIR/unsafe-env.rs:26:5 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/unsafe-env.rs:11:8 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/rust-2024/unsafe-env.rs b/tests/ui/rust-2024/unsafe-env.rs new file mode 100644 index 000000000000..a882f077b9bb --- /dev/null +++ b/tests/ui/rust-2024/unsafe-env.rs @@ -0,0 +1,30 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options + +use std::env; + +unsafe fn unsafe_fn() {} +fn safe_fn() {} + +#[deny(unused_unsafe)] +fn main() { + env::set_var("FOO", "BAR"); + //[e2024]~^ ERROR call to unsafe function `set_var` is unsafe + env::remove_var("FOO"); + //[e2024]~^ ERROR call to unsafe function `remove_var` is unsafe + + unsafe { + env::set_var("FOO", "BAR"); + env::remove_var("FOO"); + } + + unsafe_fn(); + //~^ ERROR call to unsafe function `unsafe_fn` is unsafe + + unsafe { + //~^ ERROR unnecessary `unsafe` block + safe_fn(); + } +} diff --git a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr index bd0519f66c0d..6fff086a89c2 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr @@ -9,7 +9,7 @@ LL | fn get>(self: R) -> u32 { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin