Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

query!() is evaluated incorrectly/inconsistently with rust-analyser because of static caching #3738

Open
zkrising opened this issue Feb 12, 2025 · 1 comment
Labels

Comments

@zkrising
Copy link

zkrising commented Feb 12, 2025

I have found these related issues/pull requests

Not related to any other issue on this repo - sort of related to #121, but not really

Description

This issue happens in workspaces with sqlx, and does not happen in cargo check, but does affect rust-analyser.

You need two crates in your workspace, and those crates need to use a different database. For example:

crates/
  postgres_red/
    .env (DATABASE_URL=postgres://blah/red_database)
  postgres_yellow/
    .env (DATABASE_URL=postgres://blah/yellow_database)

Rust-Analyser will incorrectly evaluate query!() executions against the wrong database, the right database, or both databases.

According to the rust-analyser devs (where this was originally reported), this is the issue:
rust-lang/rust-analyzer#18533 (comment)

Thanks for the repro, that made me reinvestigate and I just noticed the issue.

Well the lookup happens here launchbadge/sqlx@4590b9c/sqlx-macros-core/src/query/mod.rs#L109-L118
So I am stumped as to what's happening here as your cargo invocation isn't really special in that regard then

I completely missed this when looking into this the last time, this static caching is the culprit. rust-analyzer does not unload proc-macros unlike rustc, so that lazy static is going to be initialized with the first expansion and as such any other expansion in differing crates will observe the Metadata for the first crate.

So unfortunately that's a wontfix from our side, we are required to cache proc-macro expansions for implementation results (I am not going into detail here as we have this discussion before and there is no budging on that stance at this point) and we can't unload proc-macro dylibs either. That needs changing in sqlx, ideally by not using a lazy static that depends on the environment in the first place or replace it with a thread local as right now we spawn a new thread per expansion to clear such context.

Reproduction steps

This repository will reproduce the issue: https://github.com/zkrising/ra-sqlx-repro

A reproduction is available here: https://github.com/zkrising/ra-sqlx-repro

Note that cargo check et. al. report no issues, but rust-analyser will. You might have to edit and save the main.rs files just to get rust-analyser to trip up, but I've found doing that pretty reliably gives you an error that shouldn't exist.

The gist of the repro is that there's sqlite_red which queries red_things and sqlite_yellow which queries yellow_things. Despite the crates working and compiling, rust-analyser will seemingly manifest an error that the table does not exist.

SQLx version

0.8

Enabled SQLx features

runtime-tokio, sqlite, but any driver has this issue

Database server and version

sqlite 3.48.0, but any works

Operating system

Linux

Rust version

rustc 1.83.0-nightly (55a22d2a6 2024-10-06)

@zkrising zkrising added the bug label Feb 12, 2025
@abonander
Copy link
Collaborator

Changing to a thread_local seems like a reasonable workaround. However, since they can be somewhat expensive to access, we should probably put all relevant state into a single context type and access that as early as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants