From 829338a64016cd50fc766649d53cf5ea0b27284f Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 1 Apr 2024 23:38:18 +0200 Subject: [PATCH 01/15] add enum variant field names to make the code clearer --- compiler/rustc_resolve/src/check_unused.rs | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index f6004fed8284e..fdec48fe26a63 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -268,9 +268,9 @@ impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { enum UnusedSpanResult { Used, - FlatUnused(Span, Span), - NestedFullUnused(Vec, Span), - NestedPartialUnused(Vec, Vec), + FlatUnused { span: Span, remove: Span }, + NestedFullUnused { spans: Vec, remove: Span }, + NestedPartialUnused { spans: Vec, remove: Vec }, } fn calc_unused_spans( @@ -288,14 +288,14 @@ fn calc_unused_spans( match use_tree.kind { ast::UseTreeKind::Simple(..) | ast::UseTreeKind::Glob => { if unused_import.unused.contains(&use_tree_id) { - UnusedSpanResult::FlatUnused(use_tree.span, full_span) + UnusedSpanResult::FlatUnused { span: use_tree.span, remove: full_span } } else { UnusedSpanResult::Used } } ast::UseTreeKind::Nested(ref nested) => { if nested.is_empty() { - return UnusedSpanResult::FlatUnused(use_tree.span, full_span); + return UnusedSpanResult::FlatUnused { span: use_tree.span, remove: full_span }; } let mut unused_spans = Vec::new(); @@ -308,15 +308,15 @@ fn calc_unused_spans( all_nested_unused = false; None } - UnusedSpanResult::FlatUnused(span, remove) => { + UnusedSpanResult::FlatUnused { span, remove } => { unused_spans.push(span); Some(remove) } - UnusedSpanResult::NestedFullUnused(mut spans, remove) => { + UnusedSpanResult::NestedFullUnused { mut spans, remove } => { unused_spans.append(&mut spans); Some(remove) } - UnusedSpanResult::NestedPartialUnused(mut spans, mut to_remove_extra) => { + UnusedSpanResult::NestedPartialUnused { mut spans, remove: mut to_remove_extra } => { all_nested_unused = false; unused_spans.append(&mut spans); to_remove.append(&mut to_remove_extra); @@ -349,9 +349,9 @@ fn calc_unused_spans( if unused_spans.is_empty() { UnusedSpanResult::Used } else if all_nested_unused { - UnusedSpanResult::NestedFullUnused(unused_spans, full_span) + UnusedSpanResult::NestedFullUnused { spans: unused_spans, remove: full_span } } else { - UnusedSpanResult::NestedPartialUnused(unused_spans, to_remove) + UnusedSpanResult::NestedPartialUnused { spans: unused_spans, remove: to_remove } } } } @@ -417,15 +417,15 @@ impl Resolver<'_, '_> { let mut fixes = Vec::new(); let spans = match calc_unused_spans(unused, &unused.use_tree, unused.use_tree_id) { UnusedSpanResult::Used => continue, - UnusedSpanResult::FlatUnused(span, remove) => { + UnusedSpanResult::FlatUnused { span, remove } => { fixes.push((remove, String::new())); vec![span] } - UnusedSpanResult::NestedFullUnused(spans, remove) => { + UnusedSpanResult::NestedFullUnused { spans, remove } => { fixes.push((remove, String::new())); spans } - UnusedSpanResult::NestedPartialUnused(spans, remove) => { + UnusedSpanResult::NestedPartialUnused { spans, remove } => { for fix in &remove { fixes.push((*fix, String::new())); } From 2c26072d8cdca85e813b423f65632911f4781ff5 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 1 Apr 2024 23:42:33 +0200 Subject: [PATCH 02/15] remove redundant flat vs nested distinction to simplify enum --- compiler/rustc_resolve/src/check_unused.rs | 29 ++++++++-------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index fdec48fe26a63..613709b0cb687 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -268,9 +268,8 @@ impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { enum UnusedSpanResult { Used, - FlatUnused { span: Span, remove: Span }, - NestedFullUnused { spans: Vec, remove: Span }, - NestedPartialUnused { spans: Vec, remove: Vec }, + Unused { spans: Vec, remove: Span }, + PartialUnused { spans: Vec, remove: Vec }, } fn calc_unused_spans( @@ -288,14 +287,14 @@ fn calc_unused_spans( match use_tree.kind { ast::UseTreeKind::Simple(..) | ast::UseTreeKind::Glob => { if unused_import.unused.contains(&use_tree_id) { - UnusedSpanResult::FlatUnused { span: use_tree.span, remove: full_span } + UnusedSpanResult::Unused { spans: vec![use_tree.span], remove: full_span } } else { UnusedSpanResult::Used } } ast::UseTreeKind::Nested(ref nested) => { if nested.is_empty() { - return UnusedSpanResult::FlatUnused { span: use_tree.span, remove: full_span }; + return UnusedSpanResult::Unused { spans: vec![use_tree.span], remove: full_span }; } let mut unused_spans = Vec::new(); @@ -308,15 +307,11 @@ fn calc_unused_spans( all_nested_unused = false; None } - UnusedSpanResult::FlatUnused { span, remove } => { - unused_spans.push(span); - Some(remove) - } - UnusedSpanResult::NestedFullUnused { mut spans, remove } => { + UnusedSpanResult::Unused { mut spans, remove } => { unused_spans.append(&mut spans); Some(remove) } - UnusedSpanResult::NestedPartialUnused { mut spans, remove: mut to_remove_extra } => { + UnusedSpanResult::PartialUnused { mut spans, remove: mut to_remove_extra } => { all_nested_unused = false; unused_spans.append(&mut spans); to_remove.append(&mut to_remove_extra); @@ -349,9 +344,9 @@ fn calc_unused_spans( if unused_spans.is_empty() { UnusedSpanResult::Used } else if all_nested_unused { - UnusedSpanResult::NestedFullUnused { spans: unused_spans, remove: full_span } + UnusedSpanResult::Unused { spans: unused_spans, remove: full_span } } else { - UnusedSpanResult::NestedPartialUnused { spans: unused_spans, remove: to_remove } + UnusedSpanResult::PartialUnused { spans: unused_spans, remove: to_remove } } } } @@ -417,15 +412,11 @@ impl Resolver<'_, '_> { let mut fixes = Vec::new(); let spans = match calc_unused_spans(unused, &unused.use_tree, unused.use_tree_id) { UnusedSpanResult::Used => continue, - UnusedSpanResult::FlatUnused { span, remove } => { - fixes.push((remove, String::new())); - vec![span] - } - UnusedSpanResult::NestedFullUnused { spans, remove } => { + UnusedSpanResult::Unused { spans, remove } => { fixes.push((remove, String::new())); spans } - UnusedSpanResult::NestedPartialUnused { spans, remove } => { + UnusedSpanResult::PartialUnused { spans, remove } => { for fix in &remove { fixes.push((*fix, String::new())); } From 2ec337c19336845b371dcd6bc1369e6b34124afd Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 1 Apr 2024 23:53:17 +0200 Subject: [PATCH 03/15] turn all_nested_unused into used_childs --- compiler/rustc_resolve/src/check_unused.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 613709b0cb687..e054847fe5e77 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -299,12 +299,12 @@ fn calc_unused_spans( let mut unused_spans = Vec::new(); let mut to_remove = Vec::new(); - let mut all_nested_unused = true; + let mut used_childs = 0; let mut previous_unused = false; for (pos, (use_tree, use_tree_id)) in nested.iter().enumerate() { let remove = match calc_unused_spans(unused_import, use_tree, *use_tree_id) { UnusedSpanResult::Used => { - all_nested_unused = false; + used_childs += 1; None } UnusedSpanResult::Unused { mut spans, remove } => { @@ -312,7 +312,7 @@ fn calc_unused_spans( Some(remove) } UnusedSpanResult::PartialUnused { mut spans, remove: mut to_remove_extra } => { - all_nested_unused = false; + used_childs += 1; unused_spans.append(&mut spans); to_remove.append(&mut to_remove_extra); None @@ -321,7 +321,7 @@ fn calc_unused_spans( if let Some(remove) = remove { let remove_span = if nested.len() == 1 { remove - } else if pos == nested.len() - 1 || !all_nested_unused { + } else if pos == nested.len() - 1 || used_childs > 0 { // Delete everything from the end of the last import, to delete the // previous comma nested[pos - 1].0.span.shrink_to_hi().to(use_tree.span) @@ -343,7 +343,7 @@ fn calc_unused_spans( } if unused_spans.is_empty() { UnusedSpanResult::Used - } else if all_nested_unused { + } else if used_childs == 0 { UnusedSpanResult::Unused { spans: unused_spans, remove: full_span } } else { UnusedSpanResult::PartialUnused { spans: unused_spans, remove: to_remove } From 13f76235b333f4b9c750be45839b488d7f5c8203 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 2 Apr 2024 00:26:10 +0200 Subject: [PATCH 04/15] store the span of the nested part of the use tree in the ast --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_ast/src/visit.rs | 4 ++-- compiler/rustc_ast_lowering/src/item.rs | 6 +++--- compiler/rustc_ast_pretty/src/pprust/state/item.rs | 4 ++-- compiler/rustc_builtin_macros/src/assert/context.rs | 11 +++++++---- compiler/rustc_expand/src/expand.rs | 4 ++-- compiler/rustc_lint/src/unused.rs | 4 ++-- compiler/rustc_parse/src/parser/item.rs | 8 ++++++-- compiler/rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/check_unused.rs | 6 +++--- compiler/rustc_resolve/src/late.rs | 6 +++--- .../clippy_lints/src/single_component_path_imports.rs | 8 ++++---- .../clippy_lints/src/unnecessary_self_imports.rs | 4 ++-- .../clippy_lints/src/unsafe_removed_from_name.rs | 4 ++-- src/tools/clippy/clippy_utils/src/ast_utils.rs | 2 +- src/tools/rustfmt/src/imports.rs | 4 +++- 17 files changed, 45 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5b708cf4e1a55..37a13aed24d65 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2703,7 +2703,7 @@ pub enum UseTreeKind { /// `use prefix` or `use prefix as rename` Simple(Option), /// `use prefix::{...}` - Nested(ThinVec<(UseTree, NodeId)>), + Nested { items: ThinVec<(UseTree, NodeId)>, span: Span }, /// `use prefix::*` Glob, } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index da57def263df5..e633c0743a701 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -436,7 +436,7 @@ pub fn noop_visit_use_tree(use_tree: &mut UseTree, vis: &mut T) { vis.visit_path(prefix); match kind { UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)), - UseTreeKind::Nested(items) => { + UseTreeKind::Nested { items, .. } => { for (tree, id) in items { vis.visit_use_tree(tree); vis.visit_id(id); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 9e9ae52962d87..30a09d4163c94 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -488,8 +488,8 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>( visit_opt!(visitor, visit_ident, rename); } UseTreeKind::Glob => {} - UseTreeKind::Nested(ref use_trees) => { - for &(ref nested_tree, nested_id) in use_trees { + UseTreeKind::Nested { ref items, .. } => { + for &(ref nested_tree, nested_id) in items { try_visit!(visitor.visit_use_tree(nested_tree, nested_id, true)); } } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index abfea6078f21c..21a1671e39809 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -134,8 +134,8 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) { match &tree.kind { - UseTreeKind::Nested(nested_vec) => { - for &(ref nested, id) in nested_vec { + UseTreeKind::Nested { items, .. } => { + for &(ref nested, id) in items { vec.push(hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(id) }, }); @@ -517,7 +517,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let path = self.lower_use_path(res, &path, ParamMode::Explicit); hir::ItemKind::Use(path, hir::UseKind::Glob) } - UseTreeKind::Nested(ref trees) => { + UseTreeKind::Nested { items: ref trees, .. } => { // Nested imports are desugared into simple imports. // So, if we start with // diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 13f27c1c95c2e..ff24874bbcf21 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -712,7 +712,7 @@ impl<'a> State<'a> { } self.word("*"); } - ast::UseTreeKind::Nested(items) => { + ast::UseTreeKind::Nested { items, .. } => { if !tree.prefix.segments.is_empty() { self.print_path(&tree.prefix, false, 0); self.word("::"); @@ -731,7 +731,7 @@ impl<'a> State<'a> { self.print_use_tree(&use_tree.0); if !is_last { self.word(","); - if let ast::UseTreeKind::Nested(_) = use_tree.0.kind { + if let ast::UseTreeKind::Nested { .. } = use_tree.0.kind { self.hardbreak(); } else { self.space(); diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 92efeab08ebea..085ea3458bbfa 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -120,10 +120,13 @@ impl<'cx, 'a> Context<'cx, 'a> { thin_vec![self.cx.attr_nested_word(sym::allow, sym::unused_imports, self.span)], ItemKind::Use(UseTree { prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])), - kind: UseTreeKind::Nested(thin_vec![ - nested_tree(self, sym::TryCaptureGeneric), - nested_tree(self, sym::TryCapturePrintable), - ]), + kind: UseTreeKind::Nested { + items: thin_vec![ + nested_tree(self, sym::TryCaptureGeneric), + nested_tree(self, sym::TryCapturePrintable), + ], + span: self.span, + }, span: self.span, }), ), diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 6029caa965c0b..6de3a392e7857 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1190,8 +1190,8 @@ impl InvocationCollectorNode for P { match &ut.kind { ast::UseTreeKind::Glob => {} ast::UseTreeKind::Simple(_) => idents.push(ut.ident()), - ast::UseTreeKind::Nested(nested) => { - for (ut, _) in nested { + ast::UseTreeKind::Nested { items, .. } => { + for (ut, _) in items { collect_use_tree_leaves(ut, idents); } } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 503caa35358ab..e8f9d373289ce 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1499,7 +1499,7 @@ declare_lint_pass!(UnusedImportBraces => [UNUSED_IMPORT_BRACES]); impl UnusedImportBraces { fn check_use_tree(&self, cx: &EarlyContext<'_>, use_tree: &ast::UseTree, item: &ast::Item) { - if let ast::UseTreeKind::Nested(ref items) = use_tree.kind { + if let ast::UseTreeKind::Nested { ref items, .. } = use_tree.kind { // Recursively check nested UseTrees for (tree, _) in items { self.check_use_tree(cx, tree, item); @@ -1520,7 +1520,7 @@ impl UnusedImportBraces { rename.unwrap_or(orig_ident).name } ast::UseTreeKind::Glob => Symbol::intern("*"), - ast::UseTreeKind::Nested(_) => return, + ast::UseTreeKind::Nested { .. } => return, }; cx.emit_span_lint( diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index d54eb8dc4c9eb..7332cc8622063 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -336,7 +336,7 @@ impl<'a> Parser<'a> { UseTreeKind::Glob => { e.note("the wildcard token must be last on the path"); } - UseTreeKind::Nested(..) => { + UseTreeKind::Nested { .. } => { e.note("glob-like brace syntax must be last on the path"); } _ => (), @@ -1056,7 +1056,11 @@ impl<'a> Parser<'a> { Ok(if self.eat(&token::BinOp(token::Star)) { UseTreeKind::Glob } else { - UseTreeKind::Nested(self.parse_use_tree_list()?) + let lo = self.token.span; + UseTreeKind::Nested { + items: self.parse_use_tree_list()?, + span: lo.to(self.prev_token.span), + } }) } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 375f20dd809f2..e484fdd45177c 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -565,7 +565,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { self.add_import(prefix, kind, use_tree.span, item, root_span, item.id, vis); } - ast::UseTreeKind::Nested(ref items) => { + ast::UseTreeKind::Nested { ref items, .. } => { // Ensure there is at most one `self` in the list let self_spans = items .iter() diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index e054847fe5e77..950a0f9ff652d 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -128,7 +128,7 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { self.unused_import(self.base_id).add(id); } } - ast::UseTreeKind::Nested(ref items) => self.check_imports_as_underscore(items), + ast::UseTreeKind::Nested { ref items, .. } => self.check_imports_as_underscore(items), _ => {} } } @@ -254,7 +254,7 @@ impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { return; } - if let ast::UseTreeKind::Nested(ref items) = use_tree.kind { + if let ast::UseTreeKind::Nested { ref items, .. } = use_tree.kind { if items.is_empty() { self.unused_import(self.base_id).add(id); } @@ -292,7 +292,7 @@ fn calc_unused_spans( UnusedSpanResult::Used } } - ast::UseTreeKind::Nested(ref nested) => { + ast::UseTreeKind::Nested { items: ref nested, .. } => { if nested.is_empty() { return UnusedSpanResult::Unused { spans: vec![use_tree.span], remove: full_span }; } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 49b4a6efd3c3e..37b259dc5393b 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2332,8 +2332,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { None => {} } } - } else if let UseTreeKind::Nested(use_trees) = &use_tree.kind { - for (use_tree, _) in use_trees { + } else if let UseTreeKind::Nested { items, .. } = &use_tree.kind { + for (use_tree, _) in items { self.future_proof_import(use_tree); } } @@ -2510,7 +2510,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ItemKind::Use(ref use_tree) => { let maybe_exported = match use_tree.kind { UseTreeKind::Simple(_) | UseTreeKind::Glob => MaybeExported::Ok(item.id), - UseTreeKind::Nested(_) => MaybeExported::NestedUse(&item.vis), + UseTreeKind::Nested { .. } => MaybeExported::NestedUse(&item.vis), }; self.resolve_doc_links(&item.attrs, maybe_exported); diff --git a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs index 18fbbdb407911..acf44a9bb5ab4 100644 --- a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs +++ b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs @@ -201,8 +201,8 @@ impl SingleComponentPathImports { if segments.is_empty() { // keep track of `use {some_module, some_other_module};` usages - if let UseTreeKind::Nested(trees) = &use_tree.kind { - for tree in trees { + if let UseTreeKind::Nested { items, .. } = &use_tree.kind { + for tree in items { let segments = &tree.0.prefix.segments; if segments.len() == 1 { if let UseTreeKind::Simple(None) = tree.0.kind { @@ -229,8 +229,8 @@ impl SingleComponentPathImports { } // nested case such as `use self::{module1::Struct1, module2::Struct2}` - if let UseTreeKind::Nested(trees) = &use_tree.kind { - for tree in trees { + if let UseTreeKind::Nested { items, .. } = &use_tree.kind { + for tree in items { let segments = &tree.0.prefix.segments; if !segments.is_empty() { imports_reused_with_self.push(segments[0].ident.name); 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 ddee06b59cae1..528a1dfcfc10f 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs @@ -36,8 +36,8 @@ declare_lint_pass!(UnnecessarySelfImports => [UNNECESSARY_SELF_IMPORTS]); impl EarlyLintPass for UnnecessarySelfImports { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { if let ItemKind::Use(use_tree) = &item.kind - && let UseTreeKind::Nested(nodes) = &use_tree.kind - && let [(self_tree, _)] = &**nodes + && let UseTreeKind::Nested { items, .. } = &use_tree.kind + && let [(self_tree, _)] = &**items && let [self_seg] = &*self_tree.prefix.segments && self_seg.ident.name == kw::SelfLower && let Some(last_segment) = use_tree.prefix.segments.last() diff --git a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs index 51b3ea93b6dc9..309eaedac8d29 100644 --- a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs +++ b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs @@ -49,8 +49,8 @@ fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) { unsafe_to_safe_check(old_name, new_name, cx, span); }, UseTreeKind::Simple(None) | UseTreeKind::Glob => {}, - UseTreeKind::Nested(ref nested_use_tree) => { - for (use_tree, _) in nested_use_tree { + UseTreeKind::Nested { ref items, .. } => { + for (use_tree, _) in items { check_use_tree(use_tree, cx, span); } }, diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index f594a40ff59ad..36d54bb41fa4d 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -637,7 +637,7 @@ pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool { match (l, r) { (Glob, Glob) => true, (Simple(l), Simple(r)) => both(l, r, |l, r| eq_id(*l, *r)), - (Nested(l), Nested(r)) => over(l, r, |(l, _), (r, _)| eq_use_tree(l, r)), + (Nested { items: l, .. }, Nested { items: r, .. }) => over(l, r, |(l, _), (r, _)| eq_use_tree(l, r)), _ => false, } } diff --git a/src/tools/rustfmt/src/imports.rs b/src/tools/rustfmt/src/imports.rs index 09f6e75233880..2da746295fc96 100644 --- a/src/tools/rustfmt/src/imports.rs +++ b/src/tools/rustfmt/src/imports.rs @@ -458,7 +458,9 @@ impl UseTree { version, }); } - UseTreeKind::Nested(ref list) => { + UseTreeKind::Nested { + items: ref list, .. + } => { // Extract comments between nested use items. // This needs to be done before sorting use items. let items = itemize_list( From 2d3a9a5847dccb2623c956e5aa175493fa68aa2a Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Sun, 14 Apr 2024 18:40:49 +0200 Subject: [PATCH 05/15] remove braces when fixing a nested use tree into a single use --- compiler/rustc_resolve/src/check_unused.rs | 27 +++++++++++++- tests/ui/suggestions/unused-imports.fixed | 35 ++++++++++++++++++ tests/ui/suggestions/unused-imports.rs | 42 ++++++++++++++++++++++ tests/ui/suggestions/unused-imports.stderr | 32 +++++++++++++++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 tests/ui/suggestions/unused-imports.fixed create mode 100644 tests/ui/suggestions/unused-imports.rs create mode 100644 tests/ui/suggestions/unused-imports.stderr diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 950a0f9ff652d..5fe68085d6537 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -292,7 +292,7 @@ fn calc_unused_spans( UnusedSpanResult::Used } } - ast::UseTreeKind::Nested { items: ref nested, .. } => { + ast::UseTreeKind::Nested { items: ref nested, span: tree_span } => { if nested.is_empty() { return UnusedSpanResult::Unused { spans: vec![use_tree.span], remove: full_span }; } @@ -300,6 +300,7 @@ fn calc_unused_spans( let mut unused_spans = Vec::new(); let mut to_remove = Vec::new(); let mut used_childs = 0; + let mut contains_self = false; let mut previous_unused = false; for (pos, (use_tree, use_tree_id)) in nested.iter().enumerate() { let remove = match calc_unused_spans(unused_import, use_tree, *use_tree_id) { @@ -339,6 +340,8 @@ fn calc_unused_spans( to_remove.push(remove_span); } } + contains_self |= use_tree.prefix == kw::SelfLower + && matches!(use_tree.kind, ast::UseTreeKind::Simple(None)); previous_unused = remove.is_some(); } if unused_spans.is_empty() { @@ -346,6 +349,28 @@ fn calc_unused_spans( } else if used_childs == 0 { UnusedSpanResult::Unused { spans: unused_spans, remove: full_span } } else { + // If there is only one remaining child that is used, the braces around the use + // tree are not needed anymore. In that case, we determine the span of the left + // brace and the right brace, and tell rustfix to remove them as well. + // + // This means that `use a::{B, C};` will be turned into `use a::B;` rather than + // `use a::{B};`, removing a rustfmt roundtrip. + // + // Note that we cannot remove the braces if the only item inside the use tree is + // `self`: `use foo::{self};` is valid Rust syntax, while `use foo::self;` errors + // out. We also cannot turn `use foo::{self}` into `use foo`, as the former doesn't + // import types with the same name as the module. + if used_childs == 1 && !contains_self { + // Left brace, from the start of the nested group to the first item. + to_remove.push( + tree_span.shrink_to_lo().to(nested.first().unwrap().0.span.shrink_to_lo()), + ); + // Right brace, from the end of the last item to the end of the nested group. + to_remove.push( + nested.last().unwrap().0.span.shrink_to_hi().to(tree_span.shrink_to_hi()), + ); + } + UnusedSpanResult::PartialUnused { spans: unused_spans, remove: to_remove } } } diff --git a/tests/ui/suggestions/unused-imports.fixed b/tests/ui/suggestions/unused-imports.fixed new file mode 100644 index 0000000000000..57dd091c0436d --- /dev/null +++ b/tests/ui/suggestions/unused-imports.fixed @@ -0,0 +1,35 @@ +//@ run-rustfix +//@ check-pass + +#![warn(unused_imports)] + +pub mod nested { + pub struct A; + pub struct B; + pub struct C; + pub struct D; + pub mod even_more { + pub struct E; + pub struct F; + pub struct G; + } + pub mod another { + pub struct H; + pub struct I; + } +} + +use nested::B; +//~^ WARN unused import + +use nested::even_more::F; +//~^^^^^^^ WARN unused import + +// Note that the following fix should result in `::{self}`, not `::self`. The latter is invalid +// Rust syntax, so the braces should not be removed. +use nested::another::{self}; +//~^ WARN unused import + +fn main() { + let _ = (B, F, another::I); +} diff --git a/tests/ui/suggestions/unused-imports.rs b/tests/ui/suggestions/unused-imports.rs new file mode 100644 index 0000000000000..5f9dd243bdd2a --- /dev/null +++ b/tests/ui/suggestions/unused-imports.rs @@ -0,0 +1,42 @@ +//@ run-rustfix +//@ check-pass + +#![warn(unused_imports)] + +pub mod nested { + pub struct A; + pub struct B; + pub struct C; + pub struct D; + pub mod even_more { + pub struct E; + pub struct F; + pub struct G; + } + pub mod another { + pub struct H; + pub struct I; + } +} + +use nested::{A, B, C}; +//~^ WARN unused import + +use nested::{ + D, + even_more::{ + E, + F, + G, + }, + }; +//~^^^^^^^ WARN unused import + +// Note that the following fix should result in `::{self}`, not `::self`. The latter is invalid +// Rust syntax, so the braces should not be removed. +use nested::another::{self, I}; +//~^ WARN unused import + +fn main() { + let _ = (B, F, another::I); +} diff --git a/tests/ui/suggestions/unused-imports.stderr b/tests/ui/suggestions/unused-imports.stderr new file mode 100644 index 0000000000000..bf112608da7ed --- /dev/null +++ b/tests/ui/suggestions/unused-imports.stderr @@ -0,0 +1,32 @@ +warning: unused imports: `A`, `C` + --> $DIR/unused-imports.rs:22:14 + | +LL | use nested::{A, B, C}; + | ^ ^ + | +note: the lint level is defined here + --> $DIR/unused-imports.rs:4:9 + | +LL | #![warn(unused_imports)] + | ^^^^^^^^^^^^^^ + +warning: unused imports: `D`, `E`, `G` + --> $DIR/unused-imports.rs:26:5 + | +LL | D, + | ^ +LL | even_more::{ +LL | E, + | ^ +LL | F, +LL | G, + | ^ + +warning: unused import: `I` + --> $DIR/unused-imports.rs:37:29 + | +LL | use nested::another::{self, I}; + | ^ + +warning: 3 warnings emitted + From 397a35d08193178958df4fbb9b912616ac7c4bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 5 May 2024 23:41:08 +0200 Subject: [PATCH 06/15] crashes: add lastest batch of crash tests --- tests/crashes/124436.rs | 7 +++++++ tests/crashes/124440.rs | 23 +++++++++++++++++++++ tests/crashes/124464.rs | 17 +++++++++++++++ tests/crashes/124490.rs | 16 ++++++++++++++ tests/crashes/124552.rs | 12 +++++++++++ tests/crashes/124563.rs | 46 +++++++++++++++++++++++++++++++++++++++++ tests/crashes/124583.rs | 5 +++++ tests/crashes/124702.rs | 14 +++++++++++++ tests/crashes/124751.rs | 8 +++++++ 9 files changed, 148 insertions(+) create mode 100644 tests/crashes/124436.rs create mode 100644 tests/crashes/124440.rs create mode 100644 tests/crashes/124464.rs create mode 100644 tests/crashes/124490.rs create mode 100644 tests/crashes/124552.rs create mode 100644 tests/crashes/124563.rs create mode 100644 tests/crashes/124583.rs create mode 100644 tests/crashes/124702.rs create mode 100644 tests/crashes/124751.rs diff --git a/tests/crashes/124436.rs b/tests/crashes/124436.rs new file mode 100644 index 0000000000000..aed830e8f0e4b --- /dev/null +++ b/tests/crashes/124436.rs @@ -0,0 +1,7 @@ +//@ known-bug: rust-lang/rust#124436 +//@ compile-flags: -Zdump-mir=all -Zpolymorphize=on + +pub trait TraitCat {} +pub trait TraitDog {} + +pub fn gamma(t: [TraitDog; 32]) {} diff --git a/tests/crashes/124440.rs b/tests/crashes/124440.rs new file mode 100644 index 0000000000000..431c4e444f10a --- /dev/null +++ b/tests/crashes/124440.rs @@ -0,0 +1,23 @@ +//@ known-bug: rust-lang/rust#124440 + +#![allow(warnings)] + +trait Foo {} + +impl Foo for F where F: FnMut(&()) {} + +struct Bar { + f: F, +} + +impl Foo for Bar where F: Foo {} + +fn assert_foo(_: F) +where + Bar: Foo, +{ +} + +fn main() { + assert_foo(|_| ()); +} diff --git a/tests/crashes/124464.rs b/tests/crashes/124464.rs new file mode 100644 index 0000000000000..471479f5cf1b6 --- /dev/null +++ b/tests/crashes/124464.rs @@ -0,0 +1,17 @@ +//@ known-bug: rust-lang/rust #124464 +enum TestOption { + TestSome(T), + TestSome(T), +} + +pub struct Request { + bar: TestOption, + bar: u8, +} + +fn default_instance() -> &'static Request { + static instance: Request = Request { bar: 17 }; + &instance +} + +pub fn main() {} diff --git a/tests/crashes/124490.rs b/tests/crashes/124490.rs new file mode 100644 index 0000000000000..9f605c32cf261 --- /dev/null +++ b/tests/crashes/124490.rs @@ -0,0 +1,16 @@ +//@ known-bug: rust-lang/rust#124490 +use io::{self as std}; +use std::collections::{self as io}; + +mod a { + pub mod b { + pub mod c {} + } +} + +use a::*; + +use b::c; +use c as b; + +fn main() {} diff --git a/tests/crashes/124552.rs b/tests/crashes/124552.rs new file mode 100644 index 0000000000000..5320ce2784305 --- /dev/null +++ b/tests/crashes/124552.rs @@ -0,0 +1,12 @@ +//@ known-bug: rust-lang/rust#124552 + +struct B; + +struct Foo { + b: u32, + b: B, +} + +static BAR: Foo = Foo { b: B }; + +fn main() {} diff --git a/tests/crashes/124563.rs b/tests/crashes/124563.rs new file mode 100644 index 0000000000000..b082739af53d9 --- /dev/null +++ b/tests/crashes/124563.rs @@ -0,0 +1,46 @@ +//@ known-bug: rust-lang/rust#124563 + +use std::marker::PhantomData; + +pub trait Trait {} + +pub trait Foo { + type Trait: Trait; + type Bar: Bar; + fn foo(&mut self); +} + +pub struct FooImpl<'a, 'b, A: Trait>(PhantomData<&'a &'b A>); + +impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T> +where + T: Trait, +{ + type Trait = T; + type Bar = BarImpl<'a, 'b, T>; + + fn foo(&mut self) { + self.enter_scope(|ctx| { + BarImpl(ctx); + }); + } +} + +impl<'a, 'b, T> FooImpl<'a, 'b, T> +where + T: Trait, +{ + fn enter_scope(&mut self, _scope: impl FnOnce(&mut Self)) {} +} +pub trait Bar { + type Foo: Foo; +} + +pub struct BarImpl<'a, 'b, T: Trait>(&'b mut FooImpl<'a, 'b, T>); + +impl<'a, 'b, T> Bar for BarImpl<'a, 'b, T> +where + T: Trait, +{ + type Foo = FooImpl<'a, 'b, T>; +} diff --git a/tests/crashes/124583.rs b/tests/crashes/124583.rs new file mode 100644 index 0000000000000..ffd9d7521add2 --- /dev/null +++ b/tests/crashes/124583.rs @@ -0,0 +1,5 @@ +//@ known-bug: rust-lang/rust#124583 + +fn main() { + let _ = -(-0.0f16); +} diff --git a/tests/crashes/124702.rs b/tests/crashes/124702.rs new file mode 100644 index 0000000000000..e3767dec4036c --- /dev/null +++ b/tests/crashes/124702.rs @@ -0,0 +1,14 @@ +//@ known-bug: rust-lang/rust#124702 +//@ compile-flags: -Znext-solver=coherence +trait X {} + +trait Z { + type Assoc: Y; +} +struct A(T); + +impl Z for A { + type Assoc = T; +} + +impl From<> as Z>::Assoc> for T {} diff --git a/tests/crashes/124751.rs b/tests/crashes/124751.rs new file mode 100644 index 0000000000000..f15e39965d3ed --- /dev/null +++ b/tests/crashes/124751.rs @@ -0,0 +1,8 @@ +//@ known-bug: rust-lang/rust#124751 +//@ compile-flags: -Zunstable-options --edition=2024 + +#![feature(gen_blocks)] + +fn main() { + let _ = async gen || {}; +} From 1d9d6715aeb089209938ae5c8c487c1c65c85a53 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 7 May 2024 19:13:33 -0400 Subject: [PATCH 07/15] Make sure we don't deny macro vars w keyword names --- compiler/rustc_lint/src/builtin.rs | 11 +++++++- tests/ui/rust-2018/async-ident.fixed | 8 +++--- tests/ui/rust-2018/async-ident.rs | 6 ++--- tests/ui/rust-2018/async-ident.stderr | 35 ++++++++++---------------- tests/ui/rust-2024/gen-kw-in-macro.rs | 13 ++++++++++ tests/ui/rust-2024/gen-kw.e2015.stderr | 11 +++++++- tests/ui/rust-2024/gen-kw.e2018.stderr | 11 +++++++- tests/ui/rust-2024/gen-kw.rs | 9 +++++++ 8 files changed, 70 insertions(+), 34 deletions(-) create mode 100644 tests/ui/rust-2024/gen-kw-in-macro.rs diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index ba316e5eeb041..b9be92b89afdf 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -40,6 +40,7 @@ use crate::{ }, EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext, }; +use ast::token::TokenKind; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::visit::{FnCtxt, FnKind}; use rustc_ast::{self as ast, *}; @@ -1869,16 +1870,24 @@ struct UnderMacro(bool); impl KeywordIdents { fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: &TokenStream) { + // Check if the preceding token is `$`, because we want to allow `$async`, etc. + let mut prev_dollar = false; for tt in tokens.trees() { match tt { // Only report non-raw idents. TokenTree::Token(token, _) => { if let Some((ident, token::IdentIsRaw::No)) = token.ident() { - self.check_ident_token(cx, UnderMacro(true), ident); + if !prev_dollar { + self.check_ident_token(cx, UnderMacro(true), ident); + } + } else if token.kind == TokenKind::Dollar { + prev_dollar = true; + continue; } } TokenTree::Delimited(.., tts) => self.check_tokens(cx, tts), } + prev_dollar = false; } } diff --git a/tests/ui/rust-2018/async-ident.fixed b/tests/ui/rust-2018/async-ident.fixed index 4e31f674435b8..639a8a245fb41 100644 --- a/tests/ui/rust-2018/async-ident.fixed +++ b/tests/ui/rust-2018/async-ident.fixed @@ -9,16 +9,14 @@ fn r#async() {} //~ ERROR async macro_rules! foo { ($foo:ident) => {}; - ($r#async:expr, r#async) => {}; + ($async:expr, r#async) => {}; //~^ ERROR async - //~| ERROR async - //~| WARN this is accepted in the current edition //~| WARN this is accepted in the current edition } foo!(r#async); - //~^ ERROR async - //~| WARN this is accepted in the current edition +//~^ ERROR async +//~| WARN this is accepted in the current edition mod dont_lint_raw { fn r#async() {} diff --git a/tests/ui/rust-2018/async-ident.rs b/tests/ui/rust-2018/async-ident.rs index 4c5134a292321..7921f05f48126 100644 --- a/tests/ui/rust-2018/async-ident.rs +++ b/tests/ui/rust-2018/async-ident.rs @@ -11,14 +11,12 @@ macro_rules! foo { ($foo:ident) => {}; ($async:expr, async) => {}; //~^ ERROR async - //~| ERROR async - //~| WARN this is accepted in the current edition //~| WARN this is accepted in the current edition } foo!(async); - //~^ ERROR async - //~| WARN this is accepted in the current edition +//~^ ERROR async +//~| WARN this is accepted in the current edition mod dont_lint_raw { fn r#async() {} diff --git a/tests/ui/rust-2018/async-ident.stderr b/tests/ui/rust-2018/async-ident.stderr index 5b8d8184f4f3d..4ab061dd6f599 100644 --- a/tests/ui/rust-2018/async-ident.stderr +++ b/tests/ui/rust-2018/async-ident.stderr @@ -13,15 +13,6 @@ LL | #![deny(keyword_idents)] | ^^^^^^^^^^^^^^ = note: `#[deny(keyword_idents_2018)]` implied by `#[deny(keyword_idents)]` -error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:12:7 - | -LL | ($async:expr, async) => {}; - | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 - error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:12:19 | @@ -32,7 +23,7 @@ LL | ($async:expr, async) => {}; = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:19:6 + --> $DIR/async-ident.rs:17:6 | LL | foo!(async); | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -41,7 +32,7 @@ LL | foo!(async); = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:28:11 + --> $DIR/async-ident.rs:26:11 | LL | trait async {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -50,7 +41,7 @@ LL | trait async {} = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:32:10 + --> $DIR/async-ident.rs:30:10 | LL | impl async for MyStruct {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -59,7 +50,7 @@ LL | impl async for MyStruct {} = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:38:12 + --> $DIR/async-ident.rs:36:12 | LL | static async: u32 = 0; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -68,7 +59,7 @@ LL | static async: u32 = 0; = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:44:11 + --> $DIR/async-ident.rs:42:11 | LL | const async: u32 = 0; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -77,7 +68,7 @@ LL | const async: u32 = 0; = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:50:15 + --> $DIR/async-ident.rs:48:15 | LL | impl Foo { fn async() {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -86,7 +77,7 @@ LL | impl Foo { fn async() {} } = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:55:12 + --> $DIR/async-ident.rs:53:12 | LL | struct async {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -95,7 +86,7 @@ LL | struct async {} = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:58:9 + --> $DIR/async-ident.rs:56:9 | LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -104,7 +95,7 @@ LL | let async: async = async {}; = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:58:16 + --> $DIR/async-ident.rs:56:16 | LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -113,7 +104,7 @@ LL | let async: async = async {}; = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:58:24 + --> $DIR/async-ident.rs:56:24 | LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -122,7 +113,7 @@ LL | let async: async = async {}; = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:69:19 + --> $DIR/async-ident.rs:67:19 | LL | () => (pub fn async() {}) | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -131,7 +122,7 @@ LL | () => (pub fn async() {}) = note: for more information, see issue #49716 error: `async` is a keyword in the 2018 edition - --> $DIR/async-ident.rs:76:6 + --> $DIR/async-ident.rs:74:6 | LL | (async) => (1) | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` @@ -139,5 +130,5 @@ LL | (async) => (1) = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #49716 -error: aborting due to 15 previous errors +error: aborting due to 14 previous errors diff --git a/tests/ui/rust-2024/gen-kw-in-macro.rs b/tests/ui/rust-2024/gen-kw-in-macro.rs new file mode 100644 index 0000000000000..3ccbe05b226bc --- /dev/null +++ b/tests/ui/rust-2024/gen-kw-in-macro.rs @@ -0,0 +1,13 @@ +//@ check-pass + +#![deny(keyword_idents_2024)] + +macro_rules! foo { + ($gen:expr) => { + $gen + }; +} + +fn main() { + foo!(println!("hello, world")); +} diff --git a/tests/ui/rust-2024/gen-kw.e2015.stderr b/tests/ui/rust-2024/gen-kw.e2015.stderr index b12363184b713..b1074f77e0089 100644 --- a/tests/ui/rust-2024/gen-kw.e2015.stderr +++ b/tests/ui/rust-2024/gen-kw.e2015.stderr @@ -22,5 +22,14 @@ LL | let gen = r#gen; = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! = note: for more information, see issue #49716 -error: aborting due to 2 previous errors +error: `gen` is a keyword in the 2024 edition + --> $DIR/gen-kw.rs:19:27 + | +LL | () => { mod test { fn gen() {} } } + | ^^^ help: you can use a raw identifier to stay compatible: `r#gen` + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see issue #49716 + +error: aborting due to 3 previous errors diff --git a/tests/ui/rust-2024/gen-kw.e2018.stderr b/tests/ui/rust-2024/gen-kw.e2018.stderr index e10fc4c45120c..b902cff7fdbc3 100644 --- a/tests/ui/rust-2024/gen-kw.e2018.stderr +++ b/tests/ui/rust-2024/gen-kw.e2018.stderr @@ -22,5 +22,14 @@ LL | let gen = r#gen; = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024! = note: for more information, see issue #49716 -error: aborting due to 2 previous errors +error: `gen` is a keyword in the 2024 edition + --> $DIR/gen-kw.rs:19:27 + | +LL | () => { mod test { fn gen() {} } } + | ^^^ help: you can use a raw identifier to stay compatible: `r#gen` + | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024! + = note: for more information, see issue #49716 + +error: aborting due to 3 previous errors diff --git a/tests/ui/rust-2024/gen-kw.rs b/tests/ui/rust-2024/gen-kw.rs index 3d2a3f9516558..04251cbcac47b 100644 --- a/tests/ui/rust-2024/gen-kw.rs +++ b/tests/ui/rust-2024/gen-kw.rs @@ -14,3 +14,12 @@ fn main() { //[e2015]~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! //[e2018]~| WARNING this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024! } + +macro_rules! t { + () => { mod test { fn gen() {} } } + //~^ ERROR `gen` is a keyword in the 2024 edition + //[e2015]~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + //[e2018]~| WARNING this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024! +} + +t!(); From b68b92041c382c7ba1c4c8377af54d2fb198a83a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 16:56:02 +1000 Subject: [PATCH 08/15] Simplify `use crate::rustc_foo::bar` occurrences. They can just be written as `use rustc_foo::bar`, which is far more standard. (I didn't even know that a `crate::` prefix was valid.) --- compiler/rustc_codegen_gcc/src/debuginfo.rs | 3 +-- compiler/rustc_codegen_gcc/src/type_of.rs | 4 ++-- .../rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs | 3 +-- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 3 +-- compiler/rustc_mir_transform/src/large_enums.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 6 ++---- src/librustdoc/clean/mod.rs | 4 ++-- src/librustdoc/externalfiles.rs | 2 +- src/librustdoc/html/format.rs | 4 ++-- src/tools/clippy/clippy_lints/src/manual_assert.rs | 3 +-- .../clippy_lints/src/methods/iter_overeager_cloned.rs | 2 +- src/tools/clippy/clippy_lints/src/redundant_closure_call.rs | 3 +-- .../clippy_lints/src/semicolon_if_nothing_returned.rs | 3 +-- src/tools/miri/src/shims/x86/avx2.rs | 2 +- 14 files changed, 18 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index aed15769025f1..1d0a6d9f09bb9 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -1,10 +1,9 @@ -use crate::rustc_index::Idx; use gccjit::{Location, RValue}; use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind}; use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoMethods}; use rustc_data_structures::sync::Lrc; use rustc_index::bit_set::BitSet; -use rustc_index::IndexVec; +use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::{self, Body, SourceScope}; use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty}; use rustc_session::config::DebugInfo; diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 8f9bfbbd18fb0..01056c1e42de8 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -1,7 +1,7 @@ use std::fmt::Write; -use crate::rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods}; use gccjit::{Struct, Type}; +use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -205,7 +205,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { /// of that field's type - this is useful for taking the address of /// that field and ensuring the struct has the right alignment. fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> { - use crate::rustc_middle::ty::layout::FnAbiOf; + use rustc_middle::ty::layout::FnAbiOf; // This must produce the same result for `repr(transparent)` wrappers as for the inner type! // In other words, this should generally not look at the type at all, but only at the // layout. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index c2068d9f66b8f..2ef254f644f73 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -1,9 +1,8 @@ //! A utility module to inspect currently ambiguous obligations in the current context. -use crate::rustc_middle::ty::TypeVisitableExt; use crate::FnCtxt; use rustc_infer::traits::solve::Goal; use rustc_infer::traits::{self, ObligationCause}; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_span::Span; use rustc_trait_selection::solve::inspect::ProofTreeInferCtxtExt; use rustc_trait_selection::solve::inspect::{InspectConfig, InspectGoal, ProofTreeVisitor}; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index d00fea4fae498..131a1adf7e762 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -6,7 +6,6 @@ use crate::fn_ctxt::rustc_span::BytePos; use crate::hir::is_range_literal; use crate::method::probe; use crate::method::probe::{IsSuggestion, Mode, ProbeScope}; -use crate::rustc_middle::ty::Article; use core::cmp::min; use core::iter; use hir::def_id::LocalDefId; @@ -28,7 +27,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::middle::stability::EvalResult; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, suggest_constraining_type_params, Binder, IsSuggestable, ToPredicate, Ty, + self, suggest_constraining_type_params, Article, Binder, IsSuggestable, ToPredicate, Ty, TypeVisitableExt, }; use rustc_session::errors::ExprParenthesesNeeded; diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 8be96b6ba8f28..e407929c9a7fd 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -1,7 +1,7 @@ -use crate::rustc_middle::ty::util::IntTypeExt; use rustc_data_structures::fx::FxHashMap; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::*; +use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, AdtDef, ParamEnv, Ty, TyCtxt}; use rustc_session::Session; use rustc_target::abi::{HasDataLayout, Size, TagEncoding, Variants}; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index aa9657797310c..a7696b1fbaff4 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -2,8 +2,6 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::rustc_middle::dep_graph::DepContext; -use crate::rustc_middle::ty::TyEncoder; use crate::QueryConfigRestored; use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_data_structures::sync::Lock; @@ -13,14 +11,14 @@ use rustc_errors::DiagInner; use rustc_index::Idx; use rustc_middle::dep_graph::dep_kinds; use rustc_middle::dep_graph::{ - self, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex, + self, DepContext, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex, }; use rustc_middle::query::on_disk_cache::AbsoluteBytePos; use rustc_middle::query::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex}; use rustc_middle::query::Key; use rustc_middle::ty::print::with_reduced_queries; use rustc_middle::ty::tls::{self, ImplicitCtxt}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt, TyEncoder}; use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext}; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f437c7d319d75..1f84c9ded1154 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1860,9 +1860,9 @@ fn normalize<'tcx>( return None; } - use crate::rustc_trait_selection::infer::TyCtxtInferExt; - use crate::rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_middle::traits::ObligationCause; + use rustc_trait_selection::infer::TyCtxtInferExt; + use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; // Try to normalize `::T` to a type let infcx = cx.tcx.infer_ctxt().build(); diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 57e82b877bf14..6beca8bdb3a68 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -1,5 +1,5 @@ use crate::html::markdown::{ErrorCodes, HeadingOffset, IdMap, Markdown, Playground}; -use crate::rustc_span::edition::Edition; +use rustc_span::edition::Edition; use std::fs; use std::path::Path; use std::str; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f82b89fdd5f98..241dc37ab9cd0 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -594,9 +594,9 @@ fn generate_item_def_id_path( root_path: Option<&str>, original_def_kind: DefKind, ) -> Result<(String, ItemType, Vec), HrefError> { - use crate::rustc_trait_selection::infer::TyCtxtInferExt; - use crate::rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_middle::traits::ObligationCause; + use rustc_trait_selection::infer::TyCtxtInferExt; + use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; let tcx = cx.tcx(); let crate_name = tcx.crate_name(def_id.krate); diff --git a/src/tools/clippy/clippy_lints/src/manual_assert.rs b/src/tools/clippy/clippy_lints/src/manual_assert.rs index d76b94eba23ed..83c16d4466d06 100644 --- a/src/tools/clippy/clippy_lints/src/manual_assert.rs +++ b/src/tools/clippy/clippy_lints/src/manual_assert.rs @@ -1,10 +1,9 @@ -use crate::rustc_lint::LintContext; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::{is_panic, root_macro_call}; use clippy_utils::{is_else_clause, is_parent_stmt, peel_blocks_with_stmt, span_extract_comment, sugg}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, UnOp}; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::declare_lint_pass; declare_clippy_lint! { diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs index 03b4680c52242..deac159457a66 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -9,10 +9,10 @@ use rustc_lint::LateContext; use rustc_middle::mir::{FakeReadCause, Mutability}; use rustc_middle::ty::{self, BorrowKind}; use rustc_span::sym; +use rustc_trait_selection::infer::TyCtxtInferExt; use super::ITER_OVEREAGER_CLONED; use crate::redundant_clone::REDUNDANT_CLONE; -use crate::rustc_trait_selection::infer::TyCtxtInferExt; #[derive(Clone, Copy)] pub(super) enum Op<'a> { diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs index 2863eb190d341..47d3ed08b8ec1 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs @@ -1,4 +1,3 @@ -use crate::rustc_lint::LintContext; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir}; use clippy_utils::get_parent_expr; use clippy_utils::sugg::Sugg; @@ -9,7 +8,7 @@ use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor}; use rustc_hir::{ intravisit as hir_visit, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, Node, }; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; use rustc_middle::ty; diff --git a/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs b/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs index 6540626f7d5a3..63237c655ef17 100644 --- a/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs +++ b/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs @@ -1,9 +1,8 @@ -use crate::rustc_lint::LintContext; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_context; use rustc_errors::Applicability; use rustc_hir::{Block, ExprKind}; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::declare_lint_pass; use rustc_span::{ExpnKind, MacroKind, Span}; diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 783be802bb73b..bbde5b49588c2 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -1,5 +1,5 @@ -use crate::rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::mir; +use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::spec::abi::Abi; From fbc2abd6be069a549b8009fafec65aa6078f89f4 Mon Sep 17 00:00:00 2001 From: James Farrell Date: Wed, 8 May 2024 15:06:35 +0000 Subject: [PATCH 09/15] Update cc crate to v1.0.97 --- Cargo.lock | 6 +++--- compiler/rustc_codegen_ssa/Cargo.toml | 2 +- compiler/rustc_llvm/Cargo.toml | 2 +- library/profiler_builtins/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 84f7d21239a29..f1304735f8fad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,9 +479,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.92" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" @@ -2219,7 +2219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.4", ] [[package]] diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index f347a7fb0bb10..1562a09f5c165 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" # tidy-alphabetical-start ar_archive_writer = "0.2.0" bitflags = "2.4.1" -cc = "1.0.90" +cc = "1.0.97" itertools = "0.12" jobserver = "0.1.28" pathdiff = "0.2.0" diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index c206380a06ff3..83fda7ef07c49 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -10,5 +10,5 @@ libc = "0.2.73" [build-dependencies] # tidy-alphabetical-start -cc = "1.0.90" +cc = "1.0.97" # tidy-alphabetical-end diff --git a/library/profiler_builtins/Cargo.toml b/library/profiler_builtins/Cargo.toml index 937149f8e86d6..5b10fb5a2bd3f 100644 --- a/library/profiler_builtins/Cargo.toml +++ b/library/profiler_builtins/Cargo.toml @@ -13,4 +13,4 @@ core = { path = "../core" } compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] } [build-dependencies] -cc = "1.0.90" +cc = "1.0.97" From c7003f57ea863f1ecafe821b99e1fe5b5bc60fee Mon Sep 17 00:00:00 2001 From: Jack Rickard Date: Wed, 8 May 2024 19:42:25 +0100 Subject: [PATCH 10/15] Ignore empty RUSTC_WRAPPER in bootstrap This change ignores the RUSTC_WRAPPER_REAL environment variable if it's set to the empty string. This matches cargo behaviour and allows users to easily shadow a globally set RUSTC_WRAPPER (which they might have set for non-rustc projects). --- src/bootstrap/src/bin/rustc.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 4b182a7a693dd..d227419917767 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -91,12 +91,13 @@ fn main() { rustc_real }; - let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER_REAL") { - let mut cmd = Command::new(wrapper); - cmd.arg(rustc_driver); - cmd - } else { - Command::new(rustc_driver) + let mut cmd = match env::var_os("RUSTC_WRAPPER_REAL") { + Some(wrapper) if !wrapper.is_empty() => { + let mut cmd = Command::new(wrapper); + cmd.arg(rustc_driver); + cmd + } + _ => Command::new(rustc_driver), }; cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); From 767711b905b244f3d0adfedc727bb3acac6ac56e Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Tue, 23 Apr 2024 22:03:33 +0200 Subject: [PATCH 11/15] Use generic `NonZero` in examples. --- library/core/src/num/nonzero.rs | 364 ++++++++++++++++---------------- 1 file changed, 181 insertions(+), 183 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 5d3ae7316b124..fcdd983343d62 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -453,8 +453,7 @@ macro_rules! nonzero_integer { #[$stability:meta] Self = $Ty:ident, Primitive = $signedness:ident $Int:ident, - $(UnsignedNonZero = $UnsignedNonZero:ident,)? - UnsignedPrimitive = $UnsignedPrimitive:ty, + UnsignedPrimitive = $Uint:ty, // Used in doc comments. leading_zeros_test = $leading_zeros_test:expr, @@ -492,7 +491,7 @@ macro_rules! nonzero_integer { #[$stability] pub type $Ty = NonZero<$Int>; - impl $Ty { + impl NonZero<$Int> { /// The size of this non-zero integer type in bits. /// #[doc = concat!("This value is equal to [`", stringify!($Int), "::BITS`].")] @@ -500,9 +499,9 @@ macro_rules! nonzero_integer { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - /// - #[doc = concat!("assert_eq!(", stringify!($Ty), "::BITS, ", stringify!($Int), "::BITS);")] + /// # use std::num::NonZero; + /// # + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::BITS, ", stringify!($Int), "::BITS);")] /// ``` #[stable(feature = "nonzero_bits", since = "1.67.0")] pub const BITS: u32 = <$Int>::BITS; @@ -516,7 +515,9 @@ macro_rules! nonzero_integer { /// Basic usage: /// /// ``` - #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", $leading_zeros_test, ").unwrap();")] + /// # use std::num::NonZero; + /// # + #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(", $leading_zeros_test, ").unwrap();")] /// /// assert_eq!(n.leading_zeros(), 0); /// ``` @@ -528,7 +529,7 @@ macro_rules! nonzero_integer { pub const fn leading_zeros(self) -> u32 { // SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`. unsafe { - intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive) + intrinsics::ctlz_nonzero(self.get() as $Uint) } } @@ -542,7 +543,9 @@ macro_rules! nonzero_integer { /// Basic usage: /// /// ``` - #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")] + /// # use std::num::NonZero; + /// # + #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(0b0101000).unwrap();")] /// /// assert_eq!(n.trailing_zeros(), 3); /// ``` @@ -554,7 +557,7 @@ macro_rules! nonzero_integer { pub const fn trailing_zeros(self) -> u32 { // SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`. unsafe { - intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive) + intrinsics::cttz_nonzero(self.get() as $Uint) } } @@ -567,10 +570,10 @@ macro_rules! nonzero_integer { /// ``` /// #![feature(non_zero_count_ones)] /// + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - /// # use std::num::*; - /// # #[doc = concat!("let a = NonZero::<", stringify!($Int), ">::new(0b100_0000)?;")] #[doc = concat!("let b = NonZero::<", stringify!($Int), ">::new(0b100_0011)?;")] /// @@ -597,8 +600,7 @@ macro_rules! nonzero_integer { nonzero_integer_signedness_dependent_methods! { Self = $Ty, Primitive = $signedness $Int, - $(UnsignedNonZero = $UnsignedNonZero,)? - UnsignedPrimitive = $UnsignedPrimitive, + UnsignedPrimitive = $Uint, } /// Multiplies two non-zero integers together. @@ -608,13 +610,13 @@ macro_rules! nonzero_integer { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")] - #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")] - #[doc = concat!("let max = ", stringify!($Ty), "::new(", - stringify!($Int), "::MAX)?;")] + #[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")] + #[doc = concat!("let four = NonZero::new(4", stringify!($Int), ")?;")] + #[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(Some(four), two.checked_mul(two)); /// assert_eq!(None, max.checked_mul(two)); @@ -642,18 +644,18 @@ macro_rules! nonzero_integer { } /// Multiplies two non-zero integers together. - #[doc = concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")] + #[doc = concat!("Return [`NonZero::<", stringify!($Int), ">::MAX`] on overflow.")] /// /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")] - #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")] - #[doc = concat!("let max = ", stringify!($Ty), "::new(", - stringify!($Int), "::MAX)?;")] + #[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")] + #[doc = concat!("let four = NonZero::new(4", stringify!($Int), ")?;")] + #[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(four, two.saturating_mul(two)); /// assert_eq!(max, four.saturating_mul(max)); @@ -698,11 +700,12 @@ macro_rules! nonzero_integer { /// ``` /// #![feature(nonzero_ops)] /// - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")] - #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")] + #[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")] + #[doc = concat!("let four = NonZero::new(4", stringify!($Int), ")?;")] /// /// assert_eq!(four, unsafe { two.unchecked_mul(two) }); /// # Some(()) @@ -724,13 +727,13 @@ macro_rules! nonzero_integer { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")] - #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")] - #[doc = concat!("let half_max = ", stringify!($Ty), "::new(", - stringify!($Int), "::MAX / 2)?;")] + #[doc = concat!("let three = NonZero::new(3", stringify!($Int), ")?;")] + #[doc = concat!("let twenty_seven = NonZero::new(27", stringify!($Int), ")?;")] + #[doc = concat!("let half_max = NonZero::new(", stringify!($Int), "::MAX / 2)?;")] /// /// assert_eq!(Some(twenty_seven), three.checked_pow(3)); /// assert_eq!(None, half_max.checked_pow(3)); @@ -761,24 +764,24 @@ macro_rules! nonzero_integer { #[doc = sign_dependent_expr!{ $signedness ? if signed { - concat!("Return [`", stringify!($Ty), "::MIN`] ", - "or [`", stringify!($Ty), "::MAX`] on overflow.") + concat!("Return [`NonZero::<", stringify!($Int), ">::MIN`] ", + "or [`NonZero::<", stringify!($Int), ">::MAX`] on overflow.") } if unsigned { - concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.") + concat!("Return [`NonZero::<", stringify!($Int), ">::MAX`] on overflow.") } }] /// /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")] - #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")] - #[doc = concat!("let max = ", stringify!($Ty), "::new(", - stringify!($Int), "::MAX)?;")] + #[doc = concat!("let three = NonZero::new(3", stringify!($Int), ")?;")] + #[doc = concat!("let twenty_seven = NonZero::new(27", stringify!($Int), ")?;")] + #[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(twenty_seven, three.saturating_pow(3)); /// assert_eq!(max, max.saturating_pow(3)); @@ -804,7 +807,7 @@ macro_rules! nonzero_integer { } #[stable(feature = "nonzero_parse", since = "1.35.0")] - impl FromStr for $Ty { + impl FromStr for NonZero<$Int> { type Err = ParseIntError; fn from_str(src: &str) -> Result { Self::new(<$Int>::from_str_radix(src, 10)?) @@ -842,56 +845,55 @@ macro_rules! nonzero_integer_signedness_dependent_impls { // Impls for unsigned nonzero types only. ($Ty:ident unsigned $Int:ty) => { #[stable(feature = "nonzero_div", since = "1.51.0")] - impl Div<$Ty> for $Int { + impl Div> for $Int { type Output = $Int; - /// This operation rounds towards zero, - /// truncating any fractional part of the exact result, and cannot panic. + /// This operation rounds towards zero, truncating any fractional + /// part of the exact result, and cannot panic. #[inline] - fn div(self, other: $Ty) -> $Int { - // SAFETY: div by zero is checked because `other` is a nonzero, + fn div(self, other: NonZero<$Int>) -> $Int { + // SAFETY: Division by zero is checked because `other` is non-zero, // and MIN/-1 is checked because `self` is an unsigned int. unsafe { intrinsics::unchecked_div(self, other.get()) } } } #[stable(feature = "nonzero_div_assign", since = "1.79.0")] - impl DivAssign<$Ty> for $Int { - /// This operation rounds towards zero, - /// truncating any fractional part of the exact result, and cannot panic. + impl DivAssign> for $Int { + /// This operation rounds towards zero, truncating any fractional + /// part of the exact result, and cannot panic. #[inline] - fn div_assign(&mut self, other: $Ty) { + fn div_assign(&mut self, other: NonZero<$Int>) { *self = *self / other; } } #[stable(feature = "nonzero_div", since = "1.51.0")] - impl Rem<$Ty> for $Int { + impl Rem> for $Int { type Output = $Int; /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. #[inline] - fn rem(self, other: $Ty) -> $Int { - // SAFETY: rem by zero is checked because `other` is a nonzero, + fn rem(self, other: NonZero<$Int>) -> $Int { + // SAFETY: Remainder by zero is checked because `other` is non-zero, // and MIN/-1 is checked because `self` is an unsigned int. unsafe { intrinsics::unchecked_rem(self, other.get()) } } } #[stable(feature = "nonzero_div_assign", since = "1.79.0")] - impl RemAssign<$Ty> for $Int { + impl RemAssign> for $Int { /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. #[inline] - fn rem_assign(&mut self, other: $Ty) { + fn rem_assign(&mut self, other: NonZero<$Int>) { *self = *self % other; } } }; - // Impls for signed nonzero types only. ($Ty:ident signed $Int:ty) => { #[stable(feature = "signed_nonzero_neg", since = "1.71.0")] - impl Neg for $Ty { + impl Neg for NonZero<$Int> { type Output = Self; #[inline] @@ -901,7 +903,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls { } } - forward_ref_unop! { impl Neg, neg for $Ty, + forward_ref_unop! { impl Neg, neg for NonZero<$Int>, #[stable(feature = "signed_nonzero_neg", since = "1.71.0")] } }; } @@ -920,8 +922,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), 1", stringify!($Int), ");")] + /// # use std::num::NonZero; + /// # + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::MIN.get(), 1", stringify!($Int), ");")] /// ``` #[stable(feature = "nonzero_min_max", since = "1.70.0")] pub const MIN: Self = Self::new(1).unwrap(); @@ -933,8 +936,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")] + /// # use std::num::NonZero; + /// # + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::MAX.get(), ", stringify!($Int), "::MAX);")] /// ``` #[stable(feature = "nonzero_min_max", since = "1.70.0")] pub const MAX: Self = Self::new(<$Int>::MAX).unwrap(); @@ -947,13 +951,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")] - #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")] - #[doc = concat!("let max = ", stringify!($Ty), "::new(", - stringify!($Int), "::MAX)?;")] + #[doc = concat!("let one = NonZero::new(1", stringify!($Int), ")?;")] + #[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")] + #[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(Some(two), one.checked_add(1)); /// assert_eq!(None, max.checked_add(1)); @@ -981,18 +985,18 @@ macro_rules! nonzero_integer_signedness_dependent_methods { } /// Adds an unsigned integer to a non-zero value. - #[doc = concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")] + #[doc = concat!("Return [`NonZero::<", stringify!($Int), ">::MAX`] on overflow.")] /// /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")] - #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")] - #[doc = concat!("let max = ", stringify!($Ty), "::new(", - stringify!($Int), "::MAX)?;")] + #[doc = concat!("let one = NonZero::new(1", stringify!($Int), ")?;")] + #[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")] + #[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(two, one.saturating_add(1)); /// assert_eq!(max, max.saturating_add(1)); @@ -1027,11 +1031,12 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// ``` /// #![feature(nonzero_ops)] /// - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")] - #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")] + #[doc = concat!("let one = NonZero::new(1", stringify!($Int), ")?;")] + #[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")] /// /// assert_eq!(two, unsafe { one.unchecked_add(1) }); /// # Some(()) @@ -1054,14 +1059,14 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")] - #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")] - #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")] - #[doc = concat!("let max = ", stringify!($Ty), "::new(", - stringify!($Int), "::MAX)?;")] + #[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")] + #[doc = concat!("let three = NonZero::new(3", stringify!($Int), ")?;")] + #[doc = concat!("let four = NonZero::new(4", stringify!($Int), ")?;")] + #[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(Some(two), two.checked_next_power_of_two() ); /// assert_eq!(Some(four), three.checked_next_power_of_two() ); @@ -1094,10 +1099,11 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(7).unwrap().ilog2(), 2);")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(8).unwrap().ilog2(), 3);")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(9).unwrap().ilog2(), 3);")] + /// # use std::num::NonZero; + /// # + #[doc = concat!("assert_eq!(NonZero::new(7", stringify!($Int), ").unwrap().ilog2(), 2);")] + #[doc = concat!("assert_eq!(NonZero::new(8", stringify!($Int), ").unwrap().ilog2(), 3);")] + #[doc = concat!("assert_eq!(NonZero::new(9", stringify!($Int), ").unwrap().ilog2(), 3);")] /// ``` #[stable(feature = "int_log", since = "1.67.0")] #[rustc_const_stable(feature = "int_log", since = "1.67.0")] @@ -1118,10 +1124,11 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(99).unwrap().ilog10(), 1);")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(100).unwrap().ilog10(), 2);")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(101).unwrap().ilog10(), 2);")] + /// # use std::num::NonZero; + /// # + #[doc = concat!("assert_eq!(NonZero::new(99", stringify!($Int), ").unwrap().ilog10(), 1);")] + #[doc = concat!("assert_eq!(NonZero::new(100", stringify!($Int), ").unwrap().ilog10(), 2);")] + #[doc = concat!("assert_eq!(NonZero::new(101", stringify!($Int), ").unwrap().ilog10(), 2);")] /// ``` #[stable(feature = "int_log", since = "1.67.0")] #[rustc_const_stable(feature = "int_log", since = "1.67.0")] @@ -1142,13 +1149,14 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// /// ``` /// #![feature(num_midpoint)] - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")] - #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")] - #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")] + #[doc = concat!("let one = NonZero::new(1", stringify!($Int), ")?;")] + #[doc = concat!("let two = NonZero::new(2", stringify!($Int), ")?;")] + #[doc = concat!("let four = NonZero::new(4", stringify!($Int), ")?;")] /// /// assert_eq!(one.midpoint(four), two); /// assert_eq!(four.midpoint(one), two); @@ -1179,9 +1187,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// Basic usage: /// /// ``` - #[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")] + #[doc = concat!("let eight = std::num::NonZero::new(8", stringify!($Int), ").unwrap();")] /// assert!(eight.is_power_of_two()); - #[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")] + #[doc = concat!("let ten = std::num::NonZero::new(10", stringify!($Int), ").unwrap();")] /// assert!(!ten.is_power_of_two()); /// ``` #[must_use] @@ -1202,7 +1210,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods { ( Self = $Ty:ident, Primitive = signed $Int:ident, - UnsignedNonZero = $Uty:ident, UnsignedPrimitive = $Uint:ty, ) => { /// The smallest value that can be represented by this non-zero @@ -1216,8 +1223,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), ", stringify!($Int), "::MIN);")] + /// # use std::num::NonZero; + /// # + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::MIN.get(), ", stringify!($Int), "::MIN);")] /// ``` #[stable(feature = "nonzero_min_max", since = "1.70.0")] pub const MIN: Self = Self::new(<$Int>::MIN).unwrap(); @@ -1233,8 +1241,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Examples /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")] + /// # use std::num::NonZero; + /// # + #[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::MAX.get(), ", stringify!($Int), "::MAX);")] /// ``` #[stable(feature = "nonzero_min_max", since = "1.70.0")] pub const MAX: Self = Self::new(<$Int>::MAX).unwrap(); @@ -1246,11 +1255,12 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")] - #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")] + #[doc = concat!("let pos = NonZero::new(1", stringify!($Int), ")?;")] + #[doc = concat!("let neg = NonZero::new(-1", stringify!($Int), ")?;")] /// /// assert_eq!(pos, pos.abs()); /// assert_eq!(pos, neg.abs()); @@ -1269,19 +1279,19 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// Checked absolute value. /// Checks for overflow and returns [`None`] if - #[doc = concat!("`self == ", stringify!($Ty), "::MIN`.")] + #[doc = concat!("`self == NonZero::<", stringify!($Int), ">::MIN`.")] /// The result cannot be zero. /// /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")] - #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")] - #[doc = concat!("let min = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN)?;")] + #[doc = concat!("let pos = NonZero::new(1", stringify!($Int), ")?;")] + #[doc = concat!("let neg = NonZero::new(-1", stringify!($Int), ")?;")] + #[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")] /// /// assert_eq!(Some(pos), neg.checked_abs()); /// assert_eq!(None, min.checked_abs()); @@ -1309,13 +1319,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")] - #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")] - #[doc = concat!("let min = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN)?;")] + #[doc = concat!("let pos = NonZero::new(1", stringify!($Int), ")?;")] + #[doc = concat!("let neg = NonZero::new(-1", stringify!($Int), ")?;")] + #[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")] /// /// assert_eq!((pos, false), pos.overflowing_abs()); /// assert_eq!((pos, false), neg.overflowing_abs()); @@ -1343,17 +1353,15 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")] - #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")] - #[doc = concat!("let min = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN)?;")] - #[doc = concat!("let min_plus = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN + 1)?;")] - #[doc = concat!("let max = ", stringify!($Ty), "::new(", - stringify!($Int), "::MAX)?;")] + #[doc = concat!("let pos = NonZero::new(1", stringify!($Int), ")?;")] + #[doc = concat!("let neg = NonZero::new(-1", stringify!($Int), ")?;")] + #[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")] + #[doc = concat!("let min_plus = NonZero::new(", stringify!($Int), "::MIN + 1)?;")] + #[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(pos, pos.saturating_abs()); /// assert_eq!(pos, neg.saturating_abs()); @@ -1378,15 +1386,14 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")] - #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")] - #[doc = concat!("let min = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN)?;")] - #[doc = concat!("# let max = ", stringify!($Ty), "::new(", - stringify!($Int), "::MAX)?;")] + #[doc = concat!("let pos = NonZero::new(1", stringify!($Int), ")?;")] + #[doc = concat!("let neg = NonZero::new(-1", stringify!($Int), ")?;")] + #[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")] + #[doc = concat!("# let max = NonZero::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(pos, pos.wrapping_abs()); /// assert_eq!(pos, neg.wrapping_abs()); @@ -1411,18 +1418,15 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] - #[doc = concat!("# use std::num::", stringify!($Uty), ";")] - /// + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let u_pos = ", stringify!($Uty), "::new(1)?;")] - #[doc = concat!("let i_pos = ", stringify!($Ty), "::new(1)?;")] - #[doc = concat!("let i_neg = ", stringify!($Ty), "::new(-1)?;")] - #[doc = concat!("let i_min = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN)?;")] - #[doc = concat!("let u_max = ", stringify!($Uty), "::new(", - stringify!($Uint), "::MAX / 2 + 1)?;")] + #[doc = concat!("let u_pos = NonZero::new(1", stringify!($Uint), ")?;")] + #[doc = concat!("let i_pos = NonZero::new(1", stringify!($Int), ")?;")] + #[doc = concat!("let i_neg = NonZero::new(-1", stringify!($Int), ")?;")] + #[doc = concat!("let i_min = NonZero::new(", stringify!($Int), "::MIN)?;")] + #[doc = concat!("let u_max = NonZero::new(", stringify!($Uint), "::MAX / 2 + 1)?;")] /// /// assert_eq!(u_pos, i_pos.unsigned_abs()); /// assert_eq!(u_pos, i_neg.unsigned_abs()); @@ -1435,9 +1439,9 @@ macro_rules! nonzero_integer_signedness_dependent_methods { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn unsigned_abs(self) -> $Uty { + pub const fn unsigned_abs(self) -> NonZero<$Uint> { // SAFETY: absolute value of nonzero cannot yield zero values. - unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) } + unsafe { NonZero::new_unchecked(self.get().unsigned_abs()) } } /// Returns `true` if `self` is positive and `false` if the @@ -1446,11 +1450,12 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] - #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] + #[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")] + #[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")] /// /// assert!(pos_five.is_positive()); /// assert!(!neg_five.is_positive()); @@ -1471,11 +1476,12 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] - #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] + #[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")] + #[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")] /// /// assert!(neg_five.is_negative()); /// assert!(!pos_five.is_negative()); @@ -1491,18 +1497,18 @@ macro_rules! nonzero_integer_signedness_dependent_methods { } /// Checked negation. Computes `-self`, - #[doc = concat!("returning `None` if `self == ", stringify!($Ty), "::MIN`.")] + #[doc = concat!("returning `None` if `self == NonZero::<", stringify!($Int), ">::MIN`.")] /// /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] - #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] - #[doc = concat!("let min = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN)?;")] + #[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")] + #[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")] + #[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")] /// /// assert_eq!(pos_five.checked_neg(), Some(neg_five)); /// assert_eq!(min.checked_neg(), None); @@ -1528,13 +1534,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] - #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] - #[doc = concat!("let min = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN)?;")] + #[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")] + #[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")] + #[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")] /// /// assert_eq!(pos_five.overflowing_neg(), (neg_five, false)); /// assert_eq!(min.overflowing_neg(), (min, true)); @@ -1551,24 +1557,22 @@ macro_rules! nonzero_integer_signedness_dependent_methods { } /// Saturating negation. Computes `-self`, - #[doc = concat!("returning [`", stringify!($Ty), "::MAX`]")] - #[doc = concat!("if `self == ", stringify!($Ty), "::MIN`")] + #[doc = concat!("returning [`NonZero::<", stringify!($Int), ">::MAX`]")] + #[doc = concat!("if `self == NonZero::<", stringify!($Int), ">::MIN`")] /// instead of overflowing. /// /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] - #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] - #[doc = concat!("let min = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN)?;")] - #[doc = concat!("let min_plus_one = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN + 1)?;")] - #[doc = concat!("let max = ", stringify!($Ty), "::new(", - stringify!($Int), "::MAX)?;")] + #[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")] + #[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")] + #[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")] + #[doc = concat!("let min_plus_one = NonZero::new(", stringify!($Int), "::MIN + 1)?;")] + #[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX)?;")] /// /// assert_eq!(pos_five.saturating_neg(), neg_five); /// assert_eq!(min.saturating_neg(), max); @@ -1595,13 +1599,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Example /// /// ``` - #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # use std::num::NonZero; + /// # /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { - #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] - #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] - #[doc = concat!("let min = ", stringify!($Ty), "::new(", - stringify!($Int), "::MIN)?;")] + #[doc = concat!("let pos_five = NonZero::new(5", stringify!($Int), ")?;")] + #[doc = concat!("let neg_five = NonZero::new(-5", stringify!($Int), ")?;")] + #[doc = concat!("let min = NonZero::new(", stringify!($Int), "::MIN)?;")] /// /// assert_eq!(pos_five.wrapping_neg(), neg_five); /// assert_eq!(min.wrapping_neg(), min); @@ -1662,41 +1666,35 @@ nonzero_integer! { nonzero_integer! { Self = NonZeroI8, Primitive = signed i8, - UnsignedNonZero = NonZeroU8, UnsignedPrimitive = u8, } nonzero_integer! { Self = NonZeroI16, Primitive = signed i16, - UnsignedNonZero = NonZeroU16, UnsignedPrimitive = u16, } nonzero_integer! { Self = NonZeroI32, Primitive = signed i32, - UnsignedNonZero = NonZeroU32, UnsignedPrimitive = u32, } nonzero_integer! { Self = NonZeroI64, Primitive = signed i64, - UnsignedNonZero = NonZeroU64, UnsignedPrimitive = u64, } nonzero_integer! { Self = NonZeroI128, Primitive = signed i128, - UnsignedNonZero = NonZeroU128, UnsignedPrimitive = u128, } nonzero_integer! { Self = NonZeroIsize, Primitive = signed isize, - UnsignedNonZero = NonZeroUsize, UnsignedPrimitive = usize, } From 3fe0be9e38309a285d54ee54f44ef7db2b07bcf0 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Tue, 23 Apr 2024 21:15:33 +0200 Subject: [PATCH 12/15] Simplify `clippy` lint. --- .../clippy/clippy_lints/src/transmute/mod.rs | 10 +-- .../transmute/transmute_int_to_non_zero.rs | 35 ++------ .../tests/ui/transmute_int_to_non_zero.fixed | 62 +++++++------- .../tests/ui/transmute_int_to_non_zero.rs | 62 +++++++------- .../tests/ui/transmute_int_to_non_zero.stderr | 80 +++++++++---------- 5 files changed, 113 insertions(+), 136 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs index 7fa536a1a29d9..598032ccdebed 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs @@ -257,7 +257,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for transmutes from integers to `NonZero*` types, and suggests their `new_unchecked` + /// Checks for transmutes from `T` to `NonZero`, and suggests the `new_unchecked` /// method instead. /// /// ### Why is this bad? @@ -266,13 +266,13 @@ declare_clippy_lint! { /// /// ### Example /// ```no_run - /// # use core::num::NonZeroU32; - /// let _non_zero: NonZeroU32 = unsafe { std::mem::transmute(123) }; + /// # use core::num::NonZero; + /// let _: NonZero = unsafe { std::mem::transmute(123) }; /// ``` /// Use instead: /// ```no_run - /// # use core::num::NonZeroU32; - /// let _non_zero = unsafe { NonZeroU32::new_unchecked(123) }; + /// # use core::num::NonZero; + /// let _: NonZero = unsafe { NonZero::new_unchecked(123) }; /// ``` #[clippy::version = "1.69.0"] pub TRANSMUTE_INT_TO_NON_ZERO, diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs index 2bea3be3d6030..7d824ef213900 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs @@ -26,45 +26,22 @@ pub(super) fn check<'tcx>( return false; }; - // FIXME: This can be simplified once `NonZero` is stable. - let coercible_types = [ - ("NonZeroU8", tcx.types.u8), - ("NonZeroU16", tcx.types.u16), - ("NonZeroU32", tcx.types.u32), - ("NonZeroU64", tcx.types.u64), - ("NonZeroU128", tcx.types.u128), - ("NonZeroUsize", tcx.types.usize), - ("NonZeroI8", tcx.types.i8), - ("NonZeroI16", tcx.types.i16), - ("NonZeroI32", tcx.types.i32), - ("NonZeroI64", tcx.types.i64), - ("NonZeroI128", tcx.types.i128), - ("NonZeroIsize", tcx.types.isize), - ]; - - let int_type = substs.type_at(0); - - let Some(nonzero_alias) = coercible_types.iter().find_map(|(nonzero_alias, t)| { - if *t == int_type && *t == from_ty { - Some(nonzero_alias) - } else { - None - } - }) else { - return false; - }; + let int_ty = substs.type_at(0); + if from_ty != int_ty { + return false; + } span_lint_and_then( cx, TRANSMUTE_INT_TO_NON_ZERO, e.span, - format!("transmute from a `{from_ty}` to a `{nonzero_alias}`"), + format!("transmute from a `{from_ty}` to a `{}<{int_ty}>`", sym::NonZero), |diag| { let arg = sugg::Sugg::hir(cx, arg, ".."); diag.span_suggestion( e.span, "consider using", - format!("{nonzero_alias}::{}({arg})", sym::new_unchecked), + format!("{}::{}({arg})", sym::NonZero, sym::new_unchecked), Applicability::Unspecified, ); }, diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed index fe8db3dcb0cf9..1a48051ec8c4d 100644 --- a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed +++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed @@ -1,7 +1,7 @@ #![warn(clippy::transmute_int_to_non_zero)] #![allow(clippy::missing_transmute_annotations)] -use core::num::*; +use core::num::NonZero; fn main() { let int_u8: u8 = 1; @@ -16,38 +16,38 @@ fn main() { let int_i64: i64 = 1; let int_i128: i128 = 1; - let _: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(int_u8) }; - //~^ ERROR: transmute from a `u8` to a `NonZeroU8` + let _: NonZero = unsafe { NonZero::new_unchecked(int_u8) }; + //~^ ERROR: transmute from a `u8` to a `NonZero` //~| NOTE: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings` - let _: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(int_u16) }; - //~^ ERROR: transmute from a `u16` to a `NonZeroU16` - let _: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(int_u32) }; - //~^ ERROR: transmute from a `u32` to a `NonZeroU32` - let _: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(int_u64) }; - //~^ ERROR: transmute from a `u64` to a `NonZeroU64` - let _: NonZeroU128 = unsafe { NonZeroU128::new_unchecked(int_u128) }; - //~^ ERROR: transmute from a `u128` to a `NonZeroU128` + let _: NonZero = unsafe { NonZero::new_unchecked(int_u16) }; + //~^ ERROR: transmute from a `u16` to a `NonZero` + let _: NonZero = unsafe { NonZero::new_unchecked(int_u32) }; + //~^ ERROR: transmute from a `u32` to a `NonZero` + let _: NonZero = unsafe { NonZero::new_unchecked(int_u64) }; + //~^ ERROR: transmute from a `u64` to a `NonZero` + let _: NonZero = unsafe { NonZero::new_unchecked(int_u128) }; + //~^ ERROR: transmute from a `u128` to a `NonZero` - let _: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(int_i8) }; - //~^ ERROR: transmute from a `i8` to a `NonZeroI8` - let _: NonZeroI16 = unsafe { NonZeroI16::new_unchecked(int_i16) }; - //~^ ERROR: transmute from a `i16` to a `NonZeroI16` - let _: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(int_i32) }; - //~^ ERROR: transmute from a `i32` to a `NonZeroI32` - let _: NonZeroI64 = unsafe { NonZeroI64::new_unchecked(int_i64) }; - //~^ ERROR: transmute from a `i64` to a `NonZeroI64` - let _: NonZeroI128 = unsafe { NonZeroI128::new_unchecked(int_i128) }; - //~^ ERROR: transmute from a `i128` to a `NonZeroI128` + let _: NonZero = unsafe { NonZero::new_unchecked(int_i8) }; + //~^ ERROR: transmute from a `i8` to a `NonZero` + let _: NonZero = unsafe { NonZero::new_unchecked(int_i16) }; + //~^ ERROR: transmute from a `i16` to a `NonZero` + let _: NonZero = unsafe { NonZero::new_unchecked(int_i32) }; + //~^ ERROR: transmute from a `i32` to a `NonZero` + let _: NonZero = unsafe { NonZero::new_unchecked(int_i64) }; + //~^ ERROR: transmute from a `i64` to a `NonZero` + let _: NonZero = unsafe { NonZero::new_unchecked(int_i128) }; + //~^ ERROR: transmute from a `i128` to a `NonZero` - let _: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(int_u8) }; - let _: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(int_u16) }; - let _: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(int_u32) }; - let _: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(int_u64) }; - let _: NonZeroU128 = unsafe { NonZeroU128::new_unchecked(int_u128) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_u8) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_u16) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_u32) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_u64) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_u128) }; - let _: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(int_i8) }; - let _: NonZeroI16 = unsafe { NonZeroI16::new_unchecked(int_i16) }; - let _: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(int_i32) }; - let _: NonZeroI64 = unsafe { NonZeroI64::new_unchecked(int_i64) }; - let _: NonZeroI128 = unsafe { NonZeroI128::new_unchecked(int_i128) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_i8) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_i16) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_i32) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_i64) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_i128) }; } diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs index a79ed5279b1f2..d8e842fb99ceb 100644 --- a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs +++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs @@ -1,7 +1,7 @@ #![warn(clippy::transmute_int_to_non_zero)] #![allow(clippy::missing_transmute_annotations)] -use core::num::*; +use core::num::NonZero; fn main() { let int_u8: u8 = 1; @@ -16,38 +16,38 @@ fn main() { let int_i64: i64 = 1; let int_i128: i128 = 1; - let _: NonZeroU8 = unsafe { std::mem::transmute(int_u8) }; - //~^ ERROR: transmute from a `u8` to a `NonZeroU8` + let _: NonZero = unsafe { std::mem::transmute(int_u8) }; + //~^ ERROR: transmute from a `u8` to a `NonZero` //~| NOTE: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings` - let _: NonZeroU16 = unsafe { std::mem::transmute(int_u16) }; - //~^ ERROR: transmute from a `u16` to a `NonZeroU16` - let _: NonZeroU32 = unsafe { std::mem::transmute(int_u32) }; - //~^ ERROR: transmute from a `u32` to a `NonZeroU32` - let _: NonZeroU64 = unsafe { std::mem::transmute(int_u64) }; - //~^ ERROR: transmute from a `u64` to a `NonZeroU64` - let _: NonZeroU128 = unsafe { std::mem::transmute(int_u128) }; - //~^ ERROR: transmute from a `u128` to a `NonZeroU128` + let _: NonZero = unsafe { std::mem::transmute(int_u16) }; + //~^ ERROR: transmute from a `u16` to a `NonZero` + let _: NonZero = unsafe { std::mem::transmute(int_u32) }; + //~^ ERROR: transmute from a `u32` to a `NonZero` + let _: NonZero = unsafe { std::mem::transmute(int_u64) }; + //~^ ERROR: transmute from a `u64` to a `NonZero` + let _: NonZero = unsafe { std::mem::transmute(int_u128) }; + //~^ ERROR: transmute from a `u128` to a `NonZero` - let _: NonZeroI8 = unsafe { std::mem::transmute(int_i8) }; - //~^ ERROR: transmute from a `i8` to a `NonZeroI8` - let _: NonZeroI16 = unsafe { std::mem::transmute(int_i16) }; - //~^ ERROR: transmute from a `i16` to a `NonZeroI16` - let _: NonZeroI32 = unsafe { std::mem::transmute(int_i32) }; - //~^ ERROR: transmute from a `i32` to a `NonZeroI32` - let _: NonZeroI64 = unsafe { std::mem::transmute(int_i64) }; - //~^ ERROR: transmute from a `i64` to a `NonZeroI64` - let _: NonZeroI128 = unsafe { std::mem::transmute(int_i128) }; - //~^ ERROR: transmute from a `i128` to a `NonZeroI128` + let _: NonZero = unsafe { std::mem::transmute(int_i8) }; + //~^ ERROR: transmute from a `i8` to a `NonZero` + let _: NonZero = unsafe { std::mem::transmute(int_i16) }; + //~^ ERROR: transmute from a `i16` to a `NonZero` + let _: NonZero = unsafe { std::mem::transmute(int_i32) }; + //~^ ERROR: transmute from a `i32` to a `NonZero` + let _: NonZero = unsafe { std::mem::transmute(int_i64) }; + //~^ ERROR: transmute from a `i64` to a `NonZero` + let _: NonZero = unsafe { std::mem::transmute(int_i128) }; + //~^ ERROR: transmute from a `i128` to a `NonZero` - let _: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(int_u8) }; - let _: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(int_u16) }; - let _: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(int_u32) }; - let _: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(int_u64) }; - let _: NonZeroU128 = unsafe { NonZeroU128::new_unchecked(int_u128) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_u8) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_u16) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_u32) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_u64) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_u128) }; - let _: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(int_i8) }; - let _: NonZeroI16 = unsafe { NonZeroI16::new_unchecked(int_i16) }; - let _: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(int_i32) }; - let _: NonZeroI64 = unsafe { NonZeroI64::new_unchecked(int_i64) }; - let _: NonZeroI128 = unsafe { NonZeroI128::new_unchecked(int_i128) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_i8) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_i16) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_i32) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_i64) }; + let _: NonZero = unsafe { NonZero::new_unchecked(int_i128) }; } diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr index bb0b0d0ff4f06..199b8ec59d092 100644 --- a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr +++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr @@ -1,65 +1,65 @@ -error: transmute from a `u8` to a `NonZeroU8` - --> tests/ui/transmute_int_to_non_zero.rs:19:33 +error: transmute from a `u8` to a `NonZero` + --> tests/ui/transmute_int_to_non_zero.rs:19:35 | -LL | let _: NonZeroU8 = unsafe { std::mem::transmute(int_u8) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU8::new_unchecked(int_u8)` +LL | let _: NonZero = unsafe { std::mem::transmute(int_u8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u8)` | = note: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_non_zero)]` -error: transmute from a `u16` to a `NonZeroU16` - --> tests/ui/transmute_int_to_non_zero.rs:22:34 +error: transmute from a `u16` to a `NonZero` + --> tests/ui/transmute_int_to_non_zero.rs:22:36 | -LL | let _: NonZeroU16 = unsafe { std::mem::transmute(int_u16) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU16::new_unchecked(int_u16)` +LL | let _: NonZero = unsafe { std::mem::transmute(int_u16) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u16)` -error: transmute from a `u32` to a `NonZeroU32` - --> tests/ui/transmute_int_to_non_zero.rs:24:34 +error: transmute from a `u32` to a `NonZero` + --> tests/ui/transmute_int_to_non_zero.rs:24:36 | -LL | let _: NonZeroU32 = unsafe { std::mem::transmute(int_u32) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU32::new_unchecked(int_u32)` +LL | let _: NonZero = unsafe { std::mem::transmute(int_u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u32)` -error: transmute from a `u64` to a `NonZeroU64` - --> tests/ui/transmute_int_to_non_zero.rs:26:34 +error: transmute from a `u64` to a `NonZero` + --> tests/ui/transmute_int_to_non_zero.rs:26:36 | -LL | let _: NonZeroU64 = unsafe { std::mem::transmute(int_u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU64::new_unchecked(int_u64)` +LL | let _: NonZero = unsafe { std::mem::transmute(int_u64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u64)` -error: transmute from a `u128` to a `NonZeroU128` - --> tests/ui/transmute_int_to_non_zero.rs:28:35 +error: transmute from a `u128` to a `NonZero` + --> tests/ui/transmute_int_to_non_zero.rs:28:37 | -LL | let _: NonZeroU128 = unsafe { std::mem::transmute(int_u128) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU128::new_unchecked(int_u128)` +LL | let _: NonZero = unsafe { std::mem::transmute(int_u128) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u128)` -error: transmute from a `i8` to a `NonZeroI8` - --> tests/ui/transmute_int_to_non_zero.rs:31:33 +error: transmute from a `i8` to a `NonZero` + --> tests/ui/transmute_int_to_non_zero.rs:31:35 | -LL | let _: NonZeroI8 = unsafe { std::mem::transmute(int_i8) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI8::new_unchecked(int_i8)` +LL | let _: NonZero = unsafe { std::mem::transmute(int_i8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i8)` -error: transmute from a `i16` to a `NonZeroI16` - --> tests/ui/transmute_int_to_non_zero.rs:33:34 +error: transmute from a `i16` to a `NonZero` + --> tests/ui/transmute_int_to_non_zero.rs:33:36 | -LL | let _: NonZeroI16 = unsafe { std::mem::transmute(int_i16) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI16::new_unchecked(int_i16)` +LL | let _: NonZero = unsafe { std::mem::transmute(int_i16) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i16)` -error: transmute from a `i32` to a `NonZeroI32` - --> tests/ui/transmute_int_to_non_zero.rs:35:34 +error: transmute from a `i32` to a `NonZero` + --> tests/ui/transmute_int_to_non_zero.rs:35:36 | -LL | let _: NonZeroI32 = unsafe { std::mem::transmute(int_i32) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI32::new_unchecked(int_i32)` +LL | let _: NonZero = unsafe { std::mem::transmute(int_i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i32)` -error: transmute from a `i64` to a `NonZeroI64` - --> tests/ui/transmute_int_to_non_zero.rs:37:34 +error: transmute from a `i64` to a `NonZero` + --> tests/ui/transmute_int_to_non_zero.rs:37:36 | -LL | let _: NonZeroI64 = unsafe { std::mem::transmute(int_i64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI64::new_unchecked(int_i64)` +LL | let _: NonZero = unsafe { std::mem::transmute(int_i64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i64)` -error: transmute from a `i128` to a `NonZeroI128` - --> tests/ui/transmute_int_to_non_zero.rs:39:35 +error: transmute from a `i128` to a `NonZero` + --> tests/ui/transmute_int_to_non_zero.rs:39:37 | -LL | let _: NonZeroI128 = unsafe { std::mem::transmute(int_i128) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI128::new_unchecked(int_i128)` +LL | let _: NonZero = unsafe { std::mem::transmute(int_i128) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i128)` error: aborting due to 10 previous errors From 7531eafa7e20eed36c8738e45790d4a82b702162 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Tue, 23 Apr 2024 21:19:12 +0200 Subject: [PATCH 13/15] Simplify suggestion. --- .../src/fn_ctxt/suggestions.rs | 29 ++++--------------- .../non_zero_assigned_something.rs | 8 ++--- .../non_zero_assigned_something.stderr | 24 +++++++-------- 3 files changed, 22 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index d00fea4fae498..61017a2ebd19b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2227,7 +2227,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> bool { let tcx = self.tcx; let (adt, args, unwrap) = match expected.kind() { - // In case Option is wanted, but * is provided, suggest calling new + // In case `Option>` is wanted, but `T` is provided, suggest calling `new`. ty::Adt(adt, args) if tcx.is_diagnostic_item(sym::Option, adt.did()) => { let nonzero_type = args.type_at(0); // Unwrap option type. let ty::Adt(adt, args) = nonzero_type.kind() else { @@ -2235,7 +2235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; (adt, args, "") } - // In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types. + // In case `NonZero` is wanted but `T` is provided, also add `.unwrap()` to satisfy types. ty::Adt(adt, args) => (adt, args, ".unwrap()"), _ => return false, }; @@ -2244,32 +2244,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - // FIXME: This can be simplified once `NonZero` is stable. - let coercable_types = [ - ("NonZeroU8", tcx.types.u8), - ("NonZeroU16", tcx.types.u16), - ("NonZeroU32", tcx.types.u32), - ("NonZeroU64", tcx.types.u64), - ("NonZeroU128", tcx.types.u128), - ("NonZeroI8", tcx.types.i8), - ("NonZeroI16", tcx.types.i16), - ("NonZeroI32", tcx.types.i32), - ("NonZeroI64", tcx.types.i64), - ("NonZeroI128", tcx.types.i128), - ]; - let int_type = args.type_at(0); - - let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| { - if *t == int_type && self.can_coerce(expr_ty, *t) { Some(nonzero_alias) } else { None } - }) else { + if !self.can_coerce(expr_ty, int_type) { return false; - }; + } err.multipart_suggestion( - format!("consider calling `{nonzero_alias}::new`"), + format!("consider calling `{}::new`", sym::NonZero), vec![ - (expr.span.shrink_to_lo(), format!("{nonzero_alias}::new(")), + (expr.span.shrink_to_lo(), format!("{}::new(", sym::NonZero)), (expr.span.shrink_to_hi(), format!("){unwrap}")), ], Applicability::MaybeIncorrect, diff --git a/tests/ui/mismatched_types/non_zero_assigned_something.rs b/tests/ui/mismatched_types/non_zero_assigned_something.rs index d2adbe01c1828..e94d5249d6a84 100644 --- a/tests/ui/mismatched_types/non_zero_assigned_something.rs +++ b/tests/ui/mismatched_types/non_zero_assigned_something.rs @@ -1,9 +1,9 @@ fn main() { - let _: std::num::NonZeroU64 = 1; + let _: std::num::NonZero = 1; //~^ ERROR mismatched types - //~| HELP consider calling `NonZeroU64::new` + //~| HELP consider calling `NonZero::new` - let _: Option = 1; + let _: Option> = 1; //~^ ERROR mismatched types - //~| HELP consider calling `NonZeroU64::new` + //~| HELP consider calling `NonZero::new` } diff --git a/tests/ui/mismatched_types/non_zero_assigned_something.stderr b/tests/ui/mismatched_types/non_zero_assigned_something.stderr index f8e86905ab9bb..aa015bd2efcc9 100644 --- a/tests/ui/mismatched_types/non_zero_assigned_something.stderr +++ b/tests/ui/mismatched_types/non_zero_assigned_something.stderr @@ -1,32 +1,32 @@ error[E0308]: mismatched types - --> $DIR/non_zero_assigned_something.rs:2:35 + --> $DIR/non_zero_assigned_something.rs:2:37 | -LL | let _: std::num::NonZeroU64 = 1; - | -------------------- ^ expected `NonZero`, found integer +LL | let _: std::num::NonZero = 1; + | ---------------------- ^ expected `NonZero`, found integer | | | expected due to this | = note: expected struct `NonZero` found type `{integer}` -help: consider calling `NonZeroU64::new` +help: consider calling `NonZero::new` | -LL | let _: std::num::NonZeroU64 = NonZeroU64::new(1).unwrap(); - | ++++++++++++++++ ++++++++++ +LL | let _: std::num::NonZero = NonZero::new(1).unwrap(); + | +++++++++++++ ++++++++++ error[E0308]: mismatched types - --> $DIR/non_zero_assigned_something.rs:6:43 + --> $DIR/non_zero_assigned_something.rs:6:45 | -LL | let _: Option = 1; - | ---------------------------- ^ expected `Option>`, found integer +LL | let _: Option> = 1; + | ------------------------------ ^ expected `Option>`, found integer | | | expected due to this | = note: expected enum `Option>` found type `{integer}` -help: consider calling `NonZeroU64::new` +help: consider calling `NonZero::new` | -LL | let _: Option = NonZeroU64::new(1); - | ++++++++++++++++ + +LL | let _: Option> = NonZero::new(1); + | +++++++++++++ + error: aborting due to 2 previous errors From bd8e565e16b43e2e68a67804d20992218579ac9d Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 21 Apr 2024 21:45:18 +0200 Subject: [PATCH 14/15] Use generic `NonZero`. --- compiler/rustc_abi/src/layout.rs | 7 ++++--- compiler/rustc_abi/src/lib.rs | 4 ++-- compiler/rustc_ast/src/ast.rs | 2 +- compiler/stable_mir/src/abi.rs | 4 ++-- library/core/src/iter/adapters/step_by.rs | 10 +++++----- src/tools/build-manifest/src/main.rs | 2 +- .../src/transmute/eager_transmute.rs | 2 +- src/tools/clippy/lintcheck/src/config.rs | 4 ++-- .../tests/ui/arithmetic_side_effects.rs | 8 ++++---- .../clippy/tests/ui/eager_transmute.fixed | 20 +++++++++---------- src/tools/clippy/tests/ui/eager_transmute.rs | 20 +++++++++---------- .../clippy/tests/ui/eager_transmute.stderr | 18 ++++++++--------- ...um-set-discriminant-niche-variant-wrong.rs | 4 ++-- .../function_pointers/abi_mismatch_repr_C.rs | 6 +++--- .../abi_mismatch_repr_C.stderr | 4 ++-- .../cast_fn_ptr_invalid_callee_ret.rs | 12 +++++------ .../cast_fn_ptr_invalid_caller_arg.rs | 14 ++++++------- .../tests/pass/function_calls/abi_compat.rs | 8 ++++---- .../available-parallelism-miri-num-cpus.rs | 4 ++-- src/tools/miri/tests/ui.rs | 4 ++-- tests/ui-fulldeps/stable-mir/check_abi.rs | 6 +++--- .../pattern_types/range_patterns_usage.rs | 2 +- 22 files changed, 83 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index a95ef4c460f45..c57be5d110641 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -2,6 +2,7 @@ use std::borrow::{Borrow, Cow}; use std::cmp; use std::fmt::{self, Write}; use std::iter; +use std::num::NonZero; use std::ops::Bound; use std::ops::Deref; @@ -10,8 +11,8 @@ use tracing::debug; use crate::{ Abi, AbiAndPrefAlign, Align, FieldsShape, IndexSlice, IndexVec, Integer, LayoutS, Niche, - NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, TargetDataLayout, - Variants, WrappingRange, + Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, TargetDataLayout, Variants, + WrappingRange, }; // A variant is absent if it's uninhabited and only has ZST fields. @@ -327,7 +328,7 @@ pub trait LayoutCalculator { Some(LayoutS { variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Union(NonZeroUsize::new(only_variant.len())?), + fields: FieldsShape::Union(NonZero::new(only_variant.len())?), abi, largest_niche: None, align, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 5e3f64540e4aa..ef5f58b1d1654 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -4,7 +4,7 @@ #![cfg_attr(feature = "nightly", feature(rustdoc_internals))] use std::fmt; -use std::num::{NonZeroUsize, ParseIntError}; +use std::num::{NonZero, ParseIntError}; use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub}; use std::str::FromStr; @@ -1149,7 +1149,7 @@ pub enum FieldsShape { Primitive, /// All fields start at no offset. The `usize` is the field count. - Union(NonZeroUsize), + Union(NonZero), /// Array/vector-like placement, with all fields of identical types. Array { stride: Size, count: u64 }, diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index fa378e19f71ab..554b6b8f0f7f4 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2164,7 +2164,7 @@ pub enum TyKind { MacCall(P), /// Placeholder for a `va_list`. CVarArgs, - /// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZeroU32`, + /// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero`, /// just as part of the type system. Pat(P, P), /// Sometimes we need a dummy value when no error has occurred. diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs index 92bc2e34561ae..e1c14fe0b380b 100644 --- a/compiler/stable_mir/src/abi.rs +++ b/compiler/stable_mir/src/abi.rs @@ -6,7 +6,7 @@ use crate::ty::{Align, IndexedVal, Ty, VariantIdx}; use crate::Error; use crate::Opaque; use std::fmt::{self, Debug}; -use std::num::NonZeroUsize; +use std::num::NonZero; use std::ops::RangeInclusive; /// A function ABI definition. @@ -133,7 +133,7 @@ pub enum FieldsShape { Primitive, /// All fields start at no offset. The `usize` is the field count. - Union(NonZeroUsize), + Union(NonZero), /// Array/vector-like placement, with all fields of identical types. Array { stride: Size, count: u64 }, diff --git a/library/core/src/iter/adapters/step_by.rs b/library/core/src/iter/adapters/step_by.rs index a5cf069d407c0..abdf2f415fe55 100644 --- a/library/core/src/iter/adapters/step_by.rs +++ b/library/core/src/iter/adapters/step_by.rs @@ -1,7 +1,7 @@ use crate::{ intrinsics, iter::{from_fn, TrustedLen, TrustedRandomAccess}, - num::NonZeroUsize, + num::NonZero, ops::{Range, Try}, }; @@ -42,10 +42,10 @@ impl StepBy { /// The `step` that was originally passed to `Iterator::step_by(step)`, /// aka `self.step_minus_one + 1`. #[inline] - fn original_step(&self) -> NonZeroUsize { + fn original_step(&self) -> NonZero { // SAFETY: By type invariant, `step_minus_one` cannot be `MAX`, which // means the addition cannot overflow and the result cannot be zero. - unsafe { NonZeroUsize::new_unchecked(intrinsics::unchecked_add(self.step_minus_one, 1)) } + unsafe { NonZero::new_unchecked(intrinsics::unchecked_add(self.step_minus_one, 1)) } } } @@ -231,12 +231,12 @@ unsafe impl StepByImpl for StepBy { #[inline] default fn spec_size_hint(&self) -> (usize, Option) { #[inline] - fn first_size(step: NonZeroUsize) -> impl Fn(usize) -> usize { + fn first_size(step: NonZero) -> impl Fn(usize) -> usize { move |n| if n == 0 { 0 } else { 1 + (n - 1) / step } } #[inline] - fn other_size(step: NonZeroUsize) -> impl Fn(usize) -> usize { + fn other_size(step: NonZero) -> impl Fn(usize) -> usize { move |n| n / step } diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index f3972346bb5be..bed76263b4516 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -236,7 +236,7 @@ fn main() { let num_threads = if let Some(num) = env::var_os("BUILD_MANIFEST_NUM_THREADS") { num.to_str().unwrap().parse().expect("invalid number for BUILD_MANIFEST_NUM_THREADS") } else { - std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) + std::thread::available_parallelism().map_or(1, std::num::NonZero::get) }; rayon::ThreadPoolBuilder::new() .num_threads(num_threads) diff --git a/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs index c44f5150dd1a9..1dfc9f7091e8c 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs @@ -87,7 +87,7 @@ pub(super) fn check<'tcx>( && is_normalizable(cx, cx.param_env, from_ty) && is_normalizable(cx, cx.param_env, to_ty) // we only want to lint if the target type has a niche that is larger than the one of the source type - // e.g. `u8` to `NonZeroU8` should lint, but `NonZeroU8` to `u8` should not + // e.g. `u8` to `NonZero` should lint, but `NonZero` to `u8` should not && let Ok(from_layout) = cx.tcx.layout_of(cx.param_env.and(from_ty)) && let Ok(to_layout) = cx.tcx.layout_of(cx.param_env.and(to_ty)) && match (from_layout.largest_niche, to_layout.largest_niche) { diff --git a/src/tools/clippy/lintcheck/src/config.rs b/src/tools/clippy/lintcheck/src/config.rs index e678d40795ee8..3f712f453fa0a 100644 --- a/src/tools/clippy/lintcheck/src/config.rs +++ b/src/tools/clippy/lintcheck/src/config.rs @@ -1,5 +1,5 @@ use clap::Parser; -use std::num::NonZeroUsize; +use std::num::NonZero; use std::path::PathBuf; #[derive(Clone, Debug, Parser)] @@ -61,7 +61,7 @@ impl LintcheckConfig { config.max_jobs = if config.fix || config.recursive { 1 } else { - std::thread::available_parallelism().map_or(1, NonZeroUsize::get) + std::thread::available_parallelism().map_or(1, NonZero::get) }; }; diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs index 66d71f337f2f6..33a91e8bbbe53 100644 --- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs @@ -15,7 +15,7 @@ extern crate proc_macro_derive; -use core::num::{NonZeroUsize, Saturating, Wrapping}; +use core::num::{NonZero, Saturating, Wrapping}; const ONE: i32 = 1; const ZERO: i32 = 0; @@ -494,15 +494,15 @@ pub fn issue_11262() { } pub fn issue_11392() { - fn example_div(unsigned: usize, nonzero_unsigned: NonZeroUsize) -> usize { + fn example_div(unsigned: usize, nonzero_unsigned: NonZero) -> usize { unsigned / nonzero_unsigned } - fn example_rem(unsigned: usize, nonzero_unsigned: NonZeroUsize) -> usize { + fn example_rem(unsigned: usize, nonzero_unsigned: NonZero) -> usize { unsigned % nonzero_unsigned } - let (unsigned, nonzero_unsigned) = (0, NonZeroUsize::new(1).unwrap()); + let (unsigned, nonzero_unsigned) = (0, NonZero::new(1).unwrap()); example_div(unsigned, nonzero_unsigned); example_rem(unsigned, nonzero_unsigned); } diff --git a/src/tools/clippy/tests/ui/eager_transmute.fixed b/src/tools/clippy/tests/ui/eager_transmute.fixed index c29e7dd9ab3ea..ba4342462dca0 100644 --- a/src/tools/clippy/tests/ui/eager_transmute.fixed +++ b/src/tools/clippy/tests/ui/eager_transmute.fixed @@ -2,7 +2,7 @@ #![warn(clippy::eager_transmute)] #![allow(clippy::transmute_int_to_non_zero, clippy::missing_transmute_annotations)] -use std::num::NonZeroU8; +use std::num::NonZero; #[repr(u8)] enum Opcode { @@ -85,21 +85,21 @@ macro_rules! impls { } impls!(NonMaxU8, NonZeroNonMaxU8); -fn niche_tests(v1: u8, v2: NonZeroU8, v3: NonZeroNonMaxU8) { - // u8 -> NonZeroU8, do lint - let _: Option = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) }); +fn niche_tests(v1: u8, v2: NonZero, v3: NonZeroNonMaxU8) { + // u8 -> NonZero, do lint + let _: Option> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) }); - // NonZeroU8 -> u8, don't lint, target type has no niche and therefore a higher validity range - let _: Option = (v2 > NonZeroU8::new(1).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); + // NonZero -> u8, don't lint, target type has no niche and therefore a higher validity range + let _: Option = (v2 > NonZero::new(1u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); - // NonZeroU8 -> NonMaxU8, do lint, different niche - let _: Option = (v2 < NonZeroU8::new(255).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); + // NonZero -> NonMaxU8, do lint, different niche + let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); // NonZeroNonMaxU8 -> NonMaxU8, don't lint, target type has more validity let _: Option = (v3 < 255).then_some(unsafe { std::mem::transmute(v2) }); - // NonZeroU8 -> NonZeroNonMaxU8, do lint, target type has less validity - let _: Option = (v2 < NonZeroU8::new(255).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); + // NonZero -> NonZeroNonMaxU8, do lint, target type has less validity + let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); } fn main() {} diff --git a/src/tools/clippy/tests/ui/eager_transmute.rs b/src/tools/clippy/tests/ui/eager_transmute.rs index 491a9485c9327..9750e87ce5741 100644 --- a/src/tools/clippy/tests/ui/eager_transmute.rs +++ b/src/tools/clippy/tests/ui/eager_transmute.rs @@ -2,7 +2,7 @@ #![warn(clippy::eager_transmute)] #![allow(clippy::transmute_int_to_non_zero, clippy::missing_transmute_annotations)] -use std::num::NonZeroU8; +use std::num::NonZero; #[repr(u8)] enum Opcode { @@ -85,21 +85,21 @@ macro_rules! impls { } impls!(NonMaxU8, NonZeroNonMaxU8); -fn niche_tests(v1: u8, v2: NonZeroU8, v3: NonZeroNonMaxU8) { - // u8 -> NonZeroU8, do lint - let _: Option = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) }); +fn niche_tests(v1: u8, v2: NonZero, v3: NonZeroNonMaxU8) { + // u8 -> NonZero, do lint + let _: Option> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) }); - // NonZeroU8 -> u8, don't lint, target type has no niche and therefore a higher validity range - let _: Option = (v2 > NonZeroU8::new(1).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); + // NonZero -> u8, don't lint, target type has no niche and therefore a higher validity range + let _: Option = (v2 > NonZero::new(1u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); - // NonZeroU8 -> NonMaxU8, do lint, different niche - let _: Option = (v2 < NonZeroU8::new(255).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); + // NonZero -> NonMaxU8, do lint, different niche + let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); // NonZeroNonMaxU8 -> NonMaxU8, don't lint, target type has more validity let _: Option = (v3 < 255).then_some(unsafe { std::mem::transmute(v2) }); - // NonZeroU8 -> NonZeroNonMaxU8, do lint, target type has less validity - let _: Option = (v2 < NonZeroU8::new(255).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); + // NonZero -> NonZeroNonMaxU8, do lint, target type has less validity + let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); } fn main() {} diff --git a/src/tools/clippy/tests/ui/eager_transmute.stderr b/src/tools/clippy/tests/ui/eager_transmute.stderr index b9a4321d99efe..5cf7bd49a929e 100644 --- a/src/tools/clippy/tests/ui/eager_transmute.stderr +++ b/src/tools/clippy/tests/ui/eager_transmute.stderr @@ -155,36 +155,36 @@ LL | (op < 4).then(|| std::mem::transmute::<_, Opcode>(op)); | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:90:60 + --> tests/ui/eager_transmute.rs:90:62 | -LL | let _: Option = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) }); - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _: Option> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) }); + | ^^^^^^^^^^^^^^^^^^^^^^^ | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) }); - | ~~~~ ++ +LL | let _: Option> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) }); + | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:96:86 | -LL | let _: Option = (v2 < NonZeroU8::new(255).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); +LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (v2 < NonZeroU8::new(255).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); +LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:102:93 | -LL | let _: Option = (v2 < NonZeroU8::new(255).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); +LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (v2 < NonZeroU8::new(255).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); +LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); | ~~~~ ++ error: aborting due to 17 previous errors diff --git a/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.rs b/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.rs index 428f371ca51c7..eca6d908b448b 100644 --- a/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.rs +++ b/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.rs @@ -2,7 +2,7 @@ #![feature(custom_mir)] use std::intrinsics::mir::*; -use std::num::NonZeroI32; +use std::num::NonZero; // We define our own option type so that we can control the variant indices. #[allow(unused)] @@ -13,7 +13,7 @@ enum Option { use Option::*; #[custom_mir(dialect = "runtime", phase = "optimized")] -fn set_discriminant(ptr: &mut Option) { +fn set_discriminant(ptr: &mut Option>) { mir! { { // We set the discriminant to `Some`, which is a NOP since this is the niched variant. diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.rs index 2cf4e04477778..c5900489b4c64 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.rs +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.rs @@ -1,7 +1,7 @@ -use std::num::*; +use std::num::NonZero; #[repr(C)] -struct S1(NonZeroI32); +struct S1(NonZero); #[repr(C)] struct S2(i32); @@ -11,6 +11,6 @@ fn callee(_s: S2) {} fn main() { let fnptr: fn(S2) = callee; let fnptr: fn(S1) = unsafe { std::mem::transmute(fnptr) }; - fnptr(S1(NonZeroI32::new(1).unwrap())); + fnptr(S1(NonZero::new(1).unwrap())); //~^ ERROR: calling a function with argument of type S2 passing data of type S1 } diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr index eaacc32bf6880..8ec19db813adf 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: calling a function with argument of type S2 passing data of type S1 --> $DIR/abi_mismatch_repr_C.rs:LL:CC | -LL | fnptr(S1(NonZeroI32::new(1).unwrap())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling a function with argument of type S2 passing data of type S1 +LL | fnptr(S1(NonZero::new(1).unwrap())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling a function with argument of type S2 passing data of type S1 | = 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/validity/cast_fn_ptr_invalid_callee_ret.rs b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.rs index 7cdc15c609495..9fabdd8e86ba4 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.rs +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.rs @@ -2,15 +2,15 @@ #![feature(core_intrinsics, custom_mir)] use std::intrinsics::mir::*; -use std::num::NonZeroU32; +use std::num::NonZero; use std::ptr; -// This function supposedly returns a NonZeroU32, but actually returns something invalid in a way that -// never materializes a bad NonZeroU32 value: we take a pointer to the return place and cast the pointer +// This function supposedly returns a `NonZero`, but actually returns something invalid in a way that +// never materializes a bad `NonZero` value: we take a pointer to the return place and cast the pointer // type. That way we never get an "invalid value constructed" error inside the function, it can // only possibly be detected when the return value is passed to the caller. #[custom_mir(dialect = "runtime", phase = "optimized")] -fn f() -> NonZeroU32 { +fn f() -> NonZero { mir! { { let tmp = ptr::addr_of_mut!(RET); @@ -22,7 +22,7 @@ fn f() -> NonZeroU32 { } fn main() { - let f: fn() -> u32 = unsafe { std::mem::transmute(f as fn() -> NonZeroU32) }; - // There's a NonZeroU32-to-u32 transmute happening here + let f: fn() -> u32 = unsafe { std::mem::transmute(f as fn() -> NonZero) }; + // There's a `NonZero` to `u32` transmute happening here. f(); //~ERROR: expected something greater or equal to 1 } diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs index 3a87bb786776e..7ca26bffc14fd 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs @@ -2,24 +2,24 @@ #![feature(core_intrinsics, custom_mir)] use std::intrinsics::mir::*; -use std::num::NonZeroU32; +use std::num::NonZero; use std::ptr; fn f(c: u32) { println!("{c}"); } -// Call that function in a bad way, with an invalid NonZeroU32, but without -// ever materializing this as a NonZeroU32 value outside the call itself. +// Call that function in a bad way, with an invalid `NonZero`, but without +// ever materializing this as a `NonZero` value outside the call itself. #[custom_mir(dialect = "runtime", phase = "optimized")] -fn call(f: fn(NonZeroU32)) { +fn call(f: fn(NonZero)) { mir! { let _res: (); { let c = 0; let tmp = ptr::addr_of!(c); - let ptr = tmp as *const NonZeroU32; - // The call site now is a NonZeroU32-to-u32 transmute. + let ptr = tmp as *const NonZero; + // The call site now is a `NonZero` to `u32` transmute. Call(_res = f(*ptr), ReturnTo(retblock), UnwindContinue()) //~ERROR: expected something greater or equal to 1 } retblock = { @@ -29,6 +29,6 @@ fn call(f: fn(NonZeroU32)) { } fn main() { - let f: fn(NonZeroU32) = unsafe { std::mem::transmute(f as fn(u32)) }; + let f: fn(NonZero) = unsafe { std::mem::transmute(f as fn(u32)) }; call(f); } diff --git a/src/tools/miri/tests/pass/function_calls/abi_compat.rs b/src/tools/miri/tests/pass/function_calls/abi_compat.rs index 14fd2d333d4fb..136660a305aff 100644 --- a/src/tools/miri/tests/pass/function_calls/abi_compat.rs +++ b/src/tools/miri/tests/pass/function_calls/abi_compat.rs @@ -70,7 +70,7 @@ fn main() { test_abi_compat(0usize, 0u64); test_abi_compat(0isize, 0i64); } - test_abi_compat(42u32, num::NonZeroU32::new(1).unwrap()); + test_abi_compat(42u32, num::NonZero::new(1u32).unwrap()); // - `char` and `u32`. test_abi_compat(42u32, 'x'); // - Reference/pointer types with the same pointee. @@ -86,9 +86,9 @@ fn main() { // - Guaranteed null-pointer-optimizations (RFC 3391). test_abi_compat(&0u32 as *const u32, Some(&0u32)); test_abi_compat(main as fn(), Some(main as fn())); - test_abi_compat(0u32, Some(num::NonZeroU32::new(1).unwrap())); + test_abi_compat(0u32, Some(num::NonZero::new(1u32).unwrap())); test_abi_compat(&0u32 as *const u32, Some(Wrapper(&0u32))); - test_abi_compat(0u32, Some(Wrapper(num::NonZeroU32::new(1).unwrap()))); + test_abi_compat(0u32, Some(Wrapper(num::NonZero::new(1u32).unwrap()))); // These must work for *any* type, since we guarantee that `repr(transparent)` is ABI-compatible // with the wrapped field. @@ -102,7 +102,7 @@ fn main() { test_abi_newtype::<[u32; 2]>(); test_abi_newtype::<[u32; 32]>(); test_abi_newtype::>(); - test_abi_newtype::>(); + test_abi_newtype::>>(); // Extra test for assumptions made by arbitrary-self-dyn-receivers. // This is interesting since these types are not `repr(transparent)`. So this is not part of our diff --git a/src/tools/miri/tests/pass/shims/available-parallelism-miri-num-cpus.rs b/src/tools/miri/tests/pass/shims/available-parallelism-miri-num-cpus.rs index 137fa51024975..0d96bc2f5e737 100644 --- a/src/tools/miri/tests/pass/shims/available-parallelism-miri-num-cpus.rs +++ b/src/tools/miri/tests/pass/shims/available-parallelism-miri-num-cpus.rs @@ -1,8 +1,8 @@ //@compile-flags: -Zmiri-num-cpus=1024 -use std::num::NonZeroUsize; +use std::num::NonZero; use std::thread::available_parallelism; fn main() { - assert_eq!(available_parallelism().unwrap(), NonZeroUsize::new(1024).unwrap()); + assert_eq!(available_parallelism().unwrap(), NonZero::new(1024).unwrap()); } diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index efeefbe29fbce..c9d53927b902a 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -1,5 +1,5 @@ use std::ffi::OsString; -use std::num::NonZeroUsize; +use std::num::NonZero; use std::path::{Path, PathBuf}; use std::sync::OnceLock; use std::{env, process::Command}; @@ -76,7 +76,7 @@ fn miri_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) -> edition: Some("2021".into()), // keep in sync with `./miri run` threads: std::env::var("MIRI_TEST_THREADS") .ok() - .map(|threads| NonZeroUsize::new(threads.parse().unwrap()).unwrap()), + .map(|threads| NonZero::new(threads.parse().unwrap()).unwrap()), ..Config::rustc(path) }; diff --git a/tests/ui-fulldeps/stable-mir/check_abi.rs b/tests/ui-fulldeps/stable-mir/check_abi.rs index 74801e007c4dd..359dd4146baf5 100644 --- a/tests/ui-fulldeps/stable-mir/check_abi.rs +++ b/tests/ui-fulldeps/stable-mir/check_abi.rs @@ -99,7 +99,7 @@ fn check_result(abi: &ArgAbi) { assert_matches!(layout.variants, VariantsShape::Multiple { .. }) } -/// Check the niche information about: `NonZeroU8` +/// Checks the niche information about `NonZero`. fn check_niche(abi: &ArgAbi) { assert!(abi.ty.kind().is_struct()); assert_matches!(abi.mode, PassMode::Direct { .. }); @@ -150,12 +150,12 @@ fn generate_input(path: &str) -> std::io::Result<()> { #![feature(c_variadic)] #![allow(unused_variables)] - use std::num::NonZeroU8; + use std::num::NonZero; pub fn fn_abi( ignore: [u8; 0], primitive: char, - niche: NonZeroU8, + niche: NonZero, ) -> Result {{ // We only care about the signature. todo!() diff --git a/tests/ui/type/pattern_types/range_patterns_usage.rs b/tests/ui/type/pattern_types/range_patterns_usage.rs index 7fe50423c511b..2a9f736ae61d5 100644 --- a/tests/ui/type/pattern_types/range_patterns_usage.rs +++ b/tests/ui/type/pattern_types/range_patterns_usage.rs @@ -8,7 +8,7 @@ use std::pat::pattern_type; -type X = std::num::NonZeroU32; +type X = std::num::NonZero; type Y = pattern_type!(u32 is 1..); type Z = Option; struct NonZeroU32New(pattern_type!(u32 is 1..)); From cacc0829ffa012e1e6a84ad35160533431a2d269 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Wed, 8 May 2024 18:22:14 +0530 Subject: [PATCH 15/15] Handle normalization failure in `struct_tail_erasing_lifetimes` Fixes an ICE that occurred when the struct in question has an error --- compiler/rustc_middle/src/ty/layout.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index f17413af77700..8873025e440aa 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -338,13 +338,14 @@ impl<'tcx> SizeSkeleton<'tcx> { pointee, |ty| match tcx.try_normalize_erasing_regions(param_env, ty) { Ok(ty) => ty, - Err(_e) => { - if let Some(guar) = tcx.dcx().has_errors() { - Ty::new_error(tcx, guar) - } else { - bug!("normalization failed, but no errors reported"); - } - } + Err(e) => Ty::new_error_with_message( + tcx, + DUMMY_SP, + format!( + "normalization failed for {} but no errors reported", + e.get_type_for_failure() + ), + ), }, || {}, );