chore: upgrade to Rust 1.89 (#2465)

Codex created this PR from the following prompt:

> upgrade this entire repo to Rust 1.89. Note that this requires
updating codex-rs/rust-toolchain.toml as well as the workflows in
.github/. Make sure that things are "clippy clean" as this change will
likely uncover new Clippy errors. `just fmt` and `cargo clippy --tests`
are sufficient to check for correctness

Note this modifies a lot of lines because it folds nested `if`
statements using `&&`.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/2465).
* #2467
* __->__ #2465
This commit is contained in:
Michael Bolin
2025-08-19 13:22:02 -07:00
committed by GitHub
parent aafa00dbe0
commit 50c48e88f5
37 changed files with 504 additions and 521 deletions

View File

@@ -33,10 +33,10 @@ impl ApprovalModalView<'_> {
/// Advance to next request if the current one is finished.
fn maybe_advance(&mut self) {
if self.current.is_complete() {
if let Some(req) = self.queue.pop() {
self.current = UserApprovalWidget::new(req, self.app_event_tx.clone());
}
if self.current.is_complete()
&& let Some(req) = self.queue.pop()
{
self.current = UserApprovalWidget::new(req, self.app_event_tx.clone());
}
}
}

View File

@@ -1575,53 +1575,53 @@ mod tests {
}
14 => {
// Try inserting inside an existing element (should clamp to boundary)
if let Some(payload) = elem_texts.choose(&mut rng).cloned() {
if let Some(start) = ta.text().find(&payload) {
let end = start + payload.len();
if end - start > 2 {
let pos = rng.random_range(start + 1..end - 1);
let ins = rand_grapheme(&mut rng);
ta.insert_str_at(pos, &ins);
}
if let Some(payload) = elem_texts.choose(&mut rng).cloned()
&& let Some(start) = ta.text().find(&payload)
{
let end = start + payload.len();
if end - start > 2 {
let pos = rng.random_range(start + 1..end - 1);
let ins = rand_grapheme(&mut rng);
ta.insert_str_at(pos, &ins);
}
}
}
15 => {
// Replace a range that intersects an element -> whole element should be replaced
if let Some(payload) = elem_texts.choose(&mut rng).cloned() {
if let Some(start) = ta.text().find(&payload) {
let end = start + payload.len();
// Create an intersecting range [start-δ, end-δ2)
let mut s = start.saturating_sub(rng.random_range(0..=2));
let mut e = (end + rng.random_range(0..=2)).min(ta.text().len());
// Align to char boundaries to satisfy String::replace_range contract
let txt = ta.text();
while s > 0 && !txt.is_char_boundary(s) {
s -= 1;
}
while e < txt.len() && !txt.is_char_boundary(e) {
e += 1;
}
if s < e {
// Small replacement text
let mut srep = String::new();
for _ in 0..rng.random_range(0..=2) {
srep.push_str(&rand_grapheme(&mut rng));
}
ta.replace_range(s..e, &srep);
if let Some(payload) = elem_texts.choose(&mut rng).cloned()
&& let Some(start) = ta.text().find(&payload)
{
let end = start + payload.len();
// Create an intersecting range [start-δ, end-δ2)
let mut s = start.saturating_sub(rng.random_range(0..=2));
let mut e = (end + rng.random_range(0..=2)).min(ta.text().len());
// Align to char boundaries to satisfy String::replace_range contract
let txt = ta.text();
while s > 0 && !txt.is_char_boundary(s) {
s -= 1;
}
while e < txt.len() && !txt.is_char_boundary(e) {
e += 1;
}
if s < e {
// Small replacement text
let mut srep = String::new();
for _ in 0..rng.random_range(0..=2) {
srep.push_str(&rand_grapheme(&mut rng));
}
ta.replace_range(s..e, &srep);
}
}
}
16 => {
// Try setting the cursor to a position inside an element; it should clamp out
if let Some(payload) = elem_texts.choose(&mut rng).cloned() {
if let Some(start) = ta.text().find(&payload) {
let end = start + payload.len();
if end - start > 2 {
let pos = rng.random_range(start + 1..end - 1);
ta.set_cursor(pos);
}
if let Some(payload) = elem_texts.choose(&mut rng).cloned()
&& let Some(start) = ta.text().find(&payload)
{
let end = start + payload.len();
if end - start > 2 {
let pos = rng.random_range(start + 1..end - 1);
ta.set_cursor(pos);
}
}
}

View File

@@ -339,18 +339,18 @@ async fn binary_size_transcript_matches_ideal_fixture() {
}
}
"app_event" => {
if let Some(variant) = v.get("variant").and_then(|s| s.as_str()) {
if variant == "CommitTick" {
chat.on_commit_tick();
while let Ok(app_ev) = rx.try_recv() {
if let AppEvent::InsertHistory(lines) = app_ev {
transcript.push_str(&lines_to_single_string(&lines));
crate::insert_history::insert_history_lines_to_writer(
&mut terminal,
&mut ansi,
lines,
);
}
if let Some(variant) = v.get("variant").and_then(|s| s.as_str())
&& variant == "CommitTick"
{
chat.on_commit_tick();
while let Ok(app_ev) = rx.try_recv() {
if let AppEvent::InsertHistory(lines) = app_ev {
transcript.push_str(&lines_to_single_string(&lines));
crate::insert_history::insert_history_lines_to_writer(
&mut terminal,
&mut ansi,
lines,
);
}
}
}

View File

@@ -264,10 +264,10 @@ where
#[allow(clippy::print_stderr)]
fn drop(&mut self) {
// Attempt to restore the cursor state
if self.hidden_cursor {
if let Err(err) = self.show_cursor() {
eprintln!("Failed to show the cursor: {err}");
}
if self.hidden_cursor
&& let Err(err) = self.show_cursor()
{
eprintln!("Failed to show the cursor: {err}");
}
}
}
@@ -309,7 +309,7 @@ where
}
/// Get a Frame object which provides a consistent view into the terminal state for rendering.
pub fn get_frame(&mut self) -> Frame {
pub fn get_frame(&mut self) -> Frame<'_> {
let count = self.frame_count;
Frame {
cursor_position: None,

View File

@@ -33,10 +33,10 @@ where
return None;
}
if let Some(home_dir) = std::env::var_os("HOME").map(PathBuf::from) {
if let Ok(rel) = path.strip_prefix(&home_dir) {
return Some(rel.to_path_buf());
}
if let Some(home_dir) = std::env::var_os("HOME").map(PathBuf::from)
&& let Ok(rel) = path.strip_prefix(&home_dir)
{
return Some(rel.to_path_buf());
}
None

View File

@@ -94,13 +94,13 @@ impl FileSearchManager {
// If there is an in-flight search that is definitely obsolete,
// cancel it now.
if let Some(active_search) = &st.active_search {
if !query.starts_with(&active_search.query) {
active_search
.cancellation_token
.store(true, Ordering::Relaxed);
st.active_search = None;
}
if let Some(active_search) = &st.active_search
&& !query.starts_with(&active_search.query)
{
active_search
.cancellation_token
.store(true, Ordering::Relaxed);
st.active_search = None;
}
// Schedule a search to run after debounce.
@@ -187,10 +187,10 @@ impl FileSearchManager {
{
#[expect(clippy::unwrap_used)]
let mut st = search_state.lock().unwrap();
if let Some(active_search) = &st.active_search {
if Arc::ptr_eq(&active_search.cancellation_token, &cancellation_token) {
st.active_search = None;
}
if let Some(active_search) = &st.active_search
&& Arc::ptr_eq(&active_search.cancellation_token, &cancellation_token)
{
st.active_search = None;
}
}
});

View File

@@ -541,33 +541,33 @@ pub(crate) fn new_status_output(
// 👤 Account (only if ChatGPT tokens exist), shown under the first block
let auth_file = get_auth_file(&config.codex_home);
if let Ok(auth) = try_read_auth_json(&auth_file) {
if let Some(tokens) = auth.tokens.clone() {
lines.push(Line::from(vec!["👤 ".into(), "Account".bold()]));
lines.push(Line::from(" • Signed in with ChatGPT"));
if let Ok(auth) = try_read_auth_json(&auth_file)
&& let Some(tokens) = auth.tokens.clone()
{
lines.push(Line::from(vec!["👤 ".into(), "Account".bold()]));
lines.push(Line::from(" • Signed in with ChatGPT"));
let info = tokens.id_token;
if let Some(email) = &info.email {
lines.push(Line::from(vec![" • Login: ".into(), email.clone().into()]));
}
match auth.openai_api_key.as_deref() {
Some(key) if !key.is_empty() => {
lines.push(Line::from(
" • Using API key. Run codex login to use ChatGPT plan",
));
}
_ => {
let plan_text = info
.get_chatgpt_plan_type()
.map(|s| title_case(&s))
.unwrap_or_else(|| "Unknown".to_string());
lines.push(Line::from(vec![" • Plan: ".into(), plan_text.into()]));
}
}
lines.push(Line::from(""));
let info = tokens.id_token;
if let Some(email) = &info.email {
lines.push(Line::from(vec![" • Login: ".into(), email.clone().into()]));
}
match auth.openai_api_key.as_deref() {
Some(key) if !key.is_empty() => {
lines.push(Line::from(
" • Using API key. Run codex login to use ChatGPT plan",
));
}
_ => {
let plan_text = info
.get_chatgpt_plan_type()
.map(|s| title_case(&s))
.unwrap_or_else(|| "Unknown".to_string());
lines.push(Line::from(vec![" • Plan: ".into(), plan_text.into()]));
}
}
lines.push(Line::from(""));
}
// 🧠 Model
@@ -612,10 +612,10 @@ pub(crate) fn new_status_output(
" • Input: ".into(),
usage.non_cached_input().to_string().into(),
];
if let Some(cached) = usage.cached_input_tokens {
if cached > 0 {
input_line_spans.push(format!(" (+ {cached} cached)").into());
}
if let Some(cached) = usage.cached_input_tokens
&& cached > 0
{
input_line_spans.push(format!(" (+ {cached} cached)").into());
}
lines.push(Line::from(input_line_spans));
// Output: <output>
@@ -688,16 +688,15 @@ pub(crate) fn new_mcp_tools_output(
]));
}
if let Some(env) = cfg.env.as_ref() {
if !env.is_empty() {
let mut env_pairs: Vec<String> =
env.iter().map(|(k, v)| format!("{k}={v}")).collect();
env_pairs.sort();
lines.push(Line::from(vec![
" • Env: ".into(),
env_pairs.join(" ").into(),
]));
}
if let Some(env) = cfg.env.as_ref()
&& !env.is_empty()
{
let mut env_pairs: Vec<String> = env.iter().map(|(k, v)| format!("{k}={v}")).collect();
env_pairs.sort();
lines.push(Line::from(vec![
" • Env: ".into(),
env_pairs.join(" ").into(),
]));
}
if names.is_empty() {

View File

@@ -123,20 +123,20 @@ impl AuthModeWidget {
// If the user is already authenticated but the method differs from their
// preferred auth method, show a brief explanation.
if let LoginStatus::AuthMode(current) = self.login_status {
if current != self.preferred_auth_method {
let to_label = |mode: AuthMode| match mode {
AuthMode::ApiKey => "API key",
AuthMode::ChatGPT => "ChatGPT",
};
let msg = format!(
" Youre currently using {} while your preferred method is {}.",
to_label(current),
to_label(self.preferred_auth_method)
);
lines.push(Line::from(msg).style(Style::default()));
lines.push(Line::from(""));
}
if let LoginStatus::AuthMode(current) = self.login_status
&& current != self.preferred_auth_method
{
let to_label = |mode: AuthMode| match mode {
AuthMode::ApiKey => "API key",
AuthMode::ChatGPT => "ChatGPT",
};
let msg = format!(
" Youre currently using {} while your preferred method is {}.",
to_label(current),
to_label(self.preferred_auth_method)
);
lines.push(Line::from(msg).style(Style::default()));
lines.push(Line::from(""));
}
let create_mode_item = |idx: usize,
@@ -222,15 +222,15 @@ impl AuthModeWidget {
spans.extend(shimmer_spans("Finish signing in via your browser"));
let mut lines = vec![Line::from(spans), Line::from("")];
if let SignInState::ChatGptContinueInBrowser(state) = &self.sign_in_state {
if !state.auth_url.is_empty() {
lines.push(Line::from(" If the link doesn't open automatically, open the following link to authenticate:"));
lines.push(Line::from(vec![
Span::raw(" "),
state.auth_url.as_str().cyan().underlined(),
]));
lines.push(Line::from(""));
}
if let SignInState::ChatGptContinueInBrowser(state) = &self.sign_in_state
&& !state.auth_url.is_empty()
{
lines.push(Line::from(" If the link doesn't open automatically, open the following link to authenticate:"));
lines.push(Line::from(vec![
Span::raw(" "),
state.auth_url.as_str().cyan().underlined(),
]));
lines.push(Line::from(""));
}
lines.push(

View File

@@ -96,26 +96,26 @@ impl StreamController {
/// Begin a stream, flushing previously completed lines from any other
/// active stream to maintain ordering.
pub(crate) fn begin(&mut self, kind: StreamKind, sink: &impl HistorySink) {
if let Some(current) = self.current_stream {
if current != kind {
// Synchronously flush completed lines from previous stream.
let cfg = self.config.clone();
let prev_state = self.state_mut(current);
let newly_completed = prev_state.collector.commit_complete_lines(&cfg);
if !newly_completed.is_empty() {
prev_state.enqueue(newly_completed);
}
let step = prev_state.drain_all();
if !step.history.is_empty() {
let mut lines: Lines = Vec::new();
self.emit_header_if_needed(current, &mut lines);
lines.extend(step.history);
// Ensure at most one trailing blank after the flushed block.
Self::ensure_single_trailing_blank(&mut lines);
sink.insert_history(lines);
}
self.current_stream = None;
if let Some(current) = self.current_stream
&& current != kind
{
// Synchronously flush completed lines from previous stream.
let cfg = self.config.clone();
let prev_state = self.state_mut(current);
let newly_completed = prev_state.collector.commit_complete_lines(&cfg);
if !newly_completed.is_empty() {
prev_state.enqueue(newly_completed);
}
let step = prev_state.drain_all();
if !step.history.is_empty() {
let mut lines: Lines = Vec::new();
self.emit_header_if_needed(current, &mut lines);
lines.extend(step.history);
// Ensure at most one trailing blank after the flushed block.
Self::ensure_single_trailing_blank(&mut lines);
sink.insert_history(lines);
}
self.current_stream = None;
}
if self.current_stream != Some(kind) {

View File

@@ -53,12 +53,12 @@ pub(crate) fn format_json_compact(text: &str) -> Option<String> {
}
' ' | '\t' if !in_string => {
// Add a space after : and , but only when not in a string
if let Some(&next_ch) = chars.peek() {
if let Some(last_ch) = result.chars().last() {
if (last_ch == ':' || last_ch == ',') && !matches!(next_ch, '}' | ']') {
result.push(' ');
}
}
if let Some(&next_ch) = chars.peek()
&& let Some(last_ch) = result.chars().last()
&& (last_ch == ':' || last_ch == ',')
&& !matches!(next_ch, '}' | ']')
{
result.push(' ');
}
}
_ => {