Pin toolchain to 1.95.0 + mechanical clippy/rustc fixes
CI was red on every recent main commit (pre-existing, not from the V0.2/audit work): the workflow installs rolling `stable`, which on the runners is ~1 year newer than the local toolchain that validated the code. Under `RUSTFLAGS: -D warnings` + `clippy -- -D warnings`, new rustc/clippy lints across pre-existing code became hard failures. Confirmed identical on the 4 commits before v1.0-rc (e.g. the `rope.rs:1076` unused_parens compile error is byte-identical there). Resolution: - `rust-toolchain.toml` pins channel 1.95.0 (the validated version). The repo directory override makes every cargo invocation use it regardless of what the CI action installs, eliminating the local/CI toolchain-drift class permanently. Bump deliberately. - Mechanical lint fixes (~17 sites, all the trivial/auto-fixable class — no logic change): `cargo clippy --fix` + `cargo fix` applied the machine-applicable set; hand-fixed the residuals: daemon.rs (duplicated #[allow]), completion_framework.rs (sort_by -> sort_by_key/Reverse), attach.rs (map().unwrap_or -> map_or, crdt), buffer.rs (is_some+expect -> match, crdt), m10_11_acceptance.rs (if -> match guard x2, crdt). - `cargo fmt --all` (clippy --fix left overlay_paint.rs unformatted). Verified clean under 1.95.0, all lanes: fmt 0 diffs; clippy --all-targets -D warnings clean for luajit, lua54, AND crdt; -D warnings build clean luajit+lua54; doc tests pass; lib 1223/0; autofix-modified tests (m7_5, m8_1 incl. the Finding-2 fs_watch fix) pass. Scope: this clears CI red class #1 (toolchain-gap lints) only. Independent and still triage-pending: #2 macOS F9 nix PeerCredentials portability (Test (macos-*)), #3 M1/M4/M6 perf/fuzz gates. Per plan, those are triaged after CI confirms #1 green. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
c50db222d3
commit
7171282b57
|
|
@ -0,0 +1,10 @@
|
||||||
|
[toolchain]
|
||||||
|
# Pinned so local == CI permanently. The CI workflow installs the
|
||||||
|
# `stable` channel via dtolnay/rust-toolchain; this directory override
|
||||||
|
# makes every cargo invocation in the repo use the validated version
|
||||||
|
# regardless, eliminating the local/CI toolchain-drift class that
|
||||||
|
# silently red-lined CI under newer rolling-stable lints. Bump
|
||||||
|
# deliberately (its own validated cycle), never implicitly.
|
||||||
|
channel = "1.95.0"
|
||||||
|
components = ["clippy", "rustfmt"]
|
||||||
|
profile = "minimal"
|
||||||
|
|
@ -803,8 +803,7 @@ pub(crate) fn run_attach_pair(
|
||||||
if matches!(k.kind, KeyEventKind::Press | KeyEventKind::Repeat) {
|
if matches!(k.kind, KeyEventKind::Press | KeyEventKind::Repeat) {
|
||||||
let timestamp_ns = std::time::SystemTime::now()
|
let timestamp_ns = std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.map(|d| u64::try_from(d.as_nanos()).unwrap_or(0))
|
.map_or(0, |d| u64::try_from(d.as_nanos()).unwrap_or(0));
|
||||||
.unwrap_or(0);
|
|
||||||
let pmacs_key = key_from_crossterm(k, assigned_id, timestamp_ns);
|
let pmacs_key = key_from_crossterm(k, assigned_id, timestamp_ns);
|
||||||
|
|
||||||
// T M10.10 Day 3 step 5 Path β — determine
|
// T M10.10 Day 3 step 5 Path β — determine
|
||||||
|
|
@ -985,8 +984,7 @@ fn forward_event<W: Write>(
|
||||||
let _ = KeyModifiers::empty(); // import touch: keeps lint happy if unused
|
let _ = KeyModifiers::empty(); // import touch: keeps lint happy if unused
|
||||||
let timestamp_ns = std::time::SystemTime::now()
|
let timestamp_ns = std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.map(|d| u64::try_from(d.as_nanos()).unwrap_or(0))
|
.map_or(0, |d| u64::try_from(d.as_nanos()).unwrap_or(0));
|
||||||
.unwrap_or(0);
|
|
||||||
let pmacs_key = key_from_crossterm(k, assigned_id, timestamp_ns);
|
let pmacs_key = key_from_crossterm(k, assigned_id, timestamp_ns);
|
||||||
write_message(writer, &FrontendEvent::Key(pmacs_key))?;
|
write_message(writer, &FrontendEvent::Key(pmacs_key))?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -322,11 +322,11 @@ mod tests {
|
||||||
let mut s = BackoffSchedule::new();
|
let mut s = BackoffSchedule::new();
|
||||||
let expected = [
|
let expected = [
|
||||||
Duration::from_millis(500),
|
Duration::from_millis(500),
|
||||||
Duration::from_millis(1000),
|
Duration::from_secs(1),
|
||||||
Duration::from_millis(2000),
|
Duration::from_secs(2),
|
||||||
Duration::from_millis(4000),
|
Duration::from_secs(4),
|
||||||
Duration::from_millis(8000),
|
Duration::from_secs(8),
|
||||||
Duration::from_millis(16000),
|
Duration::from_secs(16),
|
||||||
Duration::from_secs(30),
|
Duration::from_secs(30),
|
||||||
];
|
];
|
||||||
for (i, &want) in expected.iter().enumerate() {
|
for (i, &want) in expected.iter().enumerate() {
|
||||||
|
|
@ -366,7 +366,7 @@ mod tests {
|
||||||
|
|
||||||
s.reset();
|
s.reset();
|
||||||
assert_eq!(s.next_delay(), Duration::from_millis(500));
|
assert_eq!(s.next_delay(), Duration::from_millis(500));
|
||||||
assert_eq!(s.next_delay(), Duration::from_millis(1000));
|
assert_eq!(s.next_delay(), Duration::from_secs(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -1050,10 +1050,9 @@ impl Buffer {
|
||||||
let (lossy_owned, captured_crdt_op): (
|
let (lossy_owned, captured_crdt_op): (
|
||||||
Option<Vec<u8>>,
|
Option<Vec<u8>>,
|
||||||
Option<Box<crate::rope::CrdtOp>>,
|
Option<Box<crate::rope::CrdtOp>>,
|
||||||
) = if self.crdt.is_some() && !is_no_op_edit(current) {
|
) = match (&self.crdt, is_no_op_edit(current)) {
|
||||||
Self::apply_to_crdt_then_normalize_bytes(self.crdt.as_ref().expect("checked"), current)?
|
(Some(crdt), false) => Self::apply_to_crdt_then_normalize_bytes(crdt, current)?,
|
||||||
} else {
|
_ => (None, None),
|
||||||
(None, None)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Stage 2: rope edit. In CRDT mode, the EditOp's byte payload
|
// Stage 2: rope edit. In CRDT mode, the EditOp's byte payload
|
||||||
|
|
|
||||||
|
|
@ -295,7 +295,7 @@ impl CompletionRegistry {
|
||||||
// the highest-priority hit.
|
// the highest-priority hit.
|
||||||
let mut order: Vec<&RegisteredProvider> =
|
let mut order: Vec<&RegisteredProvider> =
|
||||||
self.providers.iter().filter(|p| p.enabled).collect();
|
self.providers.iter().filter(|p| p.enabled).collect();
|
||||||
order.sort_by(|a, b| b.priority.cmp(&a.priority));
|
order.sort_by_key(|p| std::cmp::Reverse(p.priority));
|
||||||
|
|
||||||
let mut by_key: HashMap<(String, String), usize> = HashMap::new();
|
let mut by_key: HashMap<(String, String), usize> = HashMap::new();
|
||||||
let mut out: Vec<CompletionCandidate> = Vec::new();
|
let mut out: Vec<CompletionCandidate> = Vec::new();
|
||||||
|
|
|
||||||
|
|
@ -798,7 +798,6 @@ fn per_attach_thread(
|
||||||
clippy::needless_pass_by_value,
|
clippy::needless_pass_by_value,
|
||||||
clippy::too_many_lines
|
clippy::too_many_lines
|
||||||
)]
|
)]
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
|
||||||
fn dispatcher_loop(
|
fn dispatcher_loop(
|
||||||
dispatcher_rx: mpsc::Receiver<DispatcherEvent>,
|
dispatcher_rx: mpsc::Receiver<DispatcherEvent>,
|
||||||
editor: &mut EditorState,
|
editor: &mut EditorState,
|
||||||
|
|
|
||||||
|
|
@ -939,7 +939,7 @@ mod tests {
|
||||||
let msg = format!("{err}");
|
let msg = format!("{err}");
|
||||||
assert!(msg.contains("/usr/local/bin/pmacs"));
|
assert!(msg.contains("/usr/local/bin/pmacs"));
|
||||||
assert!(msg.contains("permission denied"));
|
assert!(msg.contains("permission denied"));
|
||||||
assert!(msg.contains("PATH"), "should hint at PATH check: {msg}",);
|
assert!(msg.contains("PATH"), "should hint at PATH check: {msg}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// F8 reproduction (M10.11 acceptance criterion 1, SSH transport).
|
/// F8 reproduction (M10.11 acceptance criterion 1, SSH transport).
|
||||||
|
|
@ -1017,7 +1017,7 @@ mod tests {
|
||||||
.set_read_timeout(Some(Duration::from_secs(3)))
|
.set_read_timeout(Some(Duration::from_secs(3)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
match output_reader.read_exact(&mut received) {
|
match output_reader.read_exact(&mut received) {
|
||||||
Ok(()) => assert_eq!(received, HELLO_FRAME, "Hello bytes corrupted in transit",),
|
Ok(()) => assert_eq!(received, HELLO_FRAME, "Hello bytes corrupted in transit"),
|
||||||
Err(e) => panic!(
|
Err(e) => panic!(
|
||||||
"F8 reproduced: Hello never reached local output ({e}) — \
|
"F8 reproduced: Hello never reached local output ({e}) — \
|
||||||
the bridge dropped the daemon→client direction on \
|
the bridge dropped the daemon→client direction on \
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ impl EditorCore {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn active_buffer_len(&self) -> u64 {
|
pub fn active_buffer_len(&self) -> u64 {
|
||||||
let id = self.active_buffer_id();
|
let id = self.active_buffer_id();
|
||||||
self.registry.borrow().get(id).map(Buffer::len).unwrap_or(0)
|
self.registry.borrow().get(id).map_or(0, Buffer::len)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Active buffer's name. Returns an owned String to release the
|
/// Active buffer's name. Returns an owned String to release the
|
||||||
|
|
|
||||||
|
|
@ -169,8 +169,7 @@ fn temp_sibling(target: &Path) -> PathBuf {
|
||||||
// and `create_new` would error if hit.
|
// and `create_new` would error if hit.
|
||||||
let nanos = SystemTime::now()
|
let nanos = SystemTime::now()
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
.map(|d| d.subsec_nanos())
|
.map_or(0, |d| d.subsec_nanos());
|
||||||
.unwrap_or(0);
|
|
||||||
name.push(format!("{nanos:x}"));
|
name.push(format!("{nanos:x}"));
|
||||||
parent.join(name)
|
parent.join(name)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -249,21 +249,19 @@ fn paint_selection_in_window(
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
match (disp.row as usize).checked_sub(window.view_top) {
|
match (disp.row as usize).checked_sub(window.view_top) {
|
||||||
Some(r) if r < inner_rows as usize => {
|
Some(r) if r < inner_rows as usize && disp.col < rect.size.cols => {
|
||||||
if disp.col < rect.size.cols {
|
let grid_row = rect.origin.row + r as u32;
|
||||||
let grid_row = rect.origin.row + r as u32;
|
let grid_col = rect.origin.col + disp.col;
|
||||||
let grid_col = rect.origin.col + disp.col;
|
if grid_row < grid.size.rows && grid_col < grid.size.cols {
|
||||||
if grid_row < grid.size.rows && grid_col < grid.size.cols {
|
let cell = grid.at(CellCoord::new(grid_row, grid_col));
|
||||||
let cell = grid.at(CellCoord::new(grid_row, grid_col));
|
cell.style.underline = UnderlineStyle::Single;
|
||||||
cell.style.underline = UnderlineStyle::Single;
|
// Use the source's color for the underline; if
|
||||||
// Use the source's color for the underline; if
|
// the cell already has a foreground style, the
|
||||||
// the cell already has a foreground style, the
|
// underline color comes from the fg. We don't
|
||||||
// underline color comes from the fg. We don't
|
// override fg to preserve the cell's existing
|
||||||
// override fg to preserve the cell's existing
|
// glyph appearance.
|
||||||
// glyph appearance.
|
if cell.style.fg == Color::Default {
|
||||||
if cell.style.fg == Color::Default {
|
cell.style.fg = color;
|
||||||
cell.style.fg = color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1073,7 +1073,7 @@ mod tests {
|
||||||
let pos = (rng() as usize) % (len + 1);
|
let pos = (rng() as usize) % (len + 1);
|
||||||
let n = (rng() % 64 + 1) as usize;
|
let n = (rng() % 64 + 1) as usize;
|
||||||
let bytes: Vec<u8> = (0..n)
|
let bytes: Vec<u8> = (0..n)
|
||||||
.map(|i| ((rng() as u8).wrapping_add(i as u8)))
|
.map(|i| (rng() as u8).wrapping_add(i as u8))
|
||||||
.collect();
|
.collect();
|
||||||
rope = rope.insert(pos as u64, &bytes).unwrap().new_rope;
|
rope = rope.insert(pos as u64, &bytes).unwrap().new_rope;
|
||||||
reference.splice(pos..pos, bytes);
|
reference.splice(pos..pos, bytes);
|
||||||
|
|
|
||||||
|
|
@ -252,17 +252,15 @@ impl Observer {
|
||||||
InstanceMessage::BufferSnapshot {
|
InstanceMessage::BufferSnapshot {
|
||||||
buffer_id,
|
buffer_id,
|
||||||
crdt_snapshot,
|
crdt_snapshot,
|
||||||
} => {
|
} if !self.replicas.contains_key(&buffer_id) => {
|
||||||
// Bootstrap each buffer's replica on first
|
// Bootstrap each buffer's replica on first
|
||||||
// BufferSnapshot for that BufferId. Later snapshots
|
// BufferSnapshot for that BufferId. Later snapshots
|
||||||
// for the same buffer are ignored — the established
|
// for the same buffer are ignored — the established
|
||||||
// replica catches up via CrdtOps.
|
// replica catches up via CrdtOps.
|
||||||
if !self.replicas.contains_key(&buffer_id) {
|
let r = CrdtState::new(self.frontend_id.0).expect("observer CrdtState::new");
|
||||||
let r = CrdtState::new(self.frontend_id.0).expect("observer CrdtState::new");
|
r.import_snapshot(&crdt_snapshot)
|
||||||
r.import_snapshot(&crdt_snapshot)
|
.expect("observer import_snapshot");
|
||||||
.expect("observer import_snapshot");
|
self.replicas.insert(buffer_id, r);
|
||||||
self.replicas.insert(buffer_id, r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
InstanceMessage::CrdtOp { buffer_id, op } => {
|
InstanceMessage::CrdtOp { buffer_id, op } => {
|
||||||
// If we received a CrdtOp for a buffer whose snapshot
|
// If we received a CrdtOp for a buffer whose snapshot
|
||||||
|
|
@ -279,10 +277,10 @@ impl Observer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InstanceMessage::PresenceUpdate { frontend_id, .. } => {
|
InstanceMessage::PresenceUpdate { frontend_id, .. }
|
||||||
if frontend_id != self.frontend_id {
|
if frontend_id != self.frontend_id =>
|
||||||
self.other_frontends.insert(frontend_id);
|
{
|
||||||
}
|
self.other_frontends.insert(frontend_id);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,7 @@ fn make_branched_package(name: &str) -> (TempDir, PathBuf, String) {
|
||||||
]);
|
]);
|
||||||
std::fs::write(
|
std::fs::write(
|
||||||
work.join("init.lua"),
|
work.join("init.lua"),
|
||||||
format!("return {{ name = '{name}', version = '1.0.0', flavor = 'feature' }}\n",),
|
format!("return {{ name = '{name}', version = '1.0.0', flavor = 'feature' }}\n"),
|
||||||
)
|
)
|
||||||
.expect("write init.lua feature");
|
.expect("write init.lua feature");
|
||||||
run_git(&[
|
run_git(&[
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ fn read_dir_returns_one_entry_per_child_with_lstat_metadata() {
|
||||||
if let Ok(err) = entries.get::<String>("error") {
|
if let Ok(err) = entries.get::<String>("error") {
|
||||||
panic!("read_dir errored: {err}");
|
panic!("read_dir errored: {err}");
|
||||||
}
|
}
|
||||||
let len: usize = entries.len().map(|n| n as usize).unwrap_or(0);
|
let len: usize = entries.len().map_or(0, |n| n as usize);
|
||||||
assert_eq!(len, 3, "expected 3 entries, got {len}");
|
assert_eq!(len, 3, "expected 3 entries, got {len}");
|
||||||
|
|
||||||
// Names are filesystem-iteration-ordered; gather and sort.
|
// Names are filesystem-iteration-ordered; gather and sort.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue