Skip to content

Commit 9f14343

Browse files
committed
Auto merge of #16751 - Veykril:codegen, r=Veykril
internal: Move diagnostics docs generation and lint definition generation into xtask/codegen
2 parents 4e8cbf3 + b9dbb8a commit 9f14343

File tree

18 files changed

+489
-200
lines changed

18 files changed

+489
-200
lines changed

Cargo.lock

+1-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ide-assists/Cargo.toml

-3
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,5 @@ expect-test = "1.4.0"
3333
test-utils.workspace = true
3434
test-fixture.workspace = true
3535

36-
[features]
37-
in-rust-tree = []
38-
3936
[lints]
4037
workspace = true

crates/ide-db/Cargo.toml

-3
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,10 @@ line-index.workspace = true
4444

4545
[dev-dependencies]
4646
expect-test = "1.4.0"
47-
oorandom = "11.1.3"
48-
xshell.workspace = true
4947

5048
# local deps
5149
test-utils.workspace = true
5250
test-fixture.workspace = true
53-
sourcegen.workspace = true
5451

5552
[lints]
5653
workspace = true

crates/ide-db/src/generated/lints.rs

+331-89
Large diffs are not rendered by default.

crates/ide-db/src/lib.rs

-6
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,3 @@ impl SnippetCap {
412412
}
413413
}
414414
}
415-
416-
#[cfg(test)]
417-
mod tests {
418-
mod line_index;
419-
mod sourcegen_lints;
420-
}

crates/ide-db/src/tests/line_index.rs

-49
This file was deleted.

crates/ide-diagnostics/Cargo.toml

-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ expect-test = "1.4.0"
3333
# local deps
3434
test-utils.workspace = true
3535
test-fixture.workspace = true
36-
sourcegen.workspace = true
37-
38-
[features]
39-
in-rust-tree = []
4036

4137
[lints]
4238
workspace = true

crates/ide-diagnostics/src/tests.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
#![allow(clippy::print_stderr)]
2-
#[cfg(not(feature = "in-rust-tree"))]
3-
mod sourcegen;
42

