@@ -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,25 @@ fn evaluate_function_match(
143153 Err ( _) => false ,
144154 }
145155 }
156+ ReturnTypePattern :: SelfValue => {
157+ get_self_type ( ctx, fn_def_id) . map_or ( false , |self_ty| return_ty == self_ty)
158+ }
159+ ReturnTypePattern :: SelfRef => {
160+ match ( get_self_type ( ctx, fn_def_id) , return_ty. kind ( ) ) {
161+ ( Some ( self_ty) , & TyKind :: Ref ( _, inner, rustc_hir:: Mutability :: Not ) ) => {
162+ inner == self_ty
163+ }
164+ _ => false ,
165+ }
166+ }
167+ ReturnTypePattern :: SelfMutRef => {
168+ match ( get_self_type ( ctx, fn_def_id) , return_ty. kind ( ) ) {
169+ ( Some ( self_ty) , & TyKind :: Ref ( _, inner, rustc_hir:: Mutability :: Mut ) ) => {
170+ inner == self_ty
171+ }
172+ _ => false ,
173+ }
174+ }
146175 }
147176 }
148177 FunctionMatch :: AndMatches ( left, right) => {
@@ -284,6 +313,21 @@ impl<'tcx> LateLintPass<'tcx> for FunctionLint {
284313 }
285314 }
286315 }
316+ FunctionRule :: MustNotExist ( severity) => {
317+ let sig_span = item
318+ . span
319+ . with_hi ( item. span . lo ( ) + BytePos ( ( item_name. len ( ) + 5 ) as u32 ) ) ;
320+
321+ span_lint_and_help (
322+ ctx,
323+ FUNCTION_LINT :: get_by_severity ( * severity) ,
324+ self . name ( ) . as_str ( ) ,
325+ sig_span,
326+ format ! ( "Function '{item_name}' is forbidden by lint rule" ) ,
327+ None ,
328+ "Remove this function to satisfy the architectural rule" ,
329+ ) ;
330+ }
287331 }
288332 }
289333 }
@@ -372,6 +416,21 @@ impl<'tcx> LateLintPass<'tcx> for FunctionLint {
372416 }
373417 }
374418 }
419+ FunctionRule :: MustNotExist ( severity) => {
420+ let sig_span = impl_item
421+ . span
422+ . with_hi ( impl_item. span . lo ( ) + BytePos ( ( item_name. len ( ) + 5 ) as u32 ) ) ;
423+
424+ span_lint_and_help (
425+ ctx,
426+ FUNCTION_LINT :: get_by_severity ( * severity) ,
427+ self . name ( ) . as_str ( ) ,
428+ sig_span,
429+ format ! ( "Function '{item_name}' is forbidden by lint rule" ) ,
430+ None ,
431+ "Remove this function to satisfy the architectural rule" ,
432+ ) ;
433+ }
375434 }
376435 }
377436 }
0 commit comments