@@ -12,6 +12,16 @@ use rustc_middle::ty::TyKind;
1212use rustc_session:: impl_lint_pass;
1313use rustc_span:: BytePos ;
1414
15+ // Helper: retrieve the concrete Self type of the impl the method belongs to, if any
16+ fn get_self_type < ' tcx > (
17+ ctx : & LateContext < ' tcx > ,
18+ fn_def_id : rustc_hir:: def_id:: DefId ,
19+ ) -> Option < rustc_middle:: ty:: Ty < ' tcx > > {
20+ ctx. tcx
21+ . impl_of_method ( fn_def_id)
22+ . map ( |impl_def_id| ctx. tcx . type_of ( impl_def_id) . instantiate_identity ( ) )
23+ }
24+
1525pub struct FunctionLint {
1626 name : String ,
1727 matches : FunctionMatch ,
@@ -143,6 +153,23 @@ fn evaluate_function_match(
143153 Err ( _) => false ,
144154 }
145155 }
156+ ReturnTypePattern :: SelfValue => get_self_type ( ctx, fn_def_id) == Some ( return_ty) ,
157+ ReturnTypePattern :: SelfRef => {
158+ match ( get_self_type ( ctx, fn_def_id) , return_ty. kind ( ) ) {
159+ ( Some ( self_ty) , & TyKind :: Ref ( _, inner, rustc_hir:: Mutability :: Not ) ) => {
160+ inner == self_ty
161+ }
162+ _ => false ,
163+ }
164+ }
165+ ReturnTypePattern :: SelfMutRef => {
166+ match ( get_self_type ( ctx, fn_def_id) , return_ty. kind ( ) ) {
167+ ( Some ( self_ty) , & TyKind :: Ref ( _, inner, rustc_hir:: Mutability :: Mut ) ) => {
168+ inner == self_ty
169+ }
170+ _ => false ,
171+ }
172+ }
146173 }
147174 }
148175 FunctionMatch :: AndMatches ( left, right) => {
@@ -284,6 +311,21 @@ impl<'tcx> LateLintPass<'tcx> for FunctionLint {
284311 }
285312 }
286313 }
314+ FunctionRule :: MustNotExist ( severity) => {
315+ let sig_span = item
316+ . span
317+ . with_hi ( item. span . lo ( ) + BytePos ( ( item_name. len ( ) + 5 ) as u32 ) ) ;
318+
319+ span_lint_and_help (
320+ ctx,
321+ FUNCTION_LINT :: get_by_severity ( * severity) ,
322+ self . name ( ) . as_str ( ) ,
323+ sig_span,
324+ format ! ( "Function '{item_name}' is forbidden by lint rule" ) ,
325+ None ,
326+ "Remove this function to satisfy the architectural rule" ,
327+ ) ;
328+ }
287329 }
288330 }
289331 }
@@ -372,6 +414,21 @@ impl<'tcx> LateLintPass<'tcx> for FunctionLint {
372414 }
373415 }
374416 }
417+ FunctionRule :: MustNotExist ( severity) => {
418+ let sig_span = impl_item
419+ . span
420+ . with_hi ( impl_item. span . lo ( ) + BytePos ( ( item_name. len ( ) + 5 ) as u32 ) ) ;
421+
422+ span_lint_and_help (
423+ ctx,
424+ FUNCTION_LINT :: get_by_severity ( * severity) ,
425+ self . name ( ) . as_str ( ) ,
426+ sig_span,
427+ format ! ( "Function '{item_name}' is forbidden by lint rule" ) ,
428+ None ,
429+ "Remove this function to satisfy the architectural rule" ,
430+ ) ;
431+ }
375432 }
376433 }
377434 }
0 commit comments