Hi all, R CMD check gives a false positive locally when the only usage of an imported package is through pkg::foo() inside an R6 class. This GitHub repo contains a full MWE, with log files and a more elaborate explanation: https://github.com/BjarkeHautop/RCMDcheckFalsePositive The R package contains a single .R file with this (I'm aware you don't have to import base packages explicitly, but this is an MWE with only base packages (except R6)): filter <- function() { message("This is a custom filter function.") } DataProcessor <- R6::R6Class( "DataProcessor", public = list( data = NULL, initialize = function(data) self$data <- data, filter_data = function(data) { filter() self$data <- stats::filter(self$data, rep(1, 3)) } ) ) When running R CMD check, it will generate the following NOTE: * checking dependencies in R code ... NOTE Namespaces in Imports field not imported from: ?R6? ?stats? Interestingly, the NOTE disappears on CRAN release/dev winbuilder. My questions are: 1. Is this the intended behavior of R CMD check, or is it a bug that it fails to detect usage of packages inside R6 classes? If intended (e.g., due to it being too expensive to check for :: in "hidden places") should this be mentioned somewhere on WRE? Currently [WRE]( https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Package-Dependencies-1) says: *"The ?Imports? field should not contain packages which are not imported from (via the NAMESPACE file or :: or ::: operators)"* indicating that `::` usage should be fully supported. 2. How/Why does the NOTE disappear when checking on CRAN dev winbuilder? Can I replicate this behavior locally using R CMD check? Will it pass on CRAN? Best regards, Bjarke
[R-pkg-devel] R CMD check false positive unused imports inside R6 class
9 messages · Michael Chirico, Bjarke Hautop, Dirk Eddelbuettel +1 more
On 12 February 2026 at 15:52, Bjarke Hautop wrote:
| Hi all, | | R CMD check gives a false positive locally when the only usage of an | imported package is through pkg::foo() inside an R6 class. This GitHub repo | contains a full MWE, with log files and a more elaborate explanation: | https://github.com/BjarkeHautop/RCMDcheckFalsePositive | | The R package contains a single .R file with this (I'm aware you don't have | to import base packages explicitly, but this is an MWE with only base | packages (except R6)): | | filter <- function() { | message("This is a custom filter function.") | } | | DataProcessor <- R6::R6Class( | "DataProcessor", | public = list( | data = NULL, | initialize = function(data) self$data <- data, | | filter_data = function(data) { | filter() | self$data <- stats::filter(self$data, rep(1, 3)) | } | ) | ) | | When running R CMD check, it will generate the following NOTE: | | * checking dependencies in R code ... NOTE | Namespaces in Imports field not imported from: | ?R6? ?stats? Thanks for posting a full and complete example! From a quick glance your problem may be that while you DO have the the packages in DESCRIPTION you DO NOT import them in NAMESPACE. The error message could arguably be more explicit but that seems to be the case here. Hope this helps, Dirk | Interestingly, the NOTE disappears on CRAN release/dev winbuilder. | | My questions are: | | 1. Is this the intended behavior of R CMD check, or is it a bug that it | fails to detect usage of packages inside | R6 classes? If intended (e.g., due to it being too expensive to check for | :: in "hidden places") should this be | mentioned somewhere on WRE? Currently | [WRE]( | https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Package-Dependencies-1) | says: | *"The ?Imports? field should not contain packages which are not imported | from (via the NAMESPACE file or :: or ::: operators)"* | indicating that `::` usage should be fully supported. | | 2. How/Why does the NOTE disappear when checking on CRAN dev winbuilder? | Can I replicate this behavior locally using R CMD check? Will it pass on | CRAN? | | Best regards, | Bjarke | | [[alternative HTML version deleted]] | | ______________________________________________ | R-package-devel at r-project.org mailing list | https://stat.ethz.ch/mailman/listinfo/r-package-devel
dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
R6 is a _build-time_ dependency for your package. It may be possible for a
user without R6 installed to run your package without issue from the built
tarball. R today doesn't really have a concept of a build-time dependency
in the DESCRIPTION
'stats' is more of a false positive -- {codetools} simply doesn't know how
to check the R6 object DataProcessor (which it sees as an environment and
doesn't walk completely). It could find 'stats::' if it looked at
body(getNamespace(<pkg>)$DataProcessor$public_methods$filter_data)[[3]][[3]][[1]]
Anyway, Dirk's advice is correct: you can just add the entries to your
NAMESPACE:
importFrom(R6, R6class)
importFrom(stats, filter)
Once that's done, you can choose whether to continue namespace-qualifying
the calls inside the sources.
You could also explore if just putting the packages in Suggests, not
Imports, works.
Mike C
On Thu, Feb 12, 2026 at 2:33?PM Dirk Eddelbuettel <edd at debian.org> wrote:
On 12 February 2026 at 15:52, Bjarke Hautop wrote: | Hi all, | | R CMD check gives a false positive locally when the only usage of an | imported package is through pkg::foo() inside an R6 class. This GitHub repo | contains a full MWE, with log files and a more elaborate explanation: | https://github.com/BjarkeHautop/RCMDcheckFalsePositive | | The R package contains a single .R file with this (I'm aware you don't have | to import base packages explicitly, but this is an MWE with only base | packages (except R6)): | | filter <- function() { | message("This is a custom filter function.") | } | | DataProcessor <- R6::R6Class( | "DataProcessor", | public = list( | data = NULL, | initialize = function(data) self$data <- data, | | filter_data = function(data) { | filter() | self$data <- stats::filter(self$data, rep(1, 3)) | } | ) | ) | | When running R CMD check, it will generate the following NOTE: | | * checking dependencies in R code ... NOTE | Namespaces in Imports field not imported from: | ?R6? ?stats? Thanks for posting a full and complete example! From a quick glance your problem may be that while you DO have the the packages in DESCRIPTION you DO NOT import them in NAMESPACE. The error message could arguably be more explicit but that seems to be the case here. Hope this helps, Dirk | Interestingly, the NOTE disappears on CRAN release/dev winbuilder. | | My questions are: | | 1. Is this the intended behavior of R CMD check, or is it a bug that it | fails to detect usage of packages inside | R6 classes? If intended (e.g., due to it being too expensive to check for | :: in "hidden places") should this be | mentioned somewhere on WRE? Currently | [WRE]( | https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Package-Dependencies-1 ) | says: | *"The ?Imports? field should not contain packages which are not imported | from (via the NAMESPACE file or :: or ::: operators)"* | indicating that `::` usage should be fully supported. | | 2. How/Why does the NOTE disappear when checking on CRAN dev winbuilder? | Can I replicate this behavior locally using R CMD check? Will it pass on | CRAN? | | Best regards, | Bjarke | | [[alternative HTML version deleted]] | | ______________________________________________ | R-package-devel at r-project.org mailing list | https://stat.ethz.ch/mailman/listinfo/r-package-devel -- dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Interestingly, the NOTE disappears on CRAN release/dev winbuilder.
I suspect that's due to a difference of running the check on the built package vs. on the package sources: tools:::.check_packages_used(dir = ".") # nothing tools:::.check_packages_used(package = <pkg>) # Namespaces in Imports field not imported from: # ?R6? ?stats? # All declared Imports should be used. Mike C On Thu, Feb 12, 2026 at 2:53?PM Michael Chirico <michaelchirico4 at gmail.com> wrote:
R6 is a _build-time_ dependency for your package. It may be possible for a
user without R6 installed to run your package without issue from the built
tarball. R today doesn't really have a concept of a build-time dependency
in the DESCRIPTION
'stats' is more of a false positive -- {codetools} simply doesn't know how
to check the R6 object DataProcessor (which it sees as an environment and
doesn't walk completely). It could find 'stats::' if it looked at
body(getNamespace(<pkg>)$DataProcessor$public_methods$filter_data)[[3]][[3]][[1]]
Anyway, Dirk's advice is correct: you can just add the entries to your
NAMESPACE:
importFrom(R6, R6class)
importFrom(stats, filter)
Once that's done, you can choose whether to continue namespace-qualifying
the calls inside the sources.
You could also explore if just putting the packages in Suggests, not
Imports, works.
Mike C
On Thu, Feb 12, 2026 at 2:33?PM Dirk Eddelbuettel <edd at debian.org> wrote:
On 12 February 2026 at 15:52, Bjarke Hautop wrote: | Hi all, | | R CMD check gives a false positive locally when the only usage of an | imported package is through pkg::foo() inside an R6 class. This GitHub repo | contains a full MWE, with log files and a more elaborate explanation: | https://github.com/BjarkeHautop/RCMDcheckFalsePositive | | The R package contains a single .R file with this (I'm aware you don't have | to import base packages explicitly, but this is an MWE with only base | packages (except R6)): | | filter <- function() { | message("This is a custom filter function.") | } | | DataProcessor <- R6::R6Class( | "DataProcessor", | public = list( | data = NULL, | initialize = function(data) self$data <- data, | | filter_data = function(data) { | filter() | self$data <- stats::filter(self$data, rep(1, 3)) | } | ) | ) | | When running R CMD check, it will generate the following NOTE: | | * checking dependencies in R code ... NOTE | Namespaces in Imports field not imported from: | ?R6? ?stats? Thanks for posting a full and complete example! From a quick glance your problem may be that while you DO have the the packages in DESCRIPTION you DO NOT import them in NAMESPACE. The error message could arguably be more explicit but that seems to be the case here. Hope this helps, Dirk | Interestingly, the NOTE disappears on CRAN release/dev winbuilder. | | My questions are: | | 1. Is this the intended behavior of R CMD check, or is it a bug that it | fails to detect usage of packages inside | R6 classes? If intended (e.g., due to it being too expensive to check for | :: in "hidden places") should this be | mentioned somewhere on WRE? Currently | [WRE]( | https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Package-Dependencies-1 ) | says: | *"The ?Imports? field should not contain packages which are not imported | from (via the NAMESPACE file or :: or ::: operators)"* | indicating that `::` usage should be fully supported. | | 2. How/Why does the NOTE disappear when checking on CRAN dev winbuilder? | Can I replicate this behavior locally using R CMD check? Will it pass on | CRAN? | | Best regards, | Bjarke | | [[alternative HTML version deleted]] | | ______________________________________________ | R-package-devel at r-project.org mailing list | https://stat.ethz.ch/mailman/listinfo/r-package-devel -- dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Thanks, Dirk and Michael,
In my opinion, there are several reasons why you wouldn't want to just do
importFrom(stats, filter). Using devtools::load_all() typing "filte" in the
console now only brings up Base::Filter and stats::filter and not the
function that will actually be called from filter(),
i.e., my internal filter function. Additionally, you can't do this if the
reason you did pkg::foo() was to avoid nameclash between two different
packages, e.g., extend my example with also dplyr::filter. You can't add
importFrom(stats, filter)
importFrom(dplyr, filter)
How I see it, the only safe way to do it in this case is to use
stats::filter and dplyr::filter outside the R6 class, either by refactoring
(which might make the code more unreadable) or adding an unused function,
such as this:
avoid_cran_note() {
stats::filter(1:10, rep(1, 3))
my_data <- data.frame(
x = 1:5,
y = c(10, 20, 30, 40, 50)
)
dplyr::filter(my_data, my_data$x > 3)
}
Neither approach seems ideal to me.
Best regards,
Bjarke
Den tors. 12. feb. 2026 kl. 23.53 skrev Michael Chirico <
michaelchirico4 at gmail.com>:
R6 is a _build-time_ dependency for your package. It may be possible for a
user without R6 installed to run your package without issue from the built
tarball. R today doesn't really have a concept of a build-time dependency
in the DESCRIPTION
'stats' is more of a false positive -- {codetools} simply doesn't know how
to check the R6 object DataProcessor (which it sees as an environment and
doesn't walk completely). It could find 'stats::' if it looked at
body(getNamespace(<pkg>)$DataProcessor$public_methods$filter_data)[[3]][[3]][[1]]
Anyway, Dirk's advice is correct: you can just add the entries to your
NAMESPACE:
importFrom(R6, R6class)
importFrom(stats, filter)
Once that's done, you can choose whether to continue namespace-qualifying
the calls inside the sources.
You could also explore if just putting the packages in Suggests, not
Imports, works.
Mike C
On Thu, Feb 12, 2026 at 2:33?PM Dirk Eddelbuettel <edd at debian.org> wrote:
On 12 February 2026 at 15:52, Bjarke Hautop wrote: | Hi all, | | R CMD check gives a false positive locally when the only usage of an | imported package is through pkg::foo() inside an R6 class. This GitHub repo | contains a full MWE, with log files and a more elaborate explanation: | https://github.com/BjarkeHautop/RCMDcheckFalsePositive | | The R package contains a single .R file with this (I'm aware you don't have | to import base packages explicitly, but this is an MWE with only base | packages (except R6)): | | filter <- function() { | message("This is a custom filter function.") | } | | DataProcessor <- R6::R6Class( | "DataProcessor", | public = list( | data = NULL, | initialize = function(data) self$data <- data, | | filter_data = function(data) { | filter() | self$data <- stats::filter(self$data, rep(1, 3)) | } | ) | ) | | When running R CMD check, it will generate the following NOTE: | | * checking dependencies in R code ... NOTE | Namespaces in Imports field not imported from: | ?R6? ?stats? Thanks for posting a full and complete example! From a quick glance your problem may be that while you DO have the the packages in DESCRIPTION you DO NOT import them in NAMESPACE. The error message could arguably be more explicit but that seems to be the case here. Hope this helps, Dirk | Interestingly, the NOTE disappears on CRAN release/dev winbuilder. | | My questions are: | | 1. Is this the intended behavior of R CMD check, or is it a bug that it | fails to detect usage of packages inside | R6 classes? If intended (e.g., due to it being too expensive to check for | :: in "hidden places") should this be | mentioned somewhere on WRE? Currently | [WRE]( | https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Package-Dependencies-1 ) | says: | *"The ?Imports? field should not contain packages which are not imported | from (via the NAMESPACE file or :: or ::: operators)"* | indicating that `::` usage should be fully supported. | | 2. How/Why does the NOTE disappear when checking on CRAN dev winbuilder? | Can I replicate this behavior locally using R CMD check? Will it pass on | CRAN? | | Best regards, | Bjarke | | [[alternative HTML version deleted]] | | ______________________________________________ | R-package-devel at r-project.org mailing list | https://stat.ethz.ch/mailman/listinfo/r-package-devel -- dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Sorry, clicked send too soon!
It could find 'stats::' if it looked at
body(getNamespace(<pkg>)$DataProcessor$public_methods$filter_data)[[3]][[3]][[1]] Is there a reason why it doesn't do this? Is it just for computational reasons? Best regards, Bjarke Den tors. 12. feb. 2026 kl. 23.53 skrev Michael Chirico < michaelchirico4 at gmail.com>:
R6 is a _build-time_ dependency for your package. It may be possible for a
user without R6 installed to run your package without issue from the built
tarball. R today doesn't really have a concept of a build-time dependency
in the DESCRIPTION
'stats' is more of a false positive -- {codetools} simply doesn't know how
to check the R6 object DataProcessor (which it sees as an environment and
doesn't walk completely). It could find 'stats::' if it looked at
body(getNamespace(<pkg>)$DataProcessor$public_methods$filter_data)[[3]][[3]][[1]]
Anyway, Dirk's advice is correct: you can just add the entries to your
NAMESPACE:
importFrom(R6, R6class)
importFrom(stats, filter)
Once that's done, you can choose whether to continue namespace-qualifying
the calls inside the sources.
You could also explore if just putting the packages in Suggests, not
Imports, works.
Mike C
On Thu, Feb 12, 2026 at 2:33?PM Dirk Eddelbuettel <edd at debian.org> wrote:
On 12 February 2026 at 15:52, Bjarke Hautop wrote: | Hi all, | | R CMD check gives a false positive locally when the only usage of an | imported package is through pkg::foo() inside an R6 class. This GitHub repo | contains a full MWE, with log files and a more elaborate explanation: | https://github.com/BjarkeHautop/RCMDcheckFalsePositive | | The R package contains a single .R file with this (I'm aware you don't have | to import base packages explicitly, but this is an MWE with only base | packages (except R6)): | | filter <- function() { | message("This is a custom filter function.") | } | | DataProcessor <- R6::R6Class( | "DataProcessor", | public = list( | data = NULL, | initialize = function(data) self$data <- data, | | filter_data = function(data) { | filter() | self$data <- stats::filter(self$data, rep(1, 3)) | } | ) | ) | | When running R CMD check, it will generate the following NOTE: | | * checking dependencies in R code ... NOTE | Namespaces in Imports field not imported from: | ?R6? ?stats? Thanks for posting a full and complete example! From a quick glance your problem may be that while you DO have the the packages in DESCRIPTION you DO NOT import them in NAMESPACE. The error message could arguably be more explicit but that seems to be the case here. Hope this helps, Dirk | Interestingly, the NOTE disappears on CRAN release/dev winbuilder. | | My questions are: | | 1. Is this the intended behavior of R CMD check, or is it a bug that it | fails to detect usage of packages inside | R6 classes? If intended (e.g., due to it being too expensive to check for | :: in "hidden places") should this be | mentioned somewhere on WRE? Currently | [WRE]( | https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Package-Dependencies-1 ) | says: | *"The ?Imports? field should not contain packages which are not imported | from (via the NAMESPACE file or :: or ::: operators)"* | indicating that `::` usage should be fully supported. | | 2. How/Why does the NOTE disappear when checking on CRAN dev winbuilder? | Can I replicate this behavior locally using R CMD check? Will it pass on | CRAN? | | Best regards, | Bjarke | | [[alternative HTML version deleted]] | | ______________________________________________ | R-package-devel at r-project.org mailing list | https://stat.ethz.ch/mailman/listinfo/r-package-devel -- dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
I reckon it was just written before R6 and could go for a patch: https://gitlab.com/luke-tierney/codetools Point taken about masking. Working from memory (CMIIW) you can just import and name from stats to satisfy the static analysis: importFrom(stats, setNames) R doesn't do two-way "include what you use" checks to insure the names you import are actually used. Mike C On Thu, Feb 12, 2026, 11:33?PM Bjarke Hautop <bjarke.hautop at gmail.com> wrote:
Sorry, clicked send too soon!
It could find 'stats::' if it looked at
body(getNamespace(<pkg>)$DataProcessor$public_methods$filter_data)[[3]][[3]][[1]] Is there a reason why it doesn't do this? Is it just for computational reasons? Best regards, Bjarke Den tors. 12. feb. 2026 kl. 23.53 skrev Michael Chirico < michaelchirico4 at gmail.com>:
R6 is a _build-time_ dependency for your package. It may be possible for
a user without R6 installed to run your package without issue from the
built tarball. R today doesn't really have a concept of a build-time
dependency in the DESCRIPTION
'stats' is more of a false positive -- {codetools} simply doesn't know
how to check the R6 object DataProcessor (which it sees as an environment
and doesn't walk completely). It could find 'stats::' if it looked at
body(getNamespace(<pkg>)$DataProcessor$public_methods$filter_data)[[3]][[3]][[1]]
Anyway, Dirk's advice is correct: you can just add the entries to your
NAMESPACE:
importFrom(R6, R6class)
importFrom(stats, filter)
Once that's done, you can choose whether to continue namespace-qualifying
the calls inside the sources.
You could also explore if just putting the packages in Suggests, not
Imports, works.
Mike C
On Thu, Feb 12, 2026 at 2:33?PM Dirk Eddelbuettel <edd at debian.org> wrote:
On 12 February 2026 at 15:52, Bjarke Hautop wrote: | Hi all, | | R CMD check gives a false positive locally when the only usage of an | imported package is through pkg::foo() inside an R6 class. This GitHub repo | contains a full MWE, with log files and a more elaborate explanation: | https://github.com/BjarkeHautop/RCMDcheckFalsePositive | | The R package contains a single .R file with this (I'm aware you don't have | to import base packages explicitly, but this is an MWE with only base | packages (except R6)): | | filter <- function() { | message("This is a custom filter function.") | } | | DataProcessor <- R6::R6Class( | "DataProcessor", | public = list( | data = NULL, | initialize = function(data) self$data <- data, | | filter_data = function(data) { | filter() | self$data <- stats::filter(self$data, rep(1, 3)) | } | ) | ) | | When running R CMD check, it will generate the following NOTE: | | * checking dependencies in R code ... NOTE | Namespaces in Imports field not imported from: | ?R6? ?stats? Thanks for posting a full and complete example! From a quick glance your problem may be that while you DO have the the packages in DESCRIPTION you DO NOT import them in NAMESPACE. The error message could arguably be more explicit but that seems to be the case here. Hope this helps, Dirk | Interestingly, the NOTE disappears on CRAN release/dev winbuilder. | | My questions are: | | 1. Is this the intended behavior of R CMD check, or is it a bug that it | fails to detect usage of packages inside | R6 classes? If intended (e.g., due to it being too expensive to check for | :: in "hidden places") should this be | mentioned somewhere on WRE? Currently | [WRE]( | https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Package-Dependencies-1 ) | says: | *"The ?Imports? field should not contain packages which are not imported | from (via the NAMESPACE file or :: or ::: operators)"* | indicating that `::` usage should be fully supported. | | 2. How/Why does the NOTE disappear when checking on CRAN dev winbuilder? | Can I replicate this behavior locally using R CMD check? Will it pass on | CRAN? | | Best regards, | Bjarke | | [[alternative HTML version deleted]] | | ______________________________________________ | R-package-devel at r-project.org mailing list | https://stat.ethz.ch/mailman/listinfo/r-package-devel -- dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Bjarke,
I had sent you a minimal diff that silenced R CMD check after you replied to
me off-list; if it were my package I'd stop there.
But you can of course continue to insist that you should be allowed to have a
local, internal filtering function -- and "yes you can". But the common
(documented) trick is to use _an internal function_ differentiated with a
leading dot, i.e. `.filter()`. So with the diff below I once again only have
a warning from your class being undocumented. That R6 needs to be imported
seems par for the course; Michael rightly suggested that you could patch
`codetools` if it really bugs you.
Cheers, Dirk
edd at paul:/tmp/r/RCMDcheckFalsePositive(main)$ git diff
diff --git i/NAMESPACE w/NAMESPACE
index dbd6067..817a7ee 100644
--- i/NAMESPACE
+++ w/NAMESPACE
@@ -1 +1,2 @@
export(DataProcessor)
+import(R6)
diff --git i/R/hello.R w/R/hello.R
index a608963..85befc4 100644
--- i/R/hello.R
+++ w/R/hello.R
@@ -1,4 +1,4 @@
-filter <- function() {
+.filter <- function() {
message("This is a custom filter function.")
}
@@ -9,7 +9,7 @@ DataProcessor <- R6::R6Class(
initialize = function(data) self$data <- data,
filter_data = function(data) {
- filter()
+ .filter()
self$data <- stats::filter(self$data, rep(1, 3))
}
)
edd at paul:/tmp/r/RCMDcheckFalsePositive(main)$
dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
? Thu, 12 Feb 2026 14:57:59 -0800 Michael Chirico <michaelchirico4 at gmail.com> ?????:
I suspect that's due to a difference of running the check on the built package vs. on the package sources: tools:::.check_packages_used(dir = ".") # nothing tools:::.check_packages_used(package = <pkg>) # Namespaces in Imports field not imported from: # ?R6? ?stats? # All declared Imports should be used.
I wonder what happens on Win-Builder during the check. According to the code (tools/R/check.R line 2156, function check_R_code), tools:::.check_packages_used(dir = ...) is only used if !do_install, and 00check.log from Win-Builder doesn't seem to divulge anything that would set do_install to FALSE. (Checking with --install=fake or --install=check:... still sets do_install to TRUE and causes the NOTE). The function is quite self-contained; indeed, it only walks LANGSXP call objects, expression vectors, and pairlists made from functions. Does tools:::.check_packages_used(package=...) really fail to notice the "unused" imports on Win-Builder? Does something unseen really set do_install <- FALSE? Is there a third reason?
Best regards, Ivan