From daa87093ca2291cbba40e9df63247335e906a241 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 30 Oct 2022 12:38:58 -0400 Subject: [PATCH] Don't drop defs that would be shadowed --- crates/compiler/collections/src/lib.rs | 1 - .../collections/src/linked_list_extra.rs | 142 ------------------ crates/repl_cli/src/repl_state.rs | 21 +-- 3 files changed, 2 insertions(+), 162 deletions(-) delete mode 100644 crates/compiler/collections/src/linked_list_extra.rs diff --git a/crates/compiler/collections/src/lib.rs b/crates/compiler/collections/src/lib.rs index b8c99089e0..299e743caf 100644 --- a/crates/compiler/collections/src/lib.rs +++ b/crates/compiler/collections/src/lib.rs @@ -3,7 +3,6 @@ #![allow(clippy::large_enum_variant)] pub mod all; -pub mod linked_list_extra; mod reference_matrix; mod small_string_interner; pub mod soa; diff --git a/crates/compiler/collections/src/linked_list_extra.rs b/crates/compiler/collections/src/linked_list_extra.rs deleted file mode 100644 index bb8c8c3913..0000000000 --- a/crates/compiler/collections/src/linked_list_extra.rs +++ /dev/null @@ -1,142 +0,0 @@ -// This is just to get the nightly drain_iter API for LinkedList. -// TODO delete this module and use normal drain_iter once it has stabilized! - -use std::{collections::LinkedList, fmt, marker::PhantomData, ptr::NonNull}; - -/// The internal representation of std::collections::linked_list::LinkedList -struct InternalLinkedList { - head: Option>>, - tail: Option>>, - len: usize, - marker: PhantomData>>, -} - -impl InternalLinkedList { - unsafe fn unlink_node(&mut self, mut node: NonNull>) { - let node = node.as_mut(); // this one is ours now, we can create an &mut. - - // Not creating new mutable (unique!) references overlapping `element`. - match node.prev { - Some(prev) => (*prev.as_ptr()).next = node.next, - // this node is the head node - None => self.head = node.next, - }; - - match node.next { - Some(next) => (*next.as_ptr()).prev = node.prev, - // this node is the tail node - None => self.tail = node.prev, - }; - - self.len -= 1; - } -} - -struct Node { - next: Option>>, - prev: Option>>, - element: T, -} - -// Implementation of the nightly DrainFilter API, Apache2 licensed: -// https://doc.rust-lang.org/std/collections/struct.LinkedList.html#method.drain_filter -// TODO replace this with normal drain_iter once it's stabilized. -pub fn drain_filter<'a, T, F>(list: &'a mut LinkedList, filter: F) -> DrainFilter<'a, T, F> -where - F: FnMut(&mut T) -> bool, -{ - // This is the internal representation of std::collections::linked_list::LinkedList; - let list = unsafe { - std::mem::transmute::<&'a mut LinkedList, &'a mut InternalLinkedList>(list) - }; - - // avoid borrow issues. - let it = list.head; - let old_len = list.len; - - DrainFilter { - list, - it, - pred: filter, - idx: 0, - old_len, - } -} - -pub struct DrainFilter<'a, T: 'a, F: 'a> -where - F: FnMut(&mut T) -> bool, -{ - list: &'a mut InternalLinkedList, - it: Option>>, - pred: F, - idx: usize, - old_len: usize, -} - -impl Iterator for DrainFilter<'_, T, F> -where - F: FnMut(&mut T) -> bool, -{ - type Item = T; - - fn next(&mut self) -> Option { - while let Some(mut node) = self.it { - unsafe { - self.it = node.as_ref().next; - self.idx += 1; - - if (self.pred)(&mut node.as_mut().element) { - // `unlink_node` is okay with aliasing `element` references. - self.list.unlink_node(node); - return Some(Box::from_raw(node.as_ptr()).element); - } - } - } - - None - } - - fn size_hint(&self) -> (usize, Option) { - (0, Some(self.old_len - self.idx)) - } -} - -impl Drop for DrainFilter<'_, T, F> -where - F: FnMut(&mut T) -> bool, -{ - fn drop(&mut self) { - struct DropGuard<'r, 'a, T, F>(&'r mut DrainFilter<'a, T, F>) - where - F: FnMut(&mut T) -> bool; - - impl<'r, 'a, T, F> Drop for DropGuard<'r, 'a, T, F> - where - F: FnMut(&mut T) -> bool, - { - fn drop(&mut self) { - self.0.for_each(drop); - } - } - - while let Some(item) = self.next() { - let guard = DropGuard(self); - drop(item); - std::mem::forget(guard); - } - } -} - -impl fmt::Debug for DrainFilter<'_, T, F> -where - F: FnMut(&mut T) -> bool, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // This is the internal representation of std::collections::linked_list::LinkedList; - let list = - unsafe { std::mem::transmute::<&InternalLinkedList, &LinkedList>(&*self.list) }; - - f.debug_tuple("DrainFilter").field(list).finish() - } -} diff --git a/crates/repl_cli/src/repl_state.rs b/crates/repl_cli/src/repl_state.rs index 83b46566c9..1396051f2f 100644 --- a/crates/repl_cli/src/repl_state.rs +++ b/crates/repl_cli/src/repl_state.rs @@ -2,7 +2,6 @@ use crate::cli_gen::gen_and_eval_llvm; use crate::colors::{BLUE, END_COL, GREEN, PINK}; use bumpalo::Bump; use const_format::concatcp; -use roc_collections::linked_list_extra::drain_filter; use roc_collections::MutSet; use roc_mono::ir::OptLevel; use roc_parse::ast::{Expr, Pattern, TypeDef, ValueDef}; @@ -16,7 +15,6 @@ use rustyline::highlight::{Highlighter, PromptInfo}; use rustyline::validate::{self, ValidationContext, ValidationResult, Validator}; use rustyline_derive::{Completer, Helper, Hinter}; use std::borrow::Cow; -use std::collections::LinkedList; use target_lexicon::Triple; pub const PROMPT: &str = concatcp!("\n", BLUE, "ยป", END_COL, " "); @@ -58,7 +56,7 @@ struct PastDef { #[derive(Completer, Helper, Hinter)] pub struct ReplState { validator: InputValidator, - past_defs: LinkedList, + past_defs: Vec, past_def_idents: MutSet, last_auto_ident: u64, } @@ -235,22 +233,7 @@ impl ReplState { existing_idents.insert(ident.clone()); - // Override any defs that would be shadowed - if !self.past_defs.is_empty() { - drain_filter(&mut self.past_defs, |PastDef { ident, .. }| { - if existing_idents.contains(ident) { - // We already have a newer def for this ident, so drop the old one. - false - } else { - // We've never seen this def, so record it! - existing_idents.insert(ident.clone()); - - true - } - }); - } - - self.past_defs.push_front(PastDef { ident, src }); + self.past_defs.push(PastDef { ident, src }); } /// Wrap the given expresssion in the appropriate past defs