From 196e4befba350f95c5aa4d3b82911af8a7e23b04 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Fri, 16 May 2025 09:19:55 +0200 Subject: [PATCH] Update MSRV to 1.85 and toolchain to 1.87 (#18126) --- Cargo.toml | 3 +- crates/ruff_db/src/source.rs | 4 +- crates/ruff_db/src/system/memory_fs.rs | 6 +-- crates/ruff_formatter/src/builders.rs | 22 +++++----- crates/ruff_formatter/src/printer/mod.rs | 6 +-- crates/ruff_linter/src/linter.rs | 4 +- .../rules/hardcoded_sql_expression.rs | 2 +- .../src/rules/ruff/rules/sort_dunder_slots.rs | 2 +- crates/ruff_linter/src/source_kind.rs | 40 +++++++++++++++++-- crates/ruff_linter/src/test.rs | 2 +- .../src/expression/parentheses.rs | 2 +- .../src/statement/stmt_assign.rs | 10 ++--- .../src/analyze/typing.rs | 8 +--- crates/ruff_server/src/session/index.rs | 2 +- .../src/session/index/ruff_settings.rs | 10 ++--- crates/ruff_server/src/session/settings.rs | 8 ++-- .../ty_python_semantic/src/site_packages.rs | 2 +- crates/ty_python_semantic/src/types.rs | 1 - rust-toolchain.toml | 2 +- 19 files changed, 82 insertions(+), 54 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 27c02132d4..2704d59a46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ resolver = "2" [workspace.package] edition = "2021" -rust-version = "1.84" +rust-version = "1.85" homepage = "https://docs.astral.sh/ruff" documentation = "https://docs.astral.sh/ruff" repository = "https://github.com/astral-sh/ruff" @@ -215,6 +215,7 @@ similar_names = "allow" single_match_else = "allow" too_many_lines = "allow" needless_continue = "allow" # An explicit continue can be more readable, especially if the alternative is an empty block. +unnecessary_debug_formatting = "allow" # too many instances, the display also doesn't quote the path which is often desired in logs where we use them the most often. # Without the hashes we run into a `rustfmt` bug in some snapshot tests, see #13250 needless_raw_string_hashes = "allow" # Disallowed restriction lints diff --git a/crates/ruff_db/src/source.rs b/crates/ruff_db/src/source.rs index 6d7d915751..5e4f15cff1 100644 --- a/crates/ruff_db/src/source.rs +++ b/crates/ruff_db/src/source.rs @@ -133,7 +133,7 @@ struct SourceTextInner { #[derive(Eq, PartialEq)] enum SourceTextKind { Text(String), - Notebook(Notebook), + Notebook(Box), } impl From for SourceTextKind { @@ -144,7 +144,7 @@ impl From for SourceTextKind { impl From for SourceTextKind { fn from(notebook: Notebook) -> Self { - SourceTextKind::Notebook(notebook) + SourceTextKind::Notebook(Box::new(notebook)) } } diff --git a/crates/ruff_db/src/system/memory_fs.rs b/crates/ruff_db/src/system/memory_fs.rs index f773b53d73..afb9a1a87e 100644 --- a/crates/ruff_db/src/system/memory_fs.rs +++ b/crates/ruff_db/src/system/memory_fs.rs @@ -463,17 +463,17 @@ fn not_found() -> std::io::Error { fn is_a_directory() -> std::io::Error { // Note: Rust returns `ErrorKind::IsADirectory` for this error but this is a nightly only variant :(. // So we have to use other for now. - std::io::Error::new(std::io::ErrorKind::Other, "Is a directory") + std::io::Error::other("Is a directory") } fn not_a_directory() -> std::io::Error { // Note: Rust returns `ErrorKind::NotADirectory` for this error but this is a nightly only variant :(. // So we have to use `Other` for now. - std::io::Error::new(std::io::ErrorKind::Other, "Not a directory") + std::io::Error::other("Not a directory") } fn directory_not_empty() -> std::io::Error { - std::io::Error::new(std::io::ErrorKind::Other, "directory not empty") + std::io::Error::other("directory not empty") } fn create_dir_all( diff --git a/crates/ruff_formatter/src/builders.rs b/crates/ruff_formatter/src/builders.rs index 21ab988b5e..a074be5bae 100644 --- a/crates/ruff_formatter/src/builders.rs +++ b/crates/ruff_formatter/src/builders.rs @@ -1388,7 +1388,7 @@ pub fn soft_space_or_block_indent(content: &impl Format) -> Bl pub fn group(content: &impl Format) -> Group { Group { content: Argument::new(content), - group_id: None, + id: None, should_expand: false, } } @@ -1396,14 +1396,14 @@ pub fn group(content: &impl Format) -> Group { #[derive(Copy, Clone)] pub struct Group<'a, Context> { content: Argument<'a, Context>, - group_id: Option, + id: Option, should_expand: bool, } impl Group<'_, Context> { #[must_use] - pub fn with_group_id(mut self, group_id: Option) -> Self { - self.group_id = group_id; + pub fn with_id(mut self, group_id: Option) -> Self { + self.id = group_id; self } @@ -1429,7 +1429,7 @@ impl Format for Group<'_, Context> { }; f.write_element(FormatElement::Tag(StartGroup( - tag::Group::new().with_id(self.group_id).with_mode(mode), + tag::Group::new().with_id(self.id).with_mode(mode), ))); Arguments::from(&self.content).fmt(f)?; @@ -1443,7 +1443,7 @@ impl Format for Group<'_, Context> { impl std::fmt::Debug for Group<'_, Context> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Group") - .field("group_id", &self.group_id) + .field("id", &self.id) .field("should_expand", &self.should_expand) .field("content", &"{{content}}") .finish() @@ -1642,7 +1642,7 @@ impl std::fmt::Debug for BestFitParenthesize<'_, Context> { /// soft_line_break(), /// if_group_breaks(&token(")")) /// ]) -/// .with_group_id(Some(parentheses_id)) +/// .with_id(Some(parentheses_id)) /// .fmt(f) /// }); /// @@ -1991,7 +1991,7 @@ impl IfGroupBreaks<'_, Context> { /// })), /// token("]") /// ], - /// ).with_group_id(Some(group_id)) + /// ).with_id(Some(group_id)) /// ]) /// })])?; /// @@ -2046,7 +2046,7 @@ impl std::fmt::Debug for IfGroupBreaks<'_, Context> { /// let id = f.group_id("head"); /// /// write!(f, [ -/// group(&token("Head")).with_group_id(Some(id)), +/// group(&token("Head")).with_id(Some(id)), /// if_group_breaks(&indent(&token("indented"))).with_group_id(Some(id)), /// if_group_fits_on_line(&token("indented")).with_group_id(Some(id)) /// ]) @@ -2071,7 +2071,7 @@ impl std::fmt::Debug for IfGroupBreaks<'_, Context> { /// let group_id = f.group_id("header"); /// /// write!(f, [ -/// group(&token("(aLongHeaderThatBreaksForSomeReason) =>")).with_group_id(Some(group_id)), +/// group(&token("(aLongHeaderThatBreaksForSomeReason) =>")).with_id(Some(group_id)), /// indent_if_group_breaks(&format_args![hard_line_break(), token("a => b")], group_id) /// ]) /// }); @@ -2101,7 +2101,7 @@ impl std::fmt::Debug for IfGroupBreaks<'_, Context> { /// let group_id = f.group_id("header"); /// /// write!(f, [ -/// group(&token("(aLongHeaderThatBreaksForSomeReason) =>")).with_group_id(Some(group_id)), +/// group(&token("(aLongHeaderThatBreaksForSomeReason) =>")).with_id(Some(group_id)), /// indent_if_group_breaks(&format_args![hard_line_break(), token("a => b")], group_id) /// ]) /// }); diff --git a/crates/ruff_formatter/src/printer/mod.rs b/crates/ruff_formatter/src/printer/mod.rs index 071432500e..f6160ed79a 100644 --- a/crates/ruff_formatter/src/printer/mod.rs +++ b/crates/ruff_formatter/src/printer/mod.rs @@ -2002,7 +2002,7 @@ two lines`, token("The referenced group breaks."), hard_line_break() ]) - .with_group_id(Some(group_id)), + .with_id(Some(group_id)), group(&format_args![ token("This group breaks because:"), soft_line_break_or_space(), @@ -2027,7 +2027,7 @@ two lines`, write!( f, [ - group(&token("Group with id-2")).with_group_id(Some(id_2)), + group(&token("Group with id-2")).with_id(Some(id_2)), hard_line_break() ] )?; @@ -2035,7 +2035,7 @@ two lines`, write!( f, [ - group(&token("Group with id-1 does not fit on the line because it exceeds the line width of 80 characters by")).with_group_id(Some(id_1)), + group(&token("Group with id-1 does not fit on the line because it exceeds the line width of 80 characters by")).with_id(Some(id_1)), hard_line_break() ] )?; diff --git a/crates/ruff_linter/src/linter.rs b/crates/ruff_linter/src/linter.rs index 58c0a3b2ee..12a91a784e 100644 --- a/crates/ruff_linter/src/linter.rs +++ b/crates/ruff_linter/src/linter.rs @@ -940,7 +940,7 @@ mod tests { #[test_case(Path::new("add_missing_cell_id.ipynb"), true; "add_missing_cell_id")] fn test_cell_id(path: &Path, has_id: bool) -> Result<()> { let source_notebook = Notebook::from_path(¬ebook_path(path))?; - let source_kind = SourceKind::IpyNotebook(source_notebook); + let source_kind = SourceKind::ipy_notebook(source_notebook); let (_, transformed) = test_contents( &source_kind, path, @@ -1231,7 +1231,7 @@ mod tests { format!("async_comprehension_in_sync_comprehension_notebook_{python_version}"); let path = Path::new("resources/test/fixtures/syntax_errors/async_comprehension.ipynb"); let messages = test_contents_syntax_errors( - &SourceKind::IpyNotebook(Notebook::from_path(path)?), + &SourceKind::ipy_notebook(Notebook::from_path(path)?), path, &LinterSettings { unresolved_target_version: python_version.into(), diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs index df0effe5e8..6352e05052 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs @@ -198,7 +198,7 @@ fn is_explicit_concatenation(expr: &Expr) -> Option { .iter() .map(is_explicit_concatenation) .collect::>(); - if values.iter().any(|v| *v == Some(true)) { + if values.contains(&Some(true)) { Some(true) } else if values.iter().all(|v| *v == Some(false)) { Some(false) diff --git a/crates/ruff_linter/src/rules/ruff/rules/sort_dunder_slots.rs b/crates/ruff_linter/src/rules/ruff/rules/sort_dunder_slots.rs index fd588bf82f..00e9c755ec 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/sort_dunder_slots.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/sort_dunder_slots.rs @@ -174,7 +174,7 @@ struct StringLiteralDisplay<'a> { /// The elts from the original AST node representing the display. /// Each elt is the AST representation of a single string literal /// element in the display - elts: Cow<'a, Vec>, + elts: Cow<'a, [ast::Expr]>, /// The source-code range of the display as a whole range: TextRange, /// What kind of a display is it? A dict, set, list or tuple? diff --git a/crates/ruff_linter/src/source_kind.rs b/crates/ruff_linter/src/source_kind.rs index f067fe49db..a146d2db13 100644 --- a/crates/ruff_linter/src/source_kind.rs +++ b/crates/ruff_linter/src/source_kind.rs @@ -16,15 +16,47 @@ use colored::Colorize; use crate::fs; use crate::text_helpers::ShowNonprinting; -#[derive(Clone, Debug, PartialEq, is_macro::Is)] +#[derive(Clone, Debug, PartialEq)] pub enum SourceKind { /// The source contains Python source code. Python(String), /// The source contains a Jupyter notebook. - IpyNotebook(Notebook), + IpyNotebook(Box), } impl SourceKind { + pub fn ipy_notebook(notebook: Notebook) -> Self { + SourceKind::IpyNotebook(Box::new(notebook)) + } + + pub fn as_ipy_notebook(&self) -> Option<&Notebook> { + match self { + SourceKind::IpyNotebook(notebook) => Some(notebook), + SourceKind::Python(_) => None, + } + } + + pub fn as_python(&self) -> Option<&str> { + match self { + SourceKind::Python(code) => Some(code), + SourceKind::IpyNotebook(_) => None, + } + } + + pub fn expect_python(self) -> String { + match self { + SourceKind::Python(code) => code, + SourceKind::IpyNotebook(_) => panic!("expected python code"), + } + } + + pub fn expect_ipy_notebook(self) -> Notebook { + match self { + SourceKind::IpyNotebook(notebook) => *notebook, + SourceKind::Python(_) => panic!("expected ipy notebook"), + } + } + #[must_use] pub(crate) fn updated(&self, new_source: String, source_map: &SourceMap) -> Self { match self { @@ -52,7 +84,7 @@ impl SourceKind { let notebook = Notebook::from_path(path)?; Ok(notebook .is_python_notebook() - .then_some(Self::IpyNotebook(notebook))) + .then_some(Self::IpyNotebook(Box::new(notebook)))) } else { let contents = std::fs::read_to_string(path)?; Ok(Some(Self::Python(contents))) @@ -69,7 +101,7 @@ impl SourceKind { let notebook = Notebook::from_source_code(&source_code)?; Ok(notebook .is_python_notebook() - .then_some(Self::IpyNotebook(notebook))) + .then_some(Self::IpyNotebook(Box::new(notebook)))) } else { Ok(Some(Self::Python(source_code))) } diff --git a/crates/ruff_linter/src/test.rs b/crates/ruff_linter/src/test.rs index 53d9d568d4..f0c3063c95 100644 --- a/crates/ruff_linter/src/test.rs +++ b/crates/ruff_linter/src/test.rs @@ -60,7 +60,7 @@ pub(crate) fn assert_notebook_path( ) -> Result { let source_notebook = Notebook::from_path(path.as_ref())?; - let source_kind = SourceKind::IpyNotebook(source_notebook); + let source_kind = SourceKind::ipy_notebook(source_notebook); let (messages, transformed) = test_contents(&source_kind, path.as_ref(), settings); let expected_notebook = Notebook::from_path(expected.as_ref())?; let linted_notebook = transformed.into_owned().expect_ipy_notebook(); diff --git a/crates/ruff_python_formatter/src/expression/parentheses.rs b/crates/ruff_python_formatter/src/expression/parentheses.rs index 8fa13546b3..e3cdf852ab 100644 --- a/crates/ruff_python_formatter/src/expression/parentheses.rs +++ b/crates/ruff_python_formatter/src/expression/parentheses.rs @@ -255,7 +255,7 @@ impl<'ast> Format> for FormatOptionalParentheses<'_, 'ast> soft_line_break(), if_group_breaks(&token(")")) ]) - .with_group_id(Some(parens_id))] + .with_id(Some(parens_id))] ) } } diff --git a/crates/ruff_python_formatter/src/statement/stmt_assign.rs b/crates/ruff_python_formatter/src/statement/stmt_assign.rs index 80dfc81884..f7bb76d628 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_assign.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_assign.rs @@ -413,7 +413,7 @@ impl Format> for FormatStatementsLastExpression<'_> { soft_block_indent(&format_args![flat, inline_comments]), token(")"), ]) - .with_group_id(Some(group_id)) + .with_id(Some(group_id)) .should_expand(true) .fmt(f) }); @@ -433,7 +433,7 @@ impl Format> for FormatStatementsLastExpression<'_> { token(")"), inline_comments, ]) - .with_group_id(Some(group_id)) + .with_id(Some(group_id)) .should_expand(true) .fmt(f) }); @@ -501,7 +501,7 @@ impl Format> for FormatStatementsLastExpression<'_> { soft_block_indent(&format_args![f_string_flat, inline_comments]), token(")"), ]) - .with_group_id(Some(group_id)) + .with_id(Some(group_id)) .should_expand(true) .fmt(f) }); @@ -817,7 +817,7 @@ impl Format> for FormatStatementsLastExpression<'_> { space(), token("("), group(&soft_block_indent(&format_expanded)) - .with_group_id(Some(group_id)) + .with_id(Some(group_id)) .should_expand(true), token(")"), inline_comments @@ -875,7 +875,7 @@ impl Format> for FormatStatementsLastExpression<'_> { space(), token("("), group(&soft_block_indent(&format_expanded)) - .with_group_id(Some(group_id)) + .with_id(Some(group_id)) .should_expand(true), token(")"), inline_comments diff --git a/crates/ruff_python_semantic/src/analyze/typing.rs b/crates/ruff_python_semantic/src/analyze/typing.rs index be1d529ce9..93213d8dea 100644 --- a/crates/ruff_python_semantic/src/analyze/typing.rs +++ b/crates/ruff_python_semantic/src/analyze/typing.rs @@ -252,9 +252,7 @@ pub fn is_immutable_annotation( .is_some_and(|qualified_name| { is_immutable_non_generic_type(qualified_name.segments()) || is_immutable_generic_type(qualified_name.segments()) - || extend_immutable_calls - .iter() - .any(|target| qualified_name == *target) + || extend_immutable_calls.contains(&qualified_name) }) } Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => semantic @@ -308,9 +306,7 @@ pub fn is_immutable_func( .resolve_qualified_name(map_subscript(func)) .is_some_and(|qualified_name| { is_immutable_return_type(qualified_name.segments()) - || extend_immutable_calls - .iter() - .any(|target| qualified_name == *target) + || extend_immutable_calls.contains(&qualified_name) }) } diff --git a/crates/ruff_server/src/session/index.rs b/crates/ruff_server/src/session/index.rs index 868b91a0cb..4fa485bb87 100644 --- a/crates/ruff_server/src/session/index.rs +++ b/crates/ruff_server/src/session/index.rs @@ -559,7 +559,7 @@ impl DocumentQuery { ruff_linter::source_kind::SourceKind::Python(document.contents().to_string()) } Self::Notebook { notebook, .. } => { - ruff_linter::source_kind::SourceKind::IpyNotebook(notebook.make_ruff_notebook()) + ruff_linter::source_kind::SourceKind::ipy_notebook(notebook.make_ruff_notebook()) } } } diff --git a/crates/ruff_server/src/session/index/ruff_settings.rs b/crates/ruff_server/src/session/index/ruff_settings.rs index c004f1d9f6..ca7fa918ff 100644 --- a/crates/ruff_server/src/session/index/ruff_settings.rs +++ b/crates/ruff_server/src/session/index/ruff_settings.rs @@ -462,7 +462,7 @@ impl ConfigurationTransformer for EditorConfigurationTransformer<'_> { tracing::debug!( "Combining settings from editor-specified inline configuration" ); - match Configuration::from_options(options, None, project_root) { + match Configuration::from_options(*options, None, project_root) { Ok(configuration) => editor_configuration.combine(configuration), Err(err) => { tracing::error!( @@ -516,10 +516,10 @@ mod tests { #[test] fn inline_settings() { let editor_settings = ResolvedEditorSettings { - configuration: Some(ResolvedConfiguration::Inline(Options { + configuration: Some(ResolvedConfiguration::Inline(Box::new(Options { line_length: Some(LineLength::try_from(120).unwrap()), ..Default::default() - })), + }))), ..Default::default() }; @@ -534,10 +534,10 @@ mod tests { #[test] fn inline_and_specific_settings_resolution_order() { let editor_settings = ResolvedEditorSettings { - configuration: Some(ResolvedConfiguration::Inline(Options { + configuration: Some(ResolvedConfiguration::Inline(Box::new(Options { line_length: Some(LineLength::try_from(120).unwrap()), ..Default::default() - })), + }))), line_length: Some(LineLength::try_from(100).unwrap()), ..Default::default() }; diff --git a/crates/ruff_server/src/session/settings.rs b/crates/ruff_server/src/session/settings.rs index d10b493737..fb5d2ee636 100644 --- a/crates/ruff_server/src/session/settings.rs +++ b/crates/ruff_server/src/session/settings.rs @@ -52,7 +52,7 @@ pub(crate) struct ResolvedEditorSettings { #[cfg_attr(test, derive(PartialEq, Eq))] pub(crate) enum ResolvedConfiguration { FilePath(PathBuf), - Inline(Options), + Inline(Box), } impl TryFrom<&ClientConfiguration> for ResolvedConfiguration { @@ -68,7 +68,7 @@ impl TryFrom<&ClientConfiguration> for ResolvedConfiguration { if options.extend.is_some() { Err(ResolvedConfigurationError::ExtendNotSupported) } else { - Ok(ResolvedConfiguration::Inline(options)) + Ok(ResolvedConfiguration::Inline(Box::new(options))) } } } @@ -991,7 +991,7 @@ mod tests { fix_violation_enable: true, show_syntax_errors: true, editor_settings: ResolvedEditorSettings { - configuration: Some(ResolvedConfiguration::Inline(Options { + configuration: Some(ResolvedConfiguration::Inline(Box::new(Options { line_length: Some(LineLength::try_from(100).unwrap()), lint: Some(LintOptions { common: LintCommonOptions { @@ -1005,7 +1005,7 @@ mod tests { ..Default::default() }), ..Default::default() - })), + }))), extend_select: Some(vec![RuleSelector::from_str("RUF001").unwrap()]), ..Default::default() } diff --git a/crates/ty_python_semantic/src/site_packages.rs b/crates/ty_python_semantic/src/site_packages.rs index 53d8a037a2..ccad356046 100644 --- a/crates/ty_python_semantic/src/site_packages.rs +++ b/crates/ty_python_semantic/src/site_packages.rs @@ -594,7 +594,7 @@ impl PythonHomePath { system .is_directory(&canonicalized) .then_some(Self(canonicalized)) - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "not a directory")) + .ok_or_else(|| io::Error::other("not a directory")) } } diff --git a/crates/ty_python_semantic/src/types.rs b/crates/ty_python_semantic/src/types.rs index ee59b8bf63..ab6a0a5ab5 100644 --- a/crates/ty_python_semantic/src/types.rs +++ b/crates/ty_python_semantic/src/types.rs @@ -5034,7 +5034,6 @@ impl<'db> Type<'db> { /// Note that this does not specialize generic classes, functions, or type aliases! That is a /// different operation that is performed explicitly (via a subscript operation), or implicitly /// via a call to the generic object. - #[must_use] #[salsa::tracked] pub fn apply_specialization( self, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index e7f22fb8ba..0837c1fca7 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.86" +channel = "1.87"