1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-21 03:00:19 +02:00

Add -Wunused-module.

* module/language/tree-il/analyze.scm (<module-info>): New record type.
(unused-module-analysis): New variable.
(make-unused-module-analysis): New analysis.
(make-analyzer): Add it.
* module/system/base/message.scm (%warning-types): Add 'unused-module'.
* test-suite/tests/tree-il.test (%opts-w-unused-module): New variable.
("warnings")["unused-module"]: New test prefix.
* NEWS: Update.
This commit is contained in:
Ludovic Courtès 2023-02-11 23:33:37 +01:00
parent 821e0f9cd5
commit 89c3bae3cf
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
4 changed files with 336 additions and 3 deletions

View file

@ -1,7 +1,7 @@
;;;; tree-il.test --- test suite for compiling tree-il -*- scheme -*-
;;;; Andy Wingo <wingo@pobox.com> --- May 2009
;;;;
;;;; Copyright (C) 2009-2014,2018-2021 Free Software Foundation, Inc.
;;;; Copyright (C) 2009-2014,2018-2021,2023 Free Software Foundation, Inc.
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
@ -217,6 +217,9 @@
(define %opts-w-unused-toplevel
'(#:warnings (unused-toplevel)))
(define %opts-w-unused-module
'(#:warnings (unused-module)))
(define %opts-w-shadowed-toplevel
'(#:warnings (shadowed-toplevel)))
@ -414,6 +417,158 @@
#:to 'cps
#:opts %opts-w-unused-toplevel))))))
(with-test-prefix "unused-module"
(pass-if-equal "quiet"
'()
(call-with-warnings
(lambda ()
(compile '(begin
(use-modules (ice-9 popen))
(define (proc cmd)
(open-input-pipe cmd)))
#:env (make-fresh-user-module)
#:opts %opts-w-unused-module))))
(pass-if-equal "quiet, renamer"
'()
(call-with-warnings
(lambda ()
(compile '(begin
(use-modules ((ice-9 popen) #:prefix p-))
(define (proc cmd)
(p-open-input-pipe cmd)))
#:env (make-fresh-user-module)
#:opts %opts-w-unused-module))))
(pass-if "definitely unused"
(let* ((defmod '(define-module (foo)
#:use-module (ice-9 vlist)
#:use-module (ice-9 popen)
#:export (proc)))
(w (call-with-warnings
(lambda ()
(set-source-properties! defmod
'((filename . "foo.scm")
(line . 0)
(column . 0)))
(compile `(begin
,defmod
(define (frob x)
(vlist-cons x vlist-null)))
#:env (make-fresh-user-module)
#:opts %opts-w-unused-module)))))
(and (= (length w) 1)
(string-prefix? "foo.scm:1:0" (car w))
(number? (string-contains (car w)
"unused module (ice-9 popen)")))))
(pass-if "definitely unused, use-modules"
(let* ((usemod '(use-modules (rnrs bytevectors)
(ice-9 q)))
(w (call-with-warnings
(lambda ()
(set-source-properties! usemod
'((filename . "bar.scm")
(line . 5)
(column . 0)))
(compile `(begin
,usemod
(define (square x)
(* x x)))
#:env (make-fresh-user-module)
#:opts %opts-w-unused-module)))))
(and (= (length w) 2)
(string-prefix? "bar.scm:6:0" (car w))
(number? (string-contains (car w)
"unused module (rnrs bytevectors)"))
(number? (string-contains (cadr w)
"unused module (ice-9 q)")))))
(pass-if "definitely unused, local binding shadows imported one"
(let ((w (call-with-warnings
(lambda ()
(compile `(begin
(define-module (whatever x y z)
#:use-module (ice-9 popen)
#:export (frob))
(define (open-input-pipe x)
;; Shadows the one from (ice-9 popen).
x)
(define (frob y)
(close-port (open-input-pipe y))))
#:env (make-fresh-user-module)
#:opts %opts-w-unused-module)))))
(and (= (length w) 1)
(number? (string-contains (car w)
"unused module (ice-9 popen)")))))
(pass-if-equal "(ice-9 match) is actually used"
'()
;; (ice-9 match) is used and the macro expansion of the 'match'
;; form refers to (@@ (ice-9 match) car) and the likes.
(call-with-warnings
(lambda ()
(compile '(begin
(use-modules (ice-9 match))
(define (proc lst)
(match lst
((a b c) (+ a (* b c))))))
#:env (make-fresh-user-module)
#:opts %opts-w-unused-module))))
(pass-if-equal "re-exporting is using"
'()
;; This module re-exports a binding from (ice-9 q), so (ice-9 q)
;; should be considered as used.
(call-with-warnings
(lambda ()
(compile '(begin
(define-module (this is an ice-9 q user)
#:use-module (ice-9 q)
#:re-export (make-q)
#:export (proc))
(define (proc a b)
(* a b)))
#:env (make-fresh-user-module)
#:opts %opts-w-unused-module))))
(pass-if "(srfi srfi-26) might be unused"
;; At the tree-il level, it is impossible to know whether (srfi
;; srfi-26) is actually use, because all we see is the output of
;; macro expansion, and in this case it doesn't capture any
;; binding from (srfi srfi-26).
(let* ((w (call-with-warnings
(lambda ()
(compile `(begin
(define-module (whatever)
#:use-module (srfi srfi-26)
#:export (square))
(define double
(cut * 2 <>)))
#:env (make-fresh-user-module)
#:opts %opts-w-unused-module)))))
(and (= (length w) 1)
(number? (string-contains (car w)
"possibly unused module (srfi srfi-26)")))))
(pass-if-equal "(ice-9 format) is actually used"
'()
;; The 'format' binding of (ice-9 format) takes precedence over
;; (@@ (guile) format), so (ice-9 format) must not be reported as
;; unused.
(call-with-warnings
(lambda ()
(compile '(begin
(define-module (whatever-else)
#:use-module (ice-9 format)
#:export (proc))
(define (proc lst)
(format #f "~{~a ~}~%" lst)))
#:env (make-fresh-user-module)
#:opts %opts-w-unused-module)))))
(with-test-prefix "shadowed-toplevel"
(pass-if "quiet"