diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 9f7f4c7583412..a9e4494d848e6 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -428,6 +428,8 @@ language_item_table! { String, sym::String, string, Target::Struct, GenericRequirement::None; CStr, sym::CStr, c_str, Target::Struct, GenericRequirement::None; + NonZero, sym::NonZero, non_zero, Target::Struct, GenericRequirement::Exact(1); + // Experimental lang items for implementing contract pre- and post-condition checking. ContractBuildCheckEnsures, sym::contract_build_check_ensures, contract_build_check_ensures_fn, Target::Fn, GenericRequirement::None; ContractCheckRequires, sym::contract_check_requires, contract_check_requires_fn, Target::Fn, GenericRequirement::None; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 127f2c676391d..fd881b82e2a0c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -735,6 +735,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => unreachable!(), } } + ty::Adt(adt, ..) if tcx.is_lang_item(adt.did(), LangItem::NonZero) => { + if i.get() == 0 { + // FIXME: report a nice error + None + } else { + Some(ty) + } + } _ => None, }); opt_ty.unwrap_or_else(|| self.next_int_var()) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 1d16c3af7fb75..377a2446ab1d3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2581,7 +2581,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => return false, }; - if !self.tcx.is_diagnostic_item(sym::NonZero, adt.did()) { + if !self.tcx.is_lang_item(adt.did(), LangItem::NonZero) { return false; } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index c55f2b9dd6f24..044bd51c267af 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -11,7 +11,7 @@ use rustc_errors::{ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::VisitorExt; -use rustc_macros::{LintDiagnostic, Subdiagnostic}; +use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::inhabitedness::InhabitedPredicate; use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_session::Session; @@ -1704,6 +1704,19 @@ pub(crate) struct OverflowingInt<'a> { #[subdiagnostic] pub help: Option>, } +#[derive(Diagnostic)] +#[diag(lint_overflowing_int)] +#[note] +pub(crate) struct OverflowingIntError<'a> { + #[primary_span] + pub span: Span, + pub ty: &'a str, + pub lit: String, + pub min: i128, + pub max: u128, + #[subdiagnostic] + pub help: Option>, +} #[derive(Subdiagnostic)] #[help(lint_help)] @@ -1729,6 +1742,18 @@ pub(crate) struct OverflowingUInt<'a> { pub max: u128, } +#[derive(Diagnostic)] +#[diag(lint_overflowing_uint)] +#[note] +pub(crate) struct OverflowingUIntError<'a> { + #[primary_span] + pub span: Span, + pub ty: &'a str, + pub lit: String, + pub min: u128, + pub max: u128, +} + #[derive(LintDiagnostic)] #[diag(lint_overflowing_literal)] #[note] diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs index d49f599407c25..2dfb697f3e66d 100644 --- a/compiler/rustc_lint/src/types/literal.rs +++ b/compiler/rustc_lint/src/types/literal.rs @@ -11,8 +11,9 @@ use crate::LateContext; use crate::context::LintContext; use crate::lints::{ OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign, OverflowingBinHexSignBitSub, - OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral, OverflowingUInt, - RangeEndpointOutOfRange, SurrogateCharCast, TooLargeCharCast, UseInclusiveRange, + OverflowingBinHexSub, OverflowingInt, OverflowingIntError, OverflowingIntHelp, + OverflowingLiteral, OverflowingUInt, OverflowingUIntError, RangeEndpointOutOfRange, + SurrogateCharCast, TooLargeCharCast, UseInclusiveRange, }; use crate::types::{OVERFLOWING_LITERALS, TypeLimits}; @@ -258,6 +259,7 @@ fn lint_int_literal<'tcx>( lit: &hir::Lit, t: ty::IntTy, v: u128, + force_error: bool, ) { let int_type = t.normalize(cx.sess().target.pointer_width); let (min, max) = int_ty_range(int_type); @@ -295,11 +297,22 @@ fn lint_int_literal<'tcx>( let help = get_type_suggestion(cx.typeck_results().node_type(hir_id), v, negative) .map(|suggestion_ty| OverflowingIntHelp { suggestion_ty }); - cx.emit_span_lint( - OVERFLOWING_LITERALS, - span, - OverflowingInt { ty: t.name_str(), lit, min, max, help }, - ); + if force_error { + cx.tcx.dcx().emit_err(OverflowingIntError { + span, + ty: t.name_str(), + lit, + min, + max, + help, + }); + } else { + cx.emit_span_lint( + OVERFLOWING_LITERALS, + span, + OverflowingInt { ty: t.name_str(), lit, min, max, help }, + ); + } } } @@ -309,6 +322,7 @@ fn lint_uint_literal<'tcx>( span: Span, lit: &hir::Lit, t: ty::UintTy, + force_error: bool, ) { let uint_type = t.normalize(cx.sess().target.pointer_width); let (min, max) = uint_ty_range(uint_type); @@ -366,10 +380,9 @@ fn lint_uint_literal<'tcx>( ); return; } - cx.emit_span_lint( - OVERFLOWING_LITERALS, - span, - OverflowingUInt { + if force_error { + cx.tcx.dcx().emit_err(OverflowingUIntError { + span, ty: t.name_str(), lit: cx .sess() @@ -378,8 +391,23 @@ fn lint_uint_literal<'tcx>( .unwrap_or_else(|_| lit_val.to_string()), min, max, - }, - ); + }); + } else { + cx.emit_span_lint( + OVERFLOWING_LITERALS, + span, + OverflowingUInt { + ty: t.name_str(), + lit: cx + .sess() + .source_map() + .span_to_snippet(lit.span) + .unwrap_or_else(|_| lit_val.to_string()), + min, + max, + }, + ); + } } } @@ -391,18 +419,39 @@ pub(crate) fn lint_literal<'tcx>( lit: &hir::Lit, negated: bool, ) { - match *cx.typeck_results().node_type(hir_id).kind() { + lint_literal_inner( + cx, + type_limits, + hir_id, + cx.typeck_results().node_type(hir_id), + span, + lit, + negated, + false, + ) +} +pub(crate) fn lint_literal_inner<'tcx>( + cx: &LateContext<'tcx>, + type_limits: &TypeLimits, + hir_id: HirId, + ty: Ty<'tcx>, + span: Span, + lit: &hir::Lit, + negated: bool, + force_error: bool, +) { + match *ty.kind() { ty::Int(t) => { match lit.node { ast::LitKind::Int(v, ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed) => { - lint_int_literal(cx, type_limits, hir_id, span, lit, t, v.get()) + lint_int_literal(cx, type_limits, hir_id, span, lit, t, v.get(), force_error) } _ => bug!(), }; } ty::Uint(t) => { assert!(!negated); - lint_uint_literal(cx, hir_id, span, lit, t) + lint_uint_literal(cx, hir_id, span, lit, t, force_error) } ty::Float(t) => { let (is_infinite, sym) = match lit.node { @@ -431,6 +480,12 @@ pub(crate) fn lint_literal<'tcx>( ); } } + ty::Pat(base, ..) if base.is_integral() => { + lint_literal_inner(cx, type_limits, hir_id, base, span, lit, negated, true) + } + ty::Adt(adt, args) if cx.tcx.is_lang_item(adt.did(), hir::LangItem::NonZero) => { + lint_literal_inner(cx, type_limits, hir_id, args.type_at(0), span, lit, negated, true) + } _ => {} } } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index 0e0c7a7fa4f0b..09c62f3253cc7 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -107,6 +107,7 @@ fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx> let lit_ty = match *ty.kind() { ty::Pat(base, _) => base, + ty::Adt(adt, args) if tcx.is_lang_item(adt.did(), LangItem::NonZero) => args.type_at(0), _ => ty, }; diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index efb0665b7f461..f2aa9bc82fa59 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -123,7 +123,7 @@ impl_zeroable_primitive!( #[stable(feature = "generic_nonzero", since = "1.79.0")] #[repr(transparent)] #[rustc_nonnull_optimization_guaranteed] -#[rustc_diagnostic_item = "NonZero"] +#[lang = "NonZero"] pub struct NonZero(T::NonZeroInner); macro_rules! impl_nonzero_fmt { diff --git a/src/tools/clippy/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs b/src/tools/clippy/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs index c6f54159c7a78..cfa7e5b724139 100644 --- a/src/tools/clippy/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs +++ b/src/tools/clippy/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs @@ -7,6 +7,7 @@ use rustc_errors::Applicability; use rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, Node, QPath, UnsafeSource}; use rustc_lint::LateContext; use rustc_span::sym; +use rustc_hir::LangItem; use super::USELESS_NONZERO_NEW_UNCHECKED; @@ -15,7 +16,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, func: &Expr<' && segment.ident.name == sym::new_unchecked && let [init_arg] = args && is_inside_always_const_context(cx.tcx, expr.hir_id) - && cx.typeck_results().node_type(ty.hir_id).is_diag_item(cx, sym::NonZero) + && cx.typeck_results().node_type(ty.hir_id).is_lang_item(cx, LangItem::NonZero) && msrv.meets(cx, msrvs::CONST_UNWRAP) { let mut app = Applicability::MachineApplicable; diff --git a/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs b/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs index 1b8ab1bdedf8a..6864d4b880567 100644 --- a/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs +++ b/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs @@ -3,7 +3,7 @@ use clippy_utils::source::snippet; use clippy_utils::sym; use rustc_ast::ast::BinOpKind; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind}; +use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, Ty}; use rustc_session::declare_lint_pass; @@ -81,7 +81,7 @@ fn check_non_zero_conversion(cx: &LateContext<'_>, expr: &Expr<'_>, applicabilit // Check if the receiver type is a NonZero type if let ty::Adt(adt_def, _) = receiver_ty.kind() && adt_def.is_struct() - && cx.tcx.get_diagnostic_name(adt_def.did()) == Some(sym::NonZero) + && cx.tcx.is_lang_item(adt_def.did(), LangItem::NonZero) && let Some(target_non_zero_type) = get_target_non_zero_type(target_ty) { let arg_snippet = get_arg_snippet(cx, arg, rcv_path); diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs index 0a6499e095832..5074089984887 100644 --- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -5,6 +5,7 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::res::MaybeDef; use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary, sym}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_hir::LangItem; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; @@ -90,7 +91,7 @@ impl ArithmeticSideEffects { fn is_non_zero_u(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { if let ty::Adt(adt, substs) = ty.kind() - && cx.tcx.is_diagnostic_item(sym::NonZero, adt.did()) + && cx.tcx.is_lang_item(adt.did(),LangItem::NonZero) && let int_type = substs.type_at(0) && matches!(int_type.kind(), ty::Uint(_)) { diff --git a/src/tools/clippy/clippy_lints/src/operators/integer_division.rs b/src/tools/clippy/clippy_lints/src/operators/integer_division.rs index 1620312474e99..1b8647f06c49c 100644 --- a/src/tools/clippy/clippy_lints/src/operators/integer_division.rs +++ b/src/tools/clippy/clippy_lints/src/operators/integer_division.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::MaybeDef; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::symbol::sym; +use rustc_hir::LangItem; use super::INTEGER_DIVISION; @@ -16,7 +16,7 @@ pub(crate) fn check<'tcx>( if op == hir::BinOpKind::Div && cx.typeck_results().expr_ty(left).is_integral() && let right_ty = cx.typeck_results().expr_ty(right) - && (right_ty.is_integral() || right_ty.is_diag_item(cx, sym::NonZero)) + && (right_ty.is_integral() || right_ty.is_lang_item(cx, LangItem::NonZero)) { #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] span_lint_and_then(cx, INTEGER_DIVISION, expr.span, "integer division", |diag| { 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 2257aa1b73c87..70e6b37da707c 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 @@ -2,10 +2,11 @@ use super::TRANSMUTE_INT_TO_NON_ZERO; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; -use rustc_hir::Expr; +use rustc_hir::{Expr}; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::sym; +use rustc_hir::LangItem; /// Checks for `transmute_int_to_non_zero` lint. /// Returns `true` if it's triggered, otherwise returns `false`. @@ -18,7 +19,7 @@ pub(super) fn check<'tcx>( ) -> bool { if let ty::Int(_) | ty::Uint(_) = from_ty.kind() && let ty::Adt(adt, substs) = to_ty.kind() - && cx.tcx.is_diagnostic_item(sym::NonZero, adt.did()) + && cx.tcx.is_lang_item( adt.did(), LangItem::NonZero) && let int_ty = substs.type_at(0) && from_ty == int_ty { diff --git a/tests/ui/mismatched_types/non_zero_assigned_lit.rs b/tests/ui/mismatched_types/non_zero_assigned_lit.rs new file mode 100644 index 0000000000000..f55c724ee7c93 --- /dev/null +++ b/tests/ui/mismatched_types/non_zero_assigned_lit.rs @@ -0,0 +1,8 @@ +//@ check-pass + +#![allow(overflowing_literals)] + +fn main() { + let x: std::num::NonZero = -128; + assert_eq!(x.get(), -128_i8); +} diff --git a/tests/ui/mismatched_types/non_zero_assigned_oflo_lit.rs b/tests/ui/mismatched_types/non_zero_assigned_oflo_lit.rs new file mode 100644 index 0000000000000..d9445396a5b88 --- /dev/null +++ b/tests/ui/mismatched_types/non_zero_assigned_oflo_lit.rs @@ -0,0 +1,15 @@ +//! Ensure overflowing literals are not allowed for +//! layout constrained types like `NonZero`, as that makes +//! it harder to perform the layout checks. Instead +//! we hard error if such literals are out of range. + +#![allow(overflowing_literals)] + +fn main() { + let _: std::num::NonZero = 256; + //~^ ERROR literal out of range + + let _: std::num::NonZero = -128; + let _: std::num::NonZero = -129; + //~^ ERROR literal out of range +} diff --git a/tests/ui/mismatched_types/non_zero_assigned_oflo_lit.stderr b/tests/ui/mismatched_types/non_zero_assigned_oflo_lit.stderr new file mode 100644 index 0000000000000..95b8fafb8dc22 --- /dev/null +++ b/tests/ui/mismatched_types/non_zero_assigned_oflo_lit.stderr @@ -0,0 +1,18 @@ +error: literal out of range for `u8` + --> $DIR/non_zero_assigned_oflo_lit.rs:9:36 + | +LL | let _: std::num::NonZero = 256; + | ^^^ + | + = note: the literal `256` does not fit into the type `u8` whose range is `0..=255` + +error: literal out of range for `i8` + --> $DIR/non_zero_assigned_oflo_lit.rs:13:36 + | +LL | let _: std::num::NonZero = -129; + | ^^^^ + | + = note: the literal `-129` does not fit into the type `i8` whose range is `-128..=127` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/mismatched_types/non_zero_assigned_something.rs b/tests/ui/mismatched_types/non_zero_assigned_something.rs index e94d5249d6a84..8c34e513ebb5c 100644 --- a/tests/ui/mismatched_types/non_zero_assigned_something.rs +++ b/tests/ui/mismatched_types/non_zero_assigned_something.rs @@ -1,7 +1,40 @@ fn main() { + let _: std::num::NonZero = 0; + //~^ ERROR mismatched types + //~| HELP consider calling `NonZero::new` + + let _: Option> = 0; + //~^ ERROR mismatched types + //~| HELP consider calling `NonZero::new` + + let _: std::num::NonZero = 0; + //~^ ERROR mismatched types + //~| HELP consider calling `NonZero::new` + + let _: Option> = 0; + //~^ ERROR mismatched types + //~| HELP consider calling `NonZero::new` + let _: std::num::NonZero = 1; + let _: std::num::NonZero = 1u8; + //~^ ERROR mismatched types + let _: std::num::NonZero = 1u64; + //~^ ERROR mismatched types + //~| HELP consider calling `NonZero::new` + + let _: std::num::NonZero = 255; + let _: std::num::NonZero = 256; // errors only if no other errors occurred + + let _: std::num::NonZero = -10; + //~^ ERROR cannot apply unary operator `-` to type `NonZero` + + let _: std::num::NonZero = -128; + let _: std::num::NonZero = -129; // errors only if no other errors occurred + let _: std::num::NonZero = -1; + let _: std::num::NonZero = 0; //~^ ERROR mismatched types //~| HELP consider calling `NonZero::new` + let _: std::num::NonZero = 1; let _: Option> = 1; //~^ ERROR mismatched types diff --git a/tests/ui/mismatched_types/non_zero_assigned_something.stderr b/tests/ui/mismatched_types/non_zero_assigned_something.stderr index aa015bd2efcc9..30a401568bf39 100644 --- a/tests/ui/mismatched_types/non_zero_assigned_something.stderr +++ b/tests/ui/mismatched_types/non_zero_assigned_something.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/non_zero_assigned_something.rs:2:37 | -LL | let _: std::num::NonZero = 1; +LL | let _: std::num::NonZero = 0; | ---------------------- ^ expected `NonZero`, found integer | | | expected due to this @@ -10,12 +10,109 @@ LL | let _: std::num::NonZero = 1; found type `{integer}` help: consider calling `NonZero::new` | -LL | let _: std::num::NonZero = NonZero::new(1).unwrap(); +LL | let _: std::num::NonZero = NonZero::new(0).unwrap(); | +++++++++++++ ++++++++++ error[E0308]: mismatched types --> $DIR/non_zero_assigned_something.rs:6:45 | +LL | let _: Option> = 0; + | ------------------------------ ^ expected `Option>`, found integer + | | + | expected due to this + | + = note: expected enum `Option>` + found type `{integer}` +help: consider calling `NonZero::new` + | +LL | let _: Option> = NonZero::new(0); + | +++++++++++++ + + +error[E0308]: mismatched types + --> $DIR/non_zero_assigned_something.rs:10:37 + | +LL | let _: std::num::NonZero = 0; + | ---------------------- ^ expected `NonZero`, found integer + | | + | expected due to this + | + = note: expected struct `NonZero` + found type `{integer}` +help: consider calling `NonZero::new` + | +LL | let _: std::num::NonZero = NonZero::new(0).unwrap(); + | +++++++++++++ ++++++++++ + +error[E0308]: mismatched types + --> $DIR/non_zero_assigned_something.rs:14:45 + | +LL | let _: Option> = 0; + | ------------------------------ ^ expected `Option>`, found integer + | | + | expected due to this + | + = note: expected enum `Option>` + found type `{integer}` +help: consider calling `NonZero::new` + | +LL | let _: Option> = NonZero::new(0); + | +++++++++++++ + + +error[E0308]: mismatched types + --> $DIR/non_zero_assigned_something.rs:19:37 + | +LL | let _: std::num::NonZero = 1u8; + | ---------------------- ^^^ expected `NonZero`, found `u8` + | | + | expected due to this + | + = note: expected struct `NonZero` + found type `u8` + +error[E0308]: mismatched types + --> $DIR/non_zero_assigned_something.rs:21:37 + | +LL | let _: std::num::NonZero = 1u64; + | ---------------------- ^^^^ expected `NonZero`, found `u64` + | | + | expected due to this + | + = note: expected struct `NonZero` + found type `u64` +help: consider calling `NonZero::new` + | +LL | let _: std::num::NonZero = NonZero::new(1u64).unwrap(); + | +++++++++++++ ++++++++++ + +error[E0600]: cannot apply unary operator `-` to type `NonZero` + --> $DIR/non_zero_assigned_something.rs:28:36 + | +LL | let _: std::num::NonZero = -10; + | ^^^ cannot apply unary operator `-` + | +note: `NonZero` does not implement `Neg` + --> $SRC_DIR/core/src/num/nonzero.rs:LL:COL + | + = note: `NonZero` is defined in another crate + +error[E0308]: mismatched types + --> $DIR/non_zero_assigned_something.rs:34:36 + | +LL | let _: std::num::NonZero = 0; + | --------------------- ^ expected `NonZero`, found integer + | | + | expected due to this + | + = note: expected struct `NonZero` + found type `{integer}` +help: consider calling `NonZero::new` + | +LL | let _: std::num::NonZero = NonZero::new(0).unwrap(); + | +++++++++++++ ++++++++++ + +error[E0308]: mismatched types + --> $DIR/non_zero_assigned_something.rs:39:45 + | LL | let _: Option> = 1; | ------------------------------ ^ expected `Option>`, found integer | | @@ -28,6 +125,7 @@ help: consider calling `NonZero::new` LL | let _: Option> = NonZero::new(1); | +++++++++++++ + -error: aborting due to 2 previous errors +error: aborting due to 9 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0600. +For more information about an error, try `rustc --explain E0308`.