Replace raw usize IDs with new types (#13832)

# Description

In this PR I replaced most of the raw usize IDs with
[newtypes](https://doc.rust-lang.org/rust-by-example/generics/new_types.html).
Some other IDs already started using new types and in this PR I did not
want to touch them. To make the implementation less repetitive, I made
use of a generic `Id<T>` with marker structs. If this lands I would try
to move make other IDs also in this pattern.

Also at some places I needed to use `cast`, I'm not sure if the type was
incorrect and therefore casting not needed or if actually different ID
types intermingle sometimes.

# User-Facing Changes

Probably few, if you got a `DeclId` via a function and placed it later
again it will still work.
This commit is contained in:
Piepmatz
2024-09-30 13:20:15 +02:00
committed by GitHub
parent fc61416c79
commit f0c83a4459
36 changed files with 317 additions and 185 deletions

View File

@ -271,7 +271,7 @@ pub fn debug_string_without_formatting(value: &Value) -> String {
.join(" ")
),
//TODO: It would be good to drill deeper into closures.
Value::Closure { val, .. } => format!("<Closure {}>", val.block_id),
Value::Closure { val, .. } => format!("<Closure {}>", val.block_id.get()),
Value::Nothing { .. } => String::new(),
Value::Error { error, .. } => format!("{error:?}"),
Value::Binary { val, .. } => format!("{val:?}"),

View File

@ -1,4 +1,5 @@
use nu_engine::command_prelude::*;
use nu_protocol::{BlockId, DeclId};
#[derive(Clone)]
pub struct ViewIr;
@ -86,7 +87,8 @@ the declaration may not be in scope.
let decl_id = val
.try_into()
.ok()
.filter(|id| *id < engine_state.num_decls())
.map(DeclId::new)
.filter(|id| id.get() < engine_state.num_decls())
.ok_or_else(|| ShellError::IncorrectValue {
msg: "not a valid decl id".into(),
val_span: target.span(),
@ -102,11 +104,15 @@ the declaration may not be in scope.
})?
}
// Block by ID - often shows up in IR
Value::Int { val, .. } => val.try_into().map_err(|_| ShellError::IncorrectValue {
msg: "not a valid block id".into(),
val_span: target.span(),
call_span: call.head,
})?,
Value::Int { val, .. } => {
val.try_into()
.map(BlockId::new)
.map_err(|_| ShellError::IncorrectValue {
msg: "not a valid block id".into(),
val_span: target.span(),
call_span: call.head,
})?
}
// Pass through errors
Value::Error { error, .. } => return Err(*error),
_ => {
@ -119,7 +125,7 @@ the declaration may not be in scope.
let Some(block) = engine_state.try_get_block(block_id) else {
return Err(ShellError::GenericError {
error: format!("Unknown block ID: {block_id}"),
error: format!("Unknown block ID: {}", block_id.get()),
msg: "ensure the block ID is correct and try again".into(),
span: Some(target.span()),
help: None,