@@ -2138,46 +2138,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2138
2138
expr_ty : Ty < ' tcx > ,
2139
2139
) -> bool {
2140
2140
let tcx = self . tcx ;
2141
- let ( adt, unwrap) = match expected. kind ( ) {
2141
+ let ( adt, substs , unwrap) = match expected. kind ( ) {
2142
2142
// 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 {
2146
2146
return false ;
2147
2147
} ;
2148
-
2149
- ( adt, "" )
2148
+ ( adt, substs, "" )
2150
2149
}
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()" ) ,
2153
2152
_ => return false ,
2154
2153
} ;
2155
2154
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 ) ,
2167
2170
] ;
2168
2171
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 }
2171
2176
} ) else {
2172
2177
return false ;
2173
2178
} ;
2174
2179
2175
- let path = self . tcx . def_path_str ( adt. non_enum_variant ( ) . def_id ) ;
2176
-
2177
2180
err. multipart_suggestion (
2178
- format ! ( "consider calling `{s }::new`" ) ,
2181
+ format ! ( "consider calling `{nonzero_alias }::new`" ) ,
2179
2182
vec ! [
2180
- ( expr. span. shrink_to_lo( ) , format!( "{path }::new(" ) ) ,
2183
+ ( expr. span. shrink_to_lo( ) , format!( "{nonzero_alias }::new(" ) ) ,
2181
2184
( expr. span. shrink_to_hi( ) , format!( "){unwrap}" ) ) ,
2182
2185
] ,
2183
2186
Applicability :: MaybeIncorrect ,
0 commit comments