@@ -22,8 +22,11 @@ pub struct MacrosEnv {
2222
2323impl Metadata {
2424 pub fn env ( & self ) -> crate :: Result < Arc < MacrosEnv > > {
25- self . env
26- . get_or_try_init ( |builder| load_env ( & self . manifest_dir , & self . config , builder) )
25+ let workspace_root = self . workspace_root ( ) ;
26+
27+ self . env . get_or_try_init ( |builder| {
28+ load_env ( & self . manifest_dir , & workspace_root, & self . config , builder)
29+ } )
2730 }
2831
2932 pub fn workspace_root ( & self ) -> PathBuf {
@@ -91,6 +94,7 @@ pub fn try_for_crate() -> crate::Result<Arc<Metadata>> {
9194
9295fn load_env (
9396 manifest_dir : & Path ,
97+ workspace_root : & Path ,
9498 config : & Config ,
9599 builder : & mut MtimeCacheBuilder ,
96100) -> crate :: Result < Arc < MacrosEnv > > {
@@ -108,7 +112,22 @@ fn load_env(
108112 offline : None ,
109113 } ;
110114
111- for dir in manifest_dir. ancestors ( ) {
115+ // https://github.com/launchbadge/sqlx/issues/4276
116+ let dirs = if manifest_dir. starts_with ( workspace_root) {
117+ // Often just `[manifest_dir, workspace_dir]` but project structures can absolutely
118+ // be more complicated
119+ manifest_dir
120+ . ancestors ( )
121+ . take_while ( |dir| dir. starts_with ( workspace_root) )
122+ . collect :: < Vec < _ > > ( )
123+ } else {
124+ // Thinking of edge cases, there's the possibility that the package directory
125+ // isn't actually a child of the workspace directory. There isn't really any other sane
126+ // thing to do here; we shouldn't traverse into unrelated paths.
127+ [ manifest_dir, workspace_root] . to_vec ( )
128+ } ;
129+
130+ for dir in dirs {
112131 let path = dir. join ( ".env" ) ;
113132
114133 let dotenv = match dotenvy:: from_path_iter ( & path) {
0 commit comments