##// END OF EJS Templates
rust-cpython: mark all PyLeaked methods as unsafe...
rust-cpython: mark all PyLeaked methods as unsafe Unfortunately, these methods can be abused to obtain the inner 'static reference. The simplest (pseudo-code) example is: let leaked: PyLeaked<&'static _> = shared.leak_immutable(); let static_ref: &'static _ = &*leaked.try_borrow(py)?; // PyLeakedRef::deref() tries to bound the lifetime to itself, but // the underlying data is a &'static reference, so the returned // reference can be &'static. This problem can be easily fixed by coercing the lifetime, but there are many other ways to achieve that, and there wouldn't be a generic solution: let leaked: PyLeaked<&'static [_]> = shared.leak_immutable(); let leaked_iter: PyLeaked<slice::Iter<'static, _>> = unsafe { leaked.map(|v| v.iter()) }; let static_slice: &'static [_] = leaked_iter.try_borrow(py)?.as_slice(); So basically I failed to design the safe borrowing interface. Maybe we'll instead have to add much more restricted interface on top of the unsafe PyLeaked methods? For instance, Iterator::next() could be implemented if its Item type is not &'a (where 'a may be cheated.) Anyway, this seems not an easy issue, so it's probably better to leave the current interface as unsafe, and get broader comments while upstreaming this feature.

File last commit:

r44457:6b332c1f default
r44689:e960c30d default
Show More
lib.rs
144 lines | 3.8 KiB | application/rls-services+xml | RustLexer
// Copyright 2018-2020 Georges Racinet <georges.racinet@octobus.net>
// and Mercurial contributors
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
mod ancestors;
pub mod dagops;
pub use ancestors::{AncestorsIterator, LazyAncestors, MissingAncestors};
mod dirstate;
pub mod discovery;
pub mod testing; // unconditionally built, for use from integration tests
pub use dirstate::{
dirs_multiset::{DirsMultiset, DirsMultisetIter},
dirstate_map::DirstateMap,
parsers::{pack_dirstate, parse_dirstate, PARENT_SIZE},
status::{status, StatusResult},
CopyMap, CopyMapIter, DirstateEntry, DirstateParents, EntryState,
StateMap, StateMapIter,
};
mod filepatterns;
pub mod matchers;
pub mod revlog;
pub use revlog::*;
pub mod utils;
use crate::utils::hg_path::HgPathBuf;
pub use filepatterns::{
build_single_regex, read_pattern_file, PatternSyntax, PatternTuple,
};
use std::collections::HashMap;
use twox_hash::RandomXxHashBuilder64;
pub type LineNumber = usize;
/// Rust's default hasher is too slow because it tries to prevent collision
/// attacks. We are not concerned about those: if an ill-minded person has
/// write access to your repository, you have other issues.
pub type FastHashMap<K, V> = HashMap<K, V, RandomXxHashBuilder64>;
#[derive(Clone, Debug, PartialEq)]
pub enum DirstateParseError {
TooLittleData,
Overflow,
CorruptedEntry(String),
Damaged,
}
impl From<std::io::Error> for DirstateParseError {
fn from(e: std::io::Error) -> Self {
DirstateParseError::CorruptedEntry(e.to_string())
}
}
impl ToString for DirstateParseError {
fn to_string(&self) -> String {
use crate::DirstateParseError::*;
match self {
TooLittleData => "Too little data for dirstate.".to_string(),
Overflow => "Overflow in dirstate.".to_string(),
CorruptedEntry(e) => format!("Corrupted entry: {:?}.", e),
Damaged => "Dirstate appears to be damaged.".to_string(),
}
}
}
#[derive(Debug, PartialEq)]
pub enum DirstatePackError {
CorruptedEntry(String),
CorruptedParent,
BadSize(usize, usize),
}
impl From<std::io::Error> for DirstatePackError {
fn from(e: std::io::Error) -> Self {
DirstatePackError::CorruptedEntry(e.to_string())
}
}
#[derive(Debug, PartialEq)]
pub enum DirstateMapError {
PathNotFound(HgPathBuf),
EmptyPath,
ConsecutiveSlashes,
}
impl ToString for DirstateMapError {
fn to_string(&self) -> String {
use crate::DirstateMapError::*;
match self {
PathNotFound(_) => "expected a value, found none".to_string(),
EmptyPath => "Overflow in dirstate.".to_string(),
ConsecutiveSlashes => {
"found invalid consecutive slashes in path".to_string()
}
}
}
}
pub enum DirstateError {
Parse(DirstateParseError),
Pack(DirstatePackError),
Map(DirstateMapError),
IO(std::io::Error),
}
impl From<DirstateParseError> for DirstateError {
fn from(e: DirstateParseError) -> Self {
DirstateError::Parse(e)
}
}
impl From<DirstatePackError> for DirstateError {
fn from(e: DirstatePackError) -> Self {
DirstateError::Pack(e)
}
}
#[derive(Debug)]
pub enum PatternError {
UnsupportedSyntax(String),
}
#[derive(Debug)]
pub enum PatternFileError {
IO(std::io::Error),
Pattern(PatternError, LineNumber),
}
impl From<std::io::Error> for PatternFileError {
fn from(e: std::io::Error) -> Self {
PatternFileError::IO(e)
}
}
impl From<DirstateMapError> for DirstateError {
fn from(e: DirstateMapError) -> Self {
DirstateError::Map(e)
}
}
impl From<std::io::Error> for DirstateError {
fn from(e: std::io::Error) -> Self {
DirstateError::IO(e)
}
}