@@ -26,6 +26,7 @@ use crate::hir_ty_lowering::errors::prohibit_assoc_item_binding;
26
26
use crate :: hir_ty_lowering:: generics:: { check_generic_arg_count, lower_generic_args} ;
27
27
use crate :: middle:: resolve_bound_vars as rbv;
28
28
use crate :: require_c_abi_if_c_variadic;
29
+ use crate :: rustc_middle:: ty:: TypeSuperVisitable ;
29
30
use rustc_ast:: TraitObjectSyntax ;
30
31
use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap } ;
31
32
use rustc_errors:: {
@@ -41,7 +42,7 @@ use rustc_infer::traits::ObligationCause;
41
42
use rustc_middle:: middle:: stability:: AllowUnstable ;
42
43
use rustc_middle:: ty:: {
43
44
self , Const , GenericArgKind , GenericArgsRef , GenericParamDefKind , ParamEnv , Ty , TyCtxt ,
44
- TypeVisitableExt ,
45
+ TypeVisitable , TypeVisitableExt ,
45
46
} ;
46
47
use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
47
48
use rustc_span:: edit_distance:: find_best_match_for_name;
@@ -52,6 +53,7 @@ use rustc_trait_selection::traits::wf::object_region_bounds;
52
53
use rustc_trait_selection:: traits:: { self , ObligationCtxt } ;
53
54
54
55
use std:: fmt:: Display ;
56
+ use std:: ops:: ControlFlow ;
55
57
use std:: slice;
56
58
57
59
/// A path segment that is semantically allowed to have generic arguments.
@@ -2193,46 +2195,76 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
2193
2195
&& let hir:: FnRetTy :: Return ( ty) = decl. output
2194
2196
&& let hir:: TyKind :: InferDelegation ( _, _) = ty. kind
2195
2197
{
2196
- try_emit ( "recursive delegation" ) ;
2198
+ try_emit ( "recursive delegation is not supported yet " ) ;
2197
2199
}
2198
2200
2199
2201
let sig = self . tcx ( ) . fn_sig ( sig_id) . instantiate_identity ( ) ;
2200
2202
if sig. output ( ) . has_opaque_types ( ) {
2201
- try_emit ( "delegation to a function with opaque type" ) ;
2203
+ try_emit ( "delegation to a function with opaque type is not supported yet " ) ;
2202
2204
}
2203
2205
2204
2206
let sig_generics = self . tcx ( ) . generics_of ( sig_id) ;
2205
2207
let parent = self . tcx ( ) . parent ( self . item_def_id ( ) ) ;
2206
2208
let parent_generics = self . tcx ( ) . generics_of ( parent) ;
2207
2209
2208
- let parent_is_trait = ( self . tcx ( ) . def_kind ( parent) == DefKind :: Trait ) as usize ;
2210
+ let parent_def_kind = self . tcx ( ) . def_kind ( parent) ;
2211
+ let parent_is_trait = ( parent_def_kind == DefKind :: Trait ) as usize ;
2209
2212
let sig_has_self = sig_generics. has_self as usize ;
2210
2213
2211
2214
if sig_generics. count ( ) > sig_has_self || parent_generics. count ( ) > parent_is_trait {
2212
- try_emit ( "delegation with early bound generics" ) ;
2215
+ try_emit ( "delegation with early bound generics is not supported yet" ) ;
2216
+ }
2217
+
2218
+ // There is no way to instantiate `Self` param for caller if
2219
+ // 1. callee is a trait method && callee contains `Self` param
2220
+ // 2. parent item isn't a trait or impl
2221
+ if let DefKind :: AssocFn = self . tcx ( ) . def_kind ( sig_id)
2222
+ && !matches ! ( parent_def_kind, DefKind :: Impl { .. } | DefKind :: Trait )
2223
+ && self . tcx ( ) . associated_item ( sig_id) . container
2224
+ == ty:: AssocItemContainer :: TraitContainer
2225
+ {
2226
+ struct HasSelfParamVisitor ;
2227
+
2228
+ impl < ' tcx > ty:: TypeVisitor < TyCtxt < ' tcx > > for HasSelfParamVisitor {
2229
+ type Result = ControlFlow < ( ) > ;
2230
+
2231
+ fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> Self :: Result {
2232
+ // All early bound generics except `Self` are previously banned.
2233
+ // It is enough to check only the `ty::Param`.
2234
+ if matches ! ( ty. kind( ) , ty:: Param ( ..) ) {
2235
+ return ControlFlow :: Break ( ( ) ) ;
2236
+ }
2237
+
2238
+ ty. super_visit_with ( self )
2239
+ }
2240
+ }
2241
+
2242
+ if sig. visit_with ( & mut HasSelfParamVisitor ) . is_break ( ) {
2243
+ try_emit ( "Couldn't instantiate `Self` callee type" ) ;
2244
+ }
2213
2245
}
2214
2246
2215
2247
if self . tcx ( ) . asyncness ( sig_id) == ty:: Asyncness :: Yes {
2216
- try_emit ( "delegation to async functions" ) ;
2248
+ try_emit ( "delegation to async functions is not supported yet " ) ;
2217
2249
}
2218
2250
2219
2251
if self . tcx ( ) . constness ( sig_id) == hir:: Constness :: Const {
2220
- try_emit ( "delegation to const functions" ) ;
2252
+ try_emit ( "delegation to const functions is not supported yet " ) ;
2221
2253
}
2222
2254
2223
2255
if sig. c_variadic ( ) {
2224
- try_emit ( "delegation to variadic functions" ) ;
2256
+ try_emit ( "delegation to variadic functions is not supported yet " ) ;
2225
2257
// variadic functions are also `unsafe` and `extern "C"`.
2226
2258
// Do not emit same error multiple times.
2227
2259
return error_occured;
2228
2260
}
2229
2261
2230
2262
if let hir:: Unsafety :: Unsafe = sig. unsafety ( ) {
2231
- try_emit ( "delegation to unsafe functions" ) ;
2263
+ try_emit ( "delegation to unsafe functions is not supported yet " ) ;
2232
2264
}
2233
2265
2234
2266
if abi:: Abi :: Rust != sig. abi ( ) {
2235
- try_emit ( "delegation to non Rust ABI functions" ) ;
2267
+ try_emit ( "delegation to non Rust ABI functions is not supported yet " ) ;
2236
2268
}
2237
2269
2238
2270
error_occured
0 commit comments