53
use ide_db::{
64
assists::AssistResolveStrategy, base_db::SourceDatabaseExt, LineIndexDatabase, RootDatabase,

crates/ide/Cargo.toml

-3
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,5 @@ expect-test = "1.4.0"
5151
test-utils.workspace = true
5252
test-fixture.workspace = true
5353

54-
[features]
55-
in-rust-tree = ["ide-assists/in-rust-tree", "ide-diagnostics/in-rust-tree"]
56-
5754
[lints]
5855
workspace = true

crates/ide/src/hover/tests.rs

+52-2
Original file line numberDiff line numberDiff line change
@@ -5434,13 +5434,62 @@ fn hover_feature() {
54345434
54355435
The tracking issue for this feature is: None.
54365436
5437-
Intrinsics are never intended to be stable directly, but intrinsics are often
5437+
Intrinsics are rarely intended to be stable directly, but are usually
54385438
exported in some sort of stable manner. Prefer using the stable interfaces to
54395439
the intrinsic directly when you can.
54405440
54415441
------------------------
54425442
54435443
5444+
## Intrinsics with fallback logic
5445+
5446+
Many intrinsics can be written in pure rust, albeit inefficiently or without supporting
5447+
some features that only exist on some backends. Backends can simply not implement those
5448+
intrinsics without causing any code miscompilations or failures to compile.
5449+
All intrinsic fallback bodies are automatically made cross-crate inlineable (like `#[inline]`)
5450+
by the codegen backend, but not the MIR inliner.
5451+
5452+
```rust
5453+
#![feature(rustc_attrs, effects)]
5454+
#![allow(internal_features)]
5455+
5456+
#[rustc_intrinsic]
5457+
const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
5458+
```
5459+
5460+
Since these are just regular functions, it is perfectly ok to create the intrinsic twice:
5461+
5462+
```rust
5463+
#![feature(rustc_attrs, effects)]
5464+
#![allow(internal_features)]
5465+
5466+
#[rustc_intrinsic]
5467+
const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
5468+
5469+
mod foo {
5470+
#[rustc_intrinsic]
5471+
const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {
5472+
panic!("noisy const dealloc")
5473+
}
5474+
}
5475+
5476+
```
5477+
5478+
The behaviour on backends that override the intrinsic is exactly the same. On other
5479+
backends, the intrinsic behaviour depends on which implementation is called, just like
5480+
with any regular function.
5481+
5482+
## Intrinsics lowered to MIR instructions
5483+
5484+
Various intrinsics have native MIR operations that they correspond to. Instead of requiring
5485+
backends to implement both the intrinsic and the MIR operation, the `lower_intrinsics` pass
5486+
will convert the calls to the MIR operation. Backends do not need to know about these intrinsics
5487+
at all.
5488+
5489+
## Intrinsics without fallback logic
5490+
5491+
These must be implemented by all backends.
5492+
54445493
These are imported as if they were FFI functions, with the special
54455494
`rust-intrinsic` ABI. For example, if one was in a freestanding
54465495
context, but wished to be able to `transmute` between types, and
@@ -5459,7 +5508,8 @@ fn hover_feature() {
54595508
}
54605509
```
54615510
5462-
As with any other FFI functions, these are always `unsafe` to call.
5511+
As with any other FFI functions, these are by default always `unsafe` to call.
5512+
You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call.
54635513
54645514
"#]],
54655515
)

crates/rust-analyzer/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ force-always-assert = ["always-assert/force"]
8585
sysroot-abi = []
8686
in-rust-tree = [
8787
"sysroot-abi",
88-
"ide/in-rust-tree",
8988
"syntax/in-rust-tree",
9089
"parser/in-rust-tree",
9190
"hir/in-rust-tree",

lib/line-index/Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,8 @@ edition = "2021"
1010
text-size = "1.1.1"
1111
nohash-hasher = "0.2.0"
1212

13+
[dev-dependencies]
14+
oorandom = "11.1.3"
15+
1316
[lints]
14-
workspace = true
17+
workspace = true

lib/line-index/src/tests.rs

+53
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,56 @@ fn test_to_wide() {
142142
let wide_line_col = line_index.to_wide(WideEncoding::Utf16, line_col.unwrap());
143143
assert_eq!(wide_line_col, Some(WideLineCol { line: 5, col: 4 }));
144144
}
145+
146+
#[test]
147+
fn test_every_chars() {
148+
let text: String = {
149+
let mut chars: Vec<char> = ((0 as char)..char::MAX).collect(); // Neat!
150+
chars.extend("\n".repeat(chars.len() / 16).chars());
151+
let seed = std::hash::Hasher::finish(&std::hash::BuildHasher::build_hasher(
152+
#[allow(clippy::disallowed_types)]
153+
&std::collections::hash_map::RandomState::new(),
154+
));
155+
let mut rng = oorandom::Rand32::new(seed);
156+
let mut rand_index = |i| rng.rand_range(0..i as u32) as usize;
157+
let mut remaining = chars.len() - 1;
158+
while remaining > 0 {
159+
let index = rand_index(remaining);
160+
chars.swap(remaining, index);
161+
remaining -= 1;
162+
}
163+
chars.into_iter().collect()
164+
};
165+
assert!(text.contains('💩')); // Sanity check.
166+
167+
let line_index = LineIndex::new(&text);
168+
169+
let mut lin_col = LineCol { line: 0, col: 0 };
170+
let mut col_utf16 = 0;
171+
let mut col_utf32 = 0;
172+
for (offset, c) in text.char_indices() {
173+
let got_offset = line_index.offset(lin_col).unwrap();
174+
assert_eq!(usize::from(got_offset), offset);
175+
176+
let got_lin_col = line_index.line_col(got_offset);
177+
assert_eq!(got_lin_col, lin_col);
178+
179+
for (enc, col) in [(WideEncoding::Utf16, col_utf16), (WideEncoding::Utf32, col_utf32)] {
180+
let wide_lin_col = line_index.to_wide(enc, lin_col).unwrap();
181+
let got_lin_col = line_index.to_utf8(enc, wide_lin_col).unwrap();
182+
assert_eq!(got_lin_col, lin_col);
183+
assert_eq!(wide_lin_col.col, col)
184+
}
185+
186+
if c == '\n' {
187+
lin_col.line += 1;
188+
lin_col.col = 0;
189+
col_utf16 = 0;
190+
col_utf32 = 0;
191+
} else {
192+
lin_col.col += c.len_utf8() as u32;
193+
col_utf16 += c.len_utf16() as u32;
194+
col_utf32 += 1;
195+
}
196+
}
197+
}

xtask/src/codegen.rs

+7
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,21 @@ use xshell::{cmd, Shell};
88
use crate::{flags, project_root};
99

1010
pub(crate) mod assists_doc_tests;
11+
pub(crate) mod diagnostics_docs;
12+
mod lints;
1113

1214
impl flags::Codegen {
1315
pub(crate) fn run(self, _sh: &Shell) -> anyhow::Result<()> {
1416
match self.codegen_type.unwrap_or_default() {
1517
flags::CodegenType::All => {
18+
diagnostics_docs::generate(self.check);
1619
assists_doc_tests::generate(self.check);
20+
// lints::generate(self.check) Updating clones the rust repo, so don't run it unless
21+
// explicitly asked for
1722
}
1823
flags::CodegenType::AssistsDocTests => assists_doc_tests::generate(self.check),
24+
flags::CodegenType::DiagnosticsDocs => diagnostics_docs::generate(self.check),
25+
flags::CodegenType::LintDefinitions => lints::generate(self.check),
1926
}
2027
Ok(())
2128
}

crates/ide-diagnostics/src/tests/sourcegen.rs renamed to xtask/src/codegen/diagnostics_docs.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,26 @@
22
33
use std::{fmt, fs, io, path::PathBuf};
44

5-
use sourcegen::project_root;
5+
use crate::{
6+
codegen::{add_preamble, list_rust_files, CommentBlock, Location},
7+
project_root,
8+
};
69

7-
#[test]
8-
fn sourcegen_diagnostic_docs() {
10+
pub(crate) fn generate(check: bool) {
911
let diagnostics = Diagnostic::collect().unwrap();
10-
let contents =
11-
diagnostics.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
12-
let contents = sourcegen::add_preamble("sourcegen_diagnostic_docs", contents);
13-
let dst = project_root().join("docs/user/generated_diagnostic.adoc");
14-
fs::write(dst, contents).unwrap();
12+
if !check {
13+
let contents =
14+
diagnostics.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
15+
let contents = add_preamble("sourcegen_diagnostic_docs", contents);
16+
let dst = project_root().join("docs/user/generated_diagnostic.adoc");
17+
fs::write(dst, contents).unwrap();
18+
}
1519
}
1620

1721
#[derive(Debug)]
1822
struct Diagnostic {
1923
id: String,
20-
location: sourcegen::Location,
24+
location: Location,
2125
doc: String,
2226
}
2327

@@ -26,23 +30,23 @@ impl Diagnostic {
2630
let handlers_dir = project_root().join("crates/ide-diagnostics/src/handlers");
2731

2832
let mut res = Vec::new();
29-
for path in sourcegen::list_rust_files(&handlers_dir) {
33+
for path in list_rust_files(&handlers_dir) {
3034
collect_file(&mut res, path)?;
3135
}
3236
res.sort_by(|lhs, rhs| lhs.id.cmp(&rhs.id));
3337
return Ok(res);
3438

3539
fn collect_file(acc: &mut Vec<Diagnostic>, path: PathBuf) -> io::Result<()> {
3640
let text = fs::read_to_string(&path)?;
37-
let comment_blocks = sourcegen::CommentBlock::extract("Diagnostic", &text);
41+
let comment_blocks = CommentBlock::extract("Diagnostic", &text);
3842

3943
for block in comment_blocks {
4044
let id = block.id;
4145
if let Err(msg) = is_valid_diagnostic_name(&id) {
4246
panic!("invalid diagnostic name: {id:?}:\n {msg}")
4347
}
4448
let doc = block.contents.join("\n");
45-
let location = sourcegen::Location { file: path.clone(), line: block.line };
49+
let location = Location { file: path.clone(), line: block.line };
4650
acc.push(Diagnostic { id, location, doc })
4751
}
4852

0 commit comments

Comments
 (0)