@@ -2140,46 +2140,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21402140 expr_ty : Ty < ' tcx > ,
21412141 ) -> bool {
21422142 let tcx = self . tcx ;
2143- let ( adt, unwrap) = match expected. kind ( ) {
2143+ let ( adt, substs , unwrap) = match expected. kind ( ) {
21442144 // In case Option<NonZero*> is wanted, but * is provided, suggest calling new
2145- ty:: Adt ( adt, args ) if tcx. is_diagnostic_item ( sym:: Option , adt. did ( ) ) => {
2146- // Unwrap option
2147- let ty:: Adt ( adt, _ ) = args . type_at ( 0 ) . kind ( ) else {
2145+ ty:: Adt ( adt, substs ) if tcx. is_diagnostic_item ( sym:: Option , adt. did ( ) ) => {
2146+ let nonzero_type = substs . type_at ( 0 ) ; // Unwrap option type.
2147+ let ty:: Adt ( adt, substs ) = nonzero_type . kind ( ) else {
21482148 return false ;
21492149 } ;
2150-
2151- ( adt, "" )
2150+ ( adt, substs, "" )
21522151 }
2153- // In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types
2154- ty:: Adt ( adt, _ ) => ( adt, ".unwrap()" ) ,
2152+ // In case ` NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types.
2153+ ty:: Adt ( adt, substs ) => ( adt, substs , ".unwrap()" ) ,
21552154 _ => return false ,
21562155 } ;
21572156
2158- let map = [
2159- ( sym:: NonZeroU8 , tcx. types . u8 ) ,
2160- ( sym:: NonZeroU16 , tcx. types . u16 ) ,
2161- ( sym:: NonZeroU32 , tcx. types . u32 ) ,
2162- ( sym:: NonZeroU64 , tcx. types . u64 ) ,
2163- ( sym:: NonZeroU128 , tcx. types . u128 ) ,
2164- ( sym:: NonZeroI8 , tcx. types . i8 ) ,
2165- ( sym:: NonZeroI16 , tcx. types . i16 ) ,
2166- ( sym:: NonZeroI32 , tcx. types . i32 ) ,
2167- ( sym:: NonZeroI64 , tcx. types . i64 ) ,
2168- ( sym:: NonZeroI128 , tcx. types . i128 ) ,
2157+ if !self . tcx . is_diagnostic_item ( sym:: NonZero , adt. did ( ) ) {
2158+ return false ;
2159+ }
2160+
2161+ // FIXME: This can be simplified once `NonZero<T>` is stable.
2162+ let coercable_types = [
2163+ ( "NonZeroU8" , tcx. types . u8 ) ,
2164+ ( "NonZeroU16" , tcx. types . u16 ) ,
2165+ ( "NonZeroU32" , tcx. types . u32 ) ,
2166+ ( "NonZeroU64" , tcx. types . u64 ) ,
2167+ ( "NonZeroU128" , tcx. types . u128 ) ,
2168+ ( "NonZeroI8" , tcx. types . i8 ) ,
2169+ ( "NonZeroI16" , tcx. types . i16 ) ,
2170+ ( "NonZeroI32" , tcx. types . i32 ) ,
2171+ ( "NonZeroI64" , tcx. types . i64 ) ,
2172+ ( "NonZeroI128" , tcx. types . i128 ) ,
21692173 ] ;
21702174
2171- let Some ( ( s, _) ) = map. iter ( ) . find ( |& & ( s, t) | {
2172- self . tcx . is_diagnostic_item ( s, adt. did ( ) ) && self . can_coerce ( expr_ty, t)
2175+ let int_type = substs. type_at ( 0 ) ;
2176+
2177+ let Some ( nonzero_alias) = coercable_types. iter ( ) . find_map ( |( nonzero_alias, t) | {
2178+ if * t == int_type && self . can_coerce ( expr_ty, * t) { Some ( nonzero_alias) } else { None }
21732179 } ) else {
21742180 return false ;
21752181 } ;
21762182
2177- let path = self . tcx . def_path_str ( adt. non_enum_variant ( ) . def_id ) ;
2178-
21792183 err. multipart_suggestion (
2180- format ! ( "consider calling `{s }::new`" ) ,
2184+ format ! ( "consider calling `{nonzero_alias }::new`" ) ,
21812185 vec ! [
2182- ( expr. span. shrink_to_lo( ) , format!( "{path }::new(" ) ) ,
2186+ ( expr. span. shrink_to_lo( ) , format!( "{nonzero_alias }::new(" ) ) ,
21832187 ( expr. span. shrink_to_hi( ) , format!( "){unwrap}" ) ) ,
21842188 ] ,
21852189 Applicability :: MaybeIncorrect ,
0 commit comments