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