Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -431,3 +431,6 @@ unnecessary_box_returns = "warn"
unnecessary_join = "warn"
unnecessary_wraps = "warn"
unnested_or_patterns = "warn"

[lints]
workspace = true
29 changes: 21 additions & 8 deletions benches/execution.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
#![allow(clippy::iter_over_hash_type)]

extern crate alloc;

use core::hint::black_box;
use criterion::{
Bencher, BenchmarkGroup, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main,
measurement::WallTime,
};
use rustpython_compiler::Mode;
use rustpython_vm::{Interpreter, PyResult, Settings};
use std::{collections::HashMap, hint::black_box, path::Path};
use std::{collections::HashMap, path::Path};

/// `true` when the benchmarks are executed by the CodSpeed runner.
///
Expand All @@ -15,8 +20,8 @@ fn is_codspeed() -> bool {
std::env::var_os("CODSPEED_ENV").is_some()
}

fn bench_cpython_code(b: &mut Bencher, source: &str) {
let c_str_source_head = std::ffi::CString::new(source).unwrap();
fn bench_cpython_code(b: &mut Bencher<'_>, source: &str) {
let c_str_source_head = alloc::ffi::CString::new(source).unwrap();
let c_str_source = c_str_source_head.as_c_str();
pyo3::Python::attach(|py| {
b.iter(|| {
Expand All @@ -27,7 +32,7 @@ fn bench_cpython_code(b: &mut Bencher, source: &str) {
})
}

fn bench_rustpython_code(b: &mut Bencher, name: &str, source: &str) {
fn bench_rustpython_code(b: &mut Bencher<'_>, name: &str, source: &str) {
// NOTE: Take long time.
let mut settings = Settings::default();
settings.path_list.push("Lib/".to_string());
Expand All @@ -41,13 +46,17 @@ fn bench_rustpython_code(b: &mut Bencher, name: &str, source: &str) {
b.iter(|| {
let code = vm.compile(source, Mode::Exec, name).unwrap();
let scope = vm.new_scope_with_builtins();
let res: PyResult = vm.run_code_obj(code.clone(), scope);
let res: PyResult = vm.run_code_obj(code, scope);
vm.unwrap_pyresult(res);
})
})
}

pub fn benchmark_file_execution(group: &mut BenchmarkGroup<WallTime>, name: &str, contents: &str) {
pub fn benchmark_file_execution(
group: &mut BenchmarkGroup<'_, WallTime>,
name: &str,
contents: &str,
) {
if !is_codspeed() {
group.bench_function(BenchmarkId::new(name, "cpython"), |b| {
bench_cpython_code(b, contents)
Expand All @@ -58,7 +67,11 @@ pub fn benchmark_file_execution(group: &mut BenchmarkGroup<WallTime>, name: &str
});
}

pub fn benchmark_file_parsing(group: &mut BenchmarkGroup<WallTime>, name: &str, contents: &str) {
pub fn benchmark_file_parsing(
group: &mut BenchmarkGroup<'_, WallTime>,
name: &str,
contents: &str,
) {
group.throughput(Throughput::Bytes(contents.len() as u64));
group.bench_function(BenchmarkId::new("rustpython", name), |b| {
b.iter(|| ruff_python_parser::parse_module(contents).unwrap())
Expand All @@ -81,7 +94,7 @@ pub fn benchmark_file_parsing(group: &mut BenchmarkGroup<WallTime>, name: &str,
}
}

pub fn benchmark_pystone(group: &mut BenchmarkGroup<WallTime>, contents: String) {
pub fn benchmark_pystone(group: &mut BenchmarkGroup<'_, WallTime>, contents: String) {
// Default is 50_000. This takes a while, so reduce it to 30k.
for idx in (10_000..=30_000).step_by(10_000) {
let code_with_loops = format!("LOOPS = {idx}\n{contents}");
Expand Down
21 changes: 9 additions & 12 deletions benches/microbenchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ use criterion::{
use pyo3::types::PyAnyMethods;
use rustpython_compiler::Mode;
use rustpython_vm::{AsObject, Interpreter, PyResult, Settings};
use std::{
fs, io,
path::{Path, PathBuf},
};
use std::{fs, io, path::Path};

// List of microbenchmarks to skip.
//
Expand Down Expand Up @@ -36,7 +33,7 @@ pub struct MicroBenchmark {
iterate: bool,
}

fn bench_cpython_code(group: &mut BenchmarkGroup<WallTime>, bench: &MicroBenchmark) {
fn bench_cpython_code(group: &mut BenchmarkGroup<'_, WallTime>, bench: &MicroBenchmark) {
pyo3::Python::attach(|py| {
let setup_name = format!("{}_setup", bench.name);
let setup_code = cpy_compile_code(py, &bench.setup, &setup_name).unwrap();
Expand All @@ -49,8 +46,8 @@ fn bench_cpython_code(group: &mut BenchmarkGroup<WallTime>, bench: &MicroBenchma
let exec = builtins.getattr("exec").expect("no exec in builtins");

let bench_func = |(globals, locals): &mut (
pyo3::Bound<pyo3::types::PyDict>,
pyo3::Bound<pyo3::types::PyDict>,
pyo3::Bound<'_, pyo3::types::PyDict>,
pyo3::Bound<'_, pyo3::types::PyDict>,
)| {
let res = exec.call((&code, &*globals, &*locals), None);
if let Err(e) = res {
Expand Down Expand Up @@ -107,7 +104,7 @@ fn cpy_compile_code<'a>(
.expect("compile() should return a code object"))
}

fn bench_rustpython_code(group: &mut BenchmarkGroup<WallTime>, bench: &MicroBenchmark) {
fn bench_rustpython_code(group: &mut BenchmarkGroup<'_, WallTime>, bench: &MicroBenchmark) {
let mut settings = Settings::default();
settings.path_list.push("Lib/".to_string());
settings.write_bytecode = false;
Expand Down Expand Up @@ -208,11 +205,11 @@ pub fn criterion_benchmark(c: &mut Criterion) {
.unwrap()
.collect::<io::Result<_>>()
.unwrap();
let paths: Vec<PathBuf> = dirs.iter().map(|p| p.path()).collect();

let benchmarks: Vec<MicroBenchmark> = paths
.into_iter()
.map(|p| {
let benchmarks: Vec<MicroBenchmark> = dirs
.iter()
.map(|d| {
let p = d.path();
let name = p.file_name().unwrap().to_os_string();
let contents = fs::read_to_string(p).unwrap();
let iterate = contents.contains("ITERATIONS");
Expand Down
13 changes: 7 additions & 6 deletions crates/codegen/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1253,8 +1253,7 @@ fn assemble_location_info(
let mut prev_line = first_line;
let mut loc = no_linetable_location();
let mut size = 0;
for i in 0..instr_sequence.instr_used {
let entry = &instr_sequence.instrs[i];
for entry in instr_sequence.instrs.iter().take(instr_sequence.instr_used) {
let instr_loc = entry.info.instruction_linetable_location();
if !same_location(loc, instr_loc) {
assemble_emit_location(&mut linetable, loc, size, &mut prev_line, debug_ranges)?;
Expand Down Expand Up @@ -2772,8 +2771,7 @@ impl Blocks {
let mut block_idx = BlockIdx(0);
while block_idx != BlockIdx::NULL {
let block = &self[block_idx];
for i in 0..block.instruction_used {
let instr = &block.instructions[i];
for instr in block.instructions.iter().take(block.instruction_used) {
if instr.instr.has_const() {
let index = u32::from(instr.arg) as usize;
debug_assert!(index < nconsts);
Expand Down Expand Up @@ -6596,8 +6594,11 @@ fn cfg_from_instruction_sequence(
if let Some(annotations_code) = &annotations_code {
debug_assert!(annotations_code.label_map.is_none());
debug_assert_eq!(annotations_code.label_map_allocation, 0);
for j in 0..annotations_code.instr_used {
let ann_entry = annotations_code.instrs[j];
for ann_entry in annotations_code
.instrs
.iter()
.take(annotations_code.instr_used)
{
debug_assert!(!ann_entry.info.instr.has_target());
let mut info = ann_entry.info;
info.target = BlockIdx::NULL;
Expand Down
7 changes: 3 additions & 4 deletions crates/common/src/float_ops.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::f64;
use core::f64::consts::LOG10_2;
use malachite_bigint::{BigInt, ToBigInt};
use num_traits::{Signed, ToPrimitive};

Expand Down Expand Up @@ -240,9 +240,8 @@ pub fn round_float_digits(x: f64, ndigits: i32) -> Option<f64> {
return Some(x);
}

const NDIGITS_MAX: i32 =
((f64::MANTISSA_DIGITS as i32 - f64::MIN_EXP) as f64 * f64::consts::LOG10_2) as i32;
const NDIGITS_MIN: i32 = -(((f64::MAX_EXP + 1) as f64 * f64::consts::LOG10_2) as i32);
const NDIGITS_MAX: i32 = ((f64::MANTISSA_DIGITS as i32 - f64::MIN_EXP) as f64 * LOG10_2) as i32;
const NDIGITS_MIN: i32 = -(((f64::MAX_EXP + 1) as f64 * LOG10_2) as i32);

if ndigits > NDIGITS_MAX {
return Some(x);
Expand Down
6 changes: 3 additions & 3 deletions crates/common/src/wtf8_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,13 @@ impl Wtf8Index {
};
let mut index = group_min << 6;
let mut pos = base;
for entry in 0..entries {
let at = base + self.groups[group_min].ofs[entry] as usize;
for (i, &entry) in self.groups[group_min].ofs.iter().enumerate().take(entries) {
let at = base + entry as usize;
if at >= bytepos {
break;
}
pos = at;
index = (group_min << 6) + (entry << 2) + 1;
index = (group_min << 6) + (i << 2) + 1;
}
while pos < bytepos {
pos = next_pos(data, pos);
Expand Down
6 changes: 3 additions & 3 deletions crates/host_env/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ nix = { workspace = true }
rustix = { workspace = true }

[target.'cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))'.dependencies]
num_cpus = "1.17.0"
num_cpus = { workspace = true }

[target.'cfg(not(any(target_os = "ios", target_os = "android", target_os = "windows", target_arch = "wasm32", target_os = "redox")))'.dependencies]
mac_address = { workspace = true }
Expand All @@ -67,8 +67,8 @@ which = { workspace = true }
termios = { workspace = true }

[target.'cfg(any(unix, windows))'.dependencies]
memmap2 = "0.9.10"
libloading = "0.9"
memmap2 = { workspace = true }
libloading = { workspace = true }

[target.'cfg(all(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"), not(any(target_env = "musl", target_env = "sgx"))))'.dependencies]
libffi = { workspace = true, features = ["system"] }
Expand Down
1 change: 0 additions & 1 deletion crates/host_env/src/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ pub fn rename(
///
/// On Windows, this supports the full u32 range including STATUS_CONTROL_C_EXIT (0xC000013A).
/// On other platforms, only the lower 8 bits are used.
#[must_use]
pub fn exit_code(code: u32) -> ExitCode {
#[cfg(windows)]
{
Expand Down
3 changes: 3 additions & 0 deletions crates/literal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ repository = { workspace = true }
license = { workspace = true }
rust-version = { workspace = true }

[lints]
workspace = true

[dependencies]
rustpython-unicode = { workspace = true }
rustpython-wtf8 = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions crates/literal/src/complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ fn component_to_string(value: f64) -> String {
}

/// Convert a complex number to a string.
#[must_use]
pub fn to_string(re: f64, im: f64) -> String {
let mut im_part = component_to_string(im);
im_part.push('j');
Expand All @@ -41,9 +42,8 @@ pub fn to_string(re: f64, im: f64) -> String {
let re_part = if re == 0.0 {
if re.is_sign_positive() {
return im_part;
} else {
"-0".to_owned()
}
"-0".to_owned()
} else {
component_to_string(re)
};
Expand Down
17 changes: 17 additions & 0 deletions crates/literal/src/escape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub enum Quote {

impl Quote {
#[inline]
#[must_use]
pub const fn swap(self) -> Self {
match self {
Self::Single => Self::Double,
Expand All @@ -17,6 +18,7 @@ impl Quote {
}

#[inline]
#[must_use]
pub const fn to_byte(&self) -> u8 {
match self {
Self::Single => b'\'',
Expand All @@ -25,6 +27,7 @@ impl Quote {
}

#[inline]
#[must_use]
pub const fn to_char(&self) -> char {
match self {
Self::Single => '\'',
Expand Down Expand Up @@ -96,20 +99,24 @@ pub struct UnicodeEscape<'a> {

impl<'a> UnicodeEscape<'a> {
#[inline]
#[must_use]
pub const fn with_forced_quote(source: &'a Wtf8, quote: Quote) -> Self {
let layout = EscapeLayout { quote, len: None };
Self { source, layout }
}
#[inline]
#[must_use]
pub fn with_preferred_quote(source: &'a Wtf8, quote: Quote) -> Self {
let layout = Self::repr_layout(source, quote);
Self { source, layout }
}
#[inline]
#[must_use]
pub fn new_repr(source: &'a Wtf8) -> Self {
Self::with_preferred_quote(source, Quote::Single)
}
#[inline]
#[must_use]
pub const fn str_repr<'r>(&'a self) -> StrRepr<'r, 'a> {
StrRepr(self)
}
Expand All @@ -125,6 +132,7 @@ impl StrRepr<'_, '_> {
formatter.write_char(quote)
}

#[must_use]
pub fn to_string(&self) -> Option<String> {
let mut s = String::with_capacity(self.0.layout().len?);
self.write(&mut s).unwrap();
Expand All @@ -141,6 +149,7 @@ impl core::fmt::Display for StrRepr<'_, '_> {
impl UnicodeEscape<'_> {
const REPR_RESERVED_LEN: usize = 2; // for quotes

#[must_use]
pub fn repr_layout(source: &Wtf8, preferred_quote: Quote) -> EscapeLayout {
Self::output_layout_with_checker(source, preferred_quote, |a, b| {
Some((a as isize).checked_add(b as isize)? as usize)
Expand Down Expand Up @@ -284,36 +293,43 @@ pub struct AsciiEscape<'a> {

impl<'a> AsciiEscape<'a> {
#[inline]
#[must_use]
pub const fn new(source: &'a [u8], layout: EscapeLayout) -> Self {
Self { source, layout }
}
#[inline]
#[must_use]
pub const fn with_forced_quote(source: &'a [u8], quote: Quote) -> Self {
let layout = EscapeLayout { quote, len: None };
Self { source, layout }
}
#[inline]
#[must_use]
pub fn with_preferred_quote(source: &'a [u8], quote: Quote) -> Self {
let layout = Self::repr_layout(source, quote);
Self { source, layout }
}
#[inline]
#[must_use]
pub fn new_repr(source: &'a [u8]) -> Self {
Self::with_preferred_quote(source, Quote::Single)
}
#[inline]
#[must_use]
pub const fn bytes_repr<'r>(&'a self) -> BytesRepr<'r, 'a> {
BytesRepr(self)
}
}

impl AsciiEscape<'_> {
#[must_use]
pub fn repr_layout(source: &[u8], preferred_quote: Quote) -> EscapeLayout {
Self::output_layout_with_checker(source, preferred_quote, 3, |a, b| {
Some((a as isize).checked_add(b as isize)? as usize)
})
}

#[must_use]
pub fn named_repr_layout(source: &[u8], name: &str) -> EscapeLayout {
Self::output_layout_with_checker(source, Quote::Single, name.len() + 2 + 3, |a, b| {
Some((a as isize).checked_add(b as isize)? as usize)
Expand Down Expand Up @@ -436,6 +452,7 @@ impl BytesRepr<'_, '_> {
formatter.write_char(quote)
}

#[must_use]
pub fn to_string(&self) -> Option<String> {
let mut s = String::with_capacity(self.0.layout().len?);
self.write(&mut s).unwrap();
Expand Down
Loading
Loading