Merge #4137
4137: Prefer core/alloc paths on #![no_std] r=matklad a=jonas-schievink Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
commit
67afeebaf5
@ -13,7 +13,8 @@ use ra_syntax::{
|
|||||||
use tt::Subtree;
|
use tt::Subtree;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase, path::ModPath, src::HasChildSource, src::HasSource, AdtId, AttrDefId, Lookup,
|
db::DefDatabase, nameres::ModuleSource, path::ModPath, src::HasChildSource, src::HasSource,
|
||||||
|
AdtId, AttrDefId, Lookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||||
@ -37,11 +38,19 @@ impl Attrs {
|
|||||||
match def {
|
match def {
|
||||||
AttrDefId::ModuleId(module) => {
|
AttrDefId::ModuleId(module) => {
|
||||||
let def_map = db.crate_def_map(module.krate);
|
let def_map = db.crate_def_map(module.krate);
|
||||||
let src = match def_map[module.local_id].declaration_source(db) {
|
let mod_data = &def_map[module.local_id];
|
||||||
Some(it) => it,
|
match mod_data.declaration_source(db) {
|
||||||
None => return Attrs::default(),
|
Some(it) => {
|
||||||
};
|
Attrs::from_attrs_owner(db, it.as_ref().map(|it| it as &dyn AttrsOwner))
|
||||||
Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
|
}
|
||||||
|
None => Attrs::from_attrs_owner(
|
||||||
|
db,
|
||||||
|
mod_data.definition_source(db).as_ref().map(|src| match src {
|
||||||
|
ModuleSource::SourceFile(file) => file as &dyn AttrsOwner,
|
||||||
|
ModuleSource::Module(module) => module as &dyn AttrsOwner,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AttrDefId::FieldId(it) => {
|
AttrDefId::FieldId(it) => {
|
||||||
let src = it.parent.child_source(db);
|
let src = it.parent.child_source(db);
|
||||||
@ -106,7 +115,9 @@ pub struct Attr {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum AttrInput {
|
pub enum AttrInput {
|
||||||
|
/// `#[attr = "string"]`
|
||||||
Literal(SmolStr),
|
Literal(SmolStr),
|
||||||
|
/// `#[attr(subtree)]`
|
||||||
TokenTree(Subtree),
|
TokenTree(Subtree),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ impl ModPath {
|
|||||||
|
|
||||||
// When std library is present, paths starting with `std::`
|
// When std library is present, paths starting with `std::`
|
||||||
// should be preferred over paths starting with `core::` and `alloc::`
|
// should be preferred over paths starting with `core::` and `alloc::`
|
||||||
fn should_start_with_std(&self) -> bool {
|
fn can_start_with_std(&self) -> bool {
|
||||||
self.segments
|
self.segments
|
||||||
.first()
|
.first()
|
||||||
.filter(|&first_segment| {
|
.filter(|&first_segment| {
|
||||||
@ -132,6 +132,9 @@ fn find_path_inner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// - otherwise, look for modules containing (reexporting) it and import it from one of those
|
// - otherwise, look for modules containing (reexporting) it and import it from one of those
|
||||||
|
let crate_root = ModuleId { local_id: def_map.root, krate: from.krate };
|
||||||
|
let crate_attrs = db.attrs(crate_root.into());
|
||||||
|
let prefer_no_std = crate_attrs.by_key("no_std").exists();
|
||||||
let importable_locations = find_importable_locations(db, item, from);
|
let importable_locations = find_importable_locations(db, item, from);
|
||||||
let mut best_path = None;
|
let mut best_path = None;
|
||||||
let mut best_path_len = max_len;
|
let mut best_path_len = max_len;
|
||||||
@ -147,21 +150,32 @@ fn find_path_inner(
|
|||||||
};
|
};
|
||||||
path.segments.push(name);
|
path.segments.push(name);
|
||||||
|
|
||||||
let new_path =
|
let new_path = if let Some(best_path) = best_path {
|
||||||
if let Some(best_path) = best_path { select_best_path(best_path, path) } else { path };
|
select_best_path(best_path, path, prefer_no_std)
|
||||||
|
} else {
|
||||||
|
path
|
||||||
|
};
|
||||||
best_path_len = new_path.len();
|
best_path_len = new_path.len();
|
||||||
best_path = Some(new_path);
|
best_path = Some(new_path);
|
||||||
}
|
}
|
||||||
best_path
|
best_path
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_best_path(old_path: ModPath, new_path: ModPath) -> ModPath {
|
fn select_best_path(old_path: ModPath, new_path: ModPath, prefer_no_std: bool) -> ModPath {
|
||||||
if old_path.starts_with_std() && new_path.should_start_with_std() {
|
if old_path.starts_with_std() && new_path.can_start_with_std() {
|
||||||
tested_by!(prefer_std_paths);
|
tested_by!(prefer_std_paths);
|
||||||
old_path
|
if prefer_no_std {
|
||||||
} else if new_path.starts_with_std() && old_path.should_start_with_std() {
|
new_path
|
||||||
|
} else {
|
||||||
|
old_path
|
||||||
|
}
|
||||||
|
} else if new_path.starts_with_std() && old_path.can_start_with_std() {
|
||||||
tested_by!(prefer_std_paths);
|
tested_by!(prefer_std_paths);
|
||||||
new_path
|
if prefer_no_std {
|
||||||
|
old_path
|
||||||
|
} else {
|
||||||
|
new_path
|
||||||
|
}
|
||||||
} else if new_path.len() < old_path.len() {
|
} else if new_path.len() < old_path.len() {
|
||||||
new_path
|
new_path
|
||||||
} else {
|
} else {
|
||||||
@ -512,6 +526,54 @@ mod tests {
|
|||||||
check_found_path(code, "std::sync::Arc");
|
check_found_path(code, "std::sync::Arc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn prefer_alloc_paths_over_std() {
|
||||||
|
covers!(prefer_std_paths);
|
||||||
|
let code = r#"
|
||||||
|
//- /main.rs crate:main deps:alloc,std
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
<|>
|
||||||
|
|
||||||
|
//- /std.rs crate:std deps:alloc
|
||||||
|
|
||||||
|
pub mod sync {
|
||||||
|
pub use alloc::sync::Arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /zzz.rs crate:alloc
|
||||||
|
|
||||||
|
pub mod sync {
|
||||||
|
pub struct Arc;
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
check_found_path(code, "alloc::sync::Arc");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn prefer_core_paths_over_std() {
|
||||||
|
covers!(prefer_std_paths);
|
||||||
|
let code = r#"
|
||||||
|
//- /main.rs crate:main deps:core,std
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
<|>
|
||||||
|
|
||||||
|
//- /std.rs crate:std deps:core
|
||||||
|
|
||||||
|
pub mod fmt {
|
||||||
|
pub use core::fmt::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /zzz.rs crate:core
|
||||||
|
|
||||||
|
pub mod fmt {
|
||||||
|
pub struct Error;
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
check_found_path(code, "core::fmt::Error");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prefer_shorter_paths_if_not_alloc() {
|
fn prefer_shorter_paths_if_not_alloc() {
|
||||||
let code = r#"
|
let code = r#"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user