Skip to content

Commit 67afeeb

Browse files
Merge #4137
4137: Prefer core/alloc paths on #![no_std] r=matklad a=jonas-schievink Co-authored-by: Jonas Schievink <[email protected]>
2 parents fc57358 + 3cf2c3b commit 67afeeb

File tree

2 files changed

+87
-14
lines changed

2 files changed

+87
-14
lines changed

crates/ra_hir_def/src/attr.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use ra_syntax::{
1313
use tt::Subtree;
1414

1515
use crate::{
16-
db::DefDatabase, path::ModPath, src::HasChildSource, src::HasSource, AdtId, AttrDefId, Lookup,
16+
db::DefDatabase, nameres::ModuleSource, path::ModPath, src::HasChildSource, src::HasSource,
17+
AdtId, AttrDefId, Lookup,
1718
};
1819

1920
#[derive(Default, Debug, Clone, PartialEq, Eq)]
@@ -37,11 +38,19 @@ impl Attrs {
3738
match def {
3839
AttrDefId::ModuleId(module) => {
3940
let def_map = db.crate_def_map(module.krate);
40-
let src = match def_map[module.local_id].declaration_source(db) {
41-
Some(it) => it,
42-
None => return Attrs::default(),
43-
};
44-
Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
41+
let mod_data = &def_map[module.local_id];
42+
match mod_data.declaration_source(db) {
43+
Some(it) => {
44+
Attrs::from_attrs_owner(db, it.as_ref().map(|it| it as &dyn AttrsOwner))
45+
}
46+
None => Attrs::from_attrs_owner(
47+
db,
48+
mod_data.definition_source(db).as_ref().map(|src| match src {
49+
ModuleSource::SourceFile(file) => file as &dyn AttrsOwner,
50+
ModuleSource::Module(module) => module as &dyn AttrsOwner,
51+
}),
52+
),
53+
}
4554
}
4655
AttrDefId::FieldId(it) => {
4756
let src = it.parent.child_source(db);
@@ -106,7 +115,9 @@ pub struct Attr {
106115

107116
#[derive(Debug, Clone, PartialEq, Eq)]
108117
pub enum AttrInput {
118+
/// `#[attr = "string"]`
109119
Literal(SmolStr),
120+
/// `#[attr(subtree)]`
110121
TokenTree(Subtree),
111122
}
112123

crates/ra_hir_def/src/find_path.rs

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ impl ModPath {
1919

2020
// When std library is present, paths starting with `std::`
2121
// should be preferred over paths starting with `core::` and `alloc::`
22-
fn should_start_with_std(&self) -> bool {
22+
fn can_start_with_std(&self) -> bool {
2323
self.segments
2424
.first()
2525
.filter(|&first_segment| {
@@ -132,6 +132,9 @@ fn find_path_inner(
132132
}
133133

134134
// - otherwise, look for modules containing (reexporting) it and import it from one of those
135+
let crate_root = ModuleId { local_id: def_map.root, krate: from.krate };
136+
let crate_attrs = db.attrs(crate_root.into());
137+
let prefer_no_std = crate_attrs.by_key("no_std").exists();
135138
let importable_locations = find_importable_locations(db, item, from);
136139
let mut best_path = None;
137140
let mut best_path_len = max_len;
@@ -147,21 +150,32 @@ fn find_path_inner(
147150
};
148151
path.segments.push(name);
149152

150-
let new_path =
151-
if let Some(best_path) = best_path { select_best_path(best_path, path) } else { path };
153+
let new_path = if let Some(best_path) = best_path {
154+
select_best_path(best_path, path, prefer_no_std)
155+
} else {
156+
path
157+
};
152158
best_path_len = new_path.len();
153159
best_path = Some(new_path);
154160
}
155161
best_path
156162
}
157163

158-
fn select_best_path(old_path: ModPath, new_path: ModPath) -> ModPath {
159-
if old_path.starts_with_std() && new_path.should_start_with_std() {
164+
fn select_best_path(old_path: ModPath, new_path: ModPath, prefer_no_std: bool) -> ModPath {
165+
if old_path.starts_with_std() && new_path.can_start_with_std() {
160166
tested_by!(prefer_std_paths);
161-
old_path
162-
} else if new_path.starts_with_std() && old_path.should_start_with_std() {
167+
if prefer_no_std {
168+
new_path
169+
} else {
170+
old_path
171+
}
172+
} else if new_path.starts_with_std() && old_path.can_start_with_std() {
163173
tested_by!(prefer_std_paths);
164-
new_path
174+
if prefer_no_std {
175+
old_path
176+
} else {
177+
new_path
178+
}
165179
} else if new_path.len() < old_path.len() {
166180
new_path
167181
} else {
@@ -512,6 +526,54 @@ mod tests {
512526
check_found_path(code, "std::sync::Arc");
513527
}
514528

529+
#[test]
530+
fn prefer_alloc_paths_over_std() {
531+
covers!(prefer_std_paths);
532+
let code = r#"
533+
//- /main.rs crate:main deps:alloc,std
534+
#![no_std]
535+
536+
<|>
537+
538+
//- /std.rs crate:std deps:alloc
539+
540+
pub mod sync {
541+
pub use alloc::sync::Arc;
542+
}
543+
544+
//- /zzz.rs crate:alloc
545+
546+
pub mod sync {
547+
pub struct Arc;
548+
}
549+
"#;
550+
check_found_path(code, "alloc::sync::Arc");
551+
}
552+
553+
#[test]
554+
fn prefer_core_paths_over_std() {
555+
covers!(prefer_std_paths);
556+
let code = r#"
557+
//- /main.rs crate:main deps:core,std
558+
#![no_std]
559+
560+
<|>
561+
562+
//- /std.rs crate:std deps:core
563+
564+
pub mod fmt {
565+
pub use core::fmt::Error;
566+
}
567+
568+
//- /zzz.rs crate:core
569+
570+
pub mod fmt {
571+
pub struct Error;
572+
}
573+
"#;
574+
check_found_path(code, "core::fmt::Error");
575+
}
576+
515577
#[test]
516578
fn prefer_shorter_paths_if_not_alloc() {
517579
let code = r#"

0 commit comments

Comments
 (0)