@@ -2138,46 +2138,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21382138 expr_ty : Ty < ' tcx > ,
21392139 ) -> bool {
21402140 let tcx = self . tcx ;
2141- let ( adt, unwrap) = match expected. kind ( ) {
2141+ let ( adt, substs , unwrap) = match expected. kind ( ) {
21422142 // In case Option<NonZero*> is wanted, but * is provided, suggest calling new
2143- ty:: Adt ( adt, args ) if tcx. is_diagnostic_item ( sym:: Option , adt. did ( ) ) => {
2144- // Unwrap option
2145- let ty:: Adt ( adt, _ ) = args . type_at ( 0 ) . kind ( ) else {
2143+ ty:: Adt ( adt, substs ) if tcx. is_diagnostic_item ( sym:: Option , adt. did ( ) ) => {
2144+ let nonzero_type = substs . type_at ( 0 ) ; // Unwrap option type.
2145+ let ty:: Adt ( adt, substs ) = nonzero_type . kind ( ) else {
21462146 return false ;
21472147 } ;
2148-
2149- ( adt, "" )
2148+ ( adt, substs, "" )
21502149 }
2151- // In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types
2152- ty:: Adt ( adt, _ ) => ( adt, ".unwrap()" ) ,
2150+ // In case ` NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types.
2151+ ty:: Adt ( adt, substs ) => ( adt, substs , ".unwrap()" ) ,
21532152 _ => return false ,
21542153 } ;
21552154
2156- let map = [
2157- ( sym:: NonZeroU8 , tcx. types . u8 ) ,
2158- ( sym:: NonZeroU16 , tcx. types . u16 ) ,
2159- ( sym:: NonZeroU32 , tcx. types . u32 ) ,
2160- ( sym:: NonZeroU64 , tcx. types . u64 ) ,
2161- ( sym:: NonZeroU128 , tcx. types . u128 ) ,
2162- ( sym:: NonZeroI8 , tcx. types . i8 ) ,
2163- ( sym:: NonZeroI16 , tcx. types . i16 ) ,
2164- ( sym:: NonZeroI32 , tcx. types . i32 ) ,
2165- ( sym:: NonZeroI64 , tcx. types . i64 ) ,
2166- ( sym:: NonZeroI128 , tcx. types . i128 ) ,
2155+ if !self . tcx . is_diagnostic_item ( sym:: NonZero , adt. did ( ) ) {
2156+ return false ;
2157+ }
2158+
2159+ let coercable_types = [
2160+ ( "NonZeroU8" , tcx. types . u8 ) ,
2161+ ( "NonZeroU16" , tcx. types . u16 ) ,
2162+ ( "NonZeroU32" , tcx. types . u32 ) ,
2163+ ( "NonZeroU64" , tcx. types . u64 ) ,
2164+ ( "NonZeroU128" , tcx. types . u128 ) ,
2165+ ( "NonZeroI8" , tcx. types . i8 ) ,
2166+ ( "NonZeroI16" , tcx. types . i16 ) ,
2167+ ( "NonZeroI32" , tcx. types . i32 ) ,
2168+ ( "NonZeroI64" , tcx. types . i64 ) ,
2169+ ( "NonZeroI128" , tcx. types . i128 ) ,
21672170 ] ;
21682171
2169- let Some ( ( s, _) ) = map. iter ( ) . find ( |& & ( s, t) | {
2170- self . tcx . is_diagnostic_item ( s, adt. did ( ) ) && self . can_coerce ( expr_ty, t)
2172+ let int_type = substs. type_at ( 0 ) ;
2173+
2174+ let Some ( nonzero_alias) = coercable_types. iter ( ) . find_map ( |( nonzero_alias, t) | {
2175+ if * t == int_type && self . can_coerce ( expr_ty, * t) { Some ( nonzero_alias) } else { None }
21712176 } ) else {
21722177 return false ;
21732178 } ;
21742179
2175- let path = self . tcx . def_path_str ( adt. non_enum_variant ( ) . def_id ) ;
2176-
21772180 err. multipart_suggestion (
2178- format ! ( "consider calling `{s }::new`" ) ,
2181+ format ! ( "consider calling `{nonzero_alias }::new`" ) ,
21792182 vec ! [
2180- ( expr. span. shrink_to_lo( ) , format!( "{path }::new(" ) ) ,
2183+ ( expr. span. shrink_to_lo( ) , format!( "{nonzero_alias }::new(" ) ) ,
21812184 ( expr. span. shrink_to_hi( ) , format!( "){unwrap}" ) ) ,
21822185 ] ,
21832186 Applicability :: MaybeIncorrect ,
0 commit comments