|  | 
| 25 | 25 | #![recursion_limit = "256"] | 
| 26 | 26 | // tidy-alphabetical-end | 
| 27 | 27 | 
 | 
| 28 |  | -use std::cell::{BorrowMutError, Cell, Ref, RefCell, RefMut}; | 
|  | 28 | +use std::cell::{Cell, Ref, RefCell}; | 
| 29 | 29 | use std::collections::BTreeSet; | 
| 30 |  | -use std::fmt::{self, Formatter}; | 
|  | 30 | +use std::fmt::{self}; | 
| 31 | 31 | use std::sync::Arc; | 
| 32 | 32 | 
 | 
| 33 | 33 | use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; | 
| @@ -96,6 +96,8 @@ pub mod rustdoc; | 
| 96 | 96 | 
 | 
| 97 | 97 | pub use macros::registered_tools_ast; | 
| 98 | 98 | 
 | 
|  | 99 | +use crate::ref_mut::{CmCell, CmRefCell}; | 
|  | 100 | + | 
| 99 | 101 | rustc_fluent_macro::fluent_messages! { "../messages.ftl" } | 
| 100 | 102 | 
 | 
| 101 | 103 | #[derive(Debug)] | 
| @@ -593,9 +595,9 @@ struct ModuleData<'ra> { | 
| 593 | 595 |     /// Resolutions in modules from other crates are not populated until accessed. | 
| 594 | 596 |     lazy_resolutions: Resolutions<'ra>, | 
| 595 | 597 |     /// True if this is a module from other crate that needs to be populated on access. | 
| 596 |  | -    populate_on_access: CmCell<bool>, // FIXME(batched): Use an atomic in batched import resolution? | 
|  | 598 | +    populate_on_access: Cell<bool>, // FIXME(parallel): Use an atomic in parallel import resolution | 
| 597 | 599 |     /// Used to disambiguate underscore items (`const _: T = ...`) in the module. | 
| 598 |  | -    underscore_disambiguator: CmCell<u32>, // FIXME(batched): Use an atomic in batched import resolution? | 
|  | 600 | +    underscore_disambiguator: CmCell<u32>, | 
| 599 | 601 | 
 | 
| 600 | 602 |     /// Macro invocations that can expand into items in this module. | 
| 601 | 603 |     unexpanded_invocations: CmRefCell<FxHashSet<LocalExpnId>>, | 
| @@ -656,7 +658,7 @@ impl<'ra> ModuleData<'ra> { | 
| 656 | 658 |             parent, | 
| 657 | 659 |             kind, | 
| 658 | 660 |             lazy_resolutions: Default::default(), | 
| 659 |  | -            populate_on_access: CmCell::new(is_foreign), | 
|  | 661 | +            populate_on_access: Cell::new(is_foreign), | 
| 660 | 662 |             underscore_disambiguator: CmCell::new(0), | 
| 661 | 663 |             unexpanded_invocations: Default::default(), | 
| 662 | 664 |             no_implicit_prelude, | 
| @@ -697,7 +699,7 @@ impl<'ra> Module<'ra> { | 
| 697 | 699 | 
 | 
| 698 | 700 |     /// This modifies `self` in place. The traits will be stored in `self.traits`. | 
| 699 | 701 |     fn ensure_traits<'tcx>(self, resolver: &impl AsRef<Resolver<'ra, 'tcx>>) { | 
| 700 |  | -        let mut traits = self.traits.borrow_mut_unchecked(); | 
|  | 702 | +        let mut traits = self.traits.borrow_mut(resolver.as_ref()); | 
| 701 | 703 |         if traits.is_none() { | 
| 702 | 704 |             let mut collected_traits = Vec::new(); | 
| 703 | 705 |             self.for_each_child(resolver, |r, name, ns, binding| { | 
| @@ -1976,7 +1978,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | 
| 1976 | 1978 |     fn resolutions(&self, module: Module<'ra>) -> &'ra Resolutions<'ra> { | 
| 1977 | 1979 |         if module.populate_on_access.get() { | 
| 1978 | 1980 |             // FIXME(batched): Will be fixed in batched import resolution. | 
| 1979 |  | -            module.populate_on_access.set_unchecked(false); | 
|  | 1981 | +            module.populate_on_access.set(false); | 
| 1980 | 1982 |             self.build_reduced_graph_external(module); | 
| 1981 | 1983 |         } | 
| 1982 | 1984 |         &module.0.0.lazy_resolutions | 
| @@ -2504,9 +2506,20 @@ pub fn provide(providers: &mut Providers) { | 
| 2504 | 2506 |     providers.registered_tools = macros::registered_tools; | 
| 2505 | 2507 | } | 
| 2506 | 2508 | 
 | 
|  | 2509 | +/// A wrapper around `&mut Resolver` that may be mutable or immutable, depending on a conditions. | 
|  | 2510 | +/// | 
|  | 2511 | +/// `Cm` stands for "conditionally mutable". | 
|  | 2512 | +/// | 
|  | 2513 | +/// Prefer constructing it through [`Resolver::cm`] to ensure correctness. | 
|  | 2514 | +type CmResolver<'r, 'ra, 'tcx> = ref_mut::RefOrMut<'r, Resolver<'ra, 'tcx>>; | 
|  | 2515 | + | 
| 2507 | 2516 | mod ref_mut { | 
|  | 2517 | +    use std::cell::{BorrowMutError, Cell, Ref, RefCell, RefMut}; | 
|  | 2518 | +    use std::fmt; | 
| 2508 | 2519 |     use std::ops::Deref; | 
| 2509 | 2520 | 
 | 
|  | 2521 | +    use crate::Resolver; | 
|  | 2522 | + | 
| 2510 | 2523 |     /// A wrapper around a mutable reference that conditionally allows mutable access. | 
| 2511 | 2524 |     pub(crate) struct RefOrMut<'a, T> { | 
| 2512 | 2525 |         p: &'a mut T, | 
| @@ -2555,117 +2568,84 @@ mod ref_mut { | 
| 2555 | 2568 |             self.p | 
| 2556 | 2569 |         } | 
| 2557 | 2570 |     } | 
| 2558 |  | -} | 
| 2559 | 2571 | 
 | 
| 2560 |  | -/// A wrapper around `&mut Resolver` that may be mutable or immutable, depending on a conditions. | 
| 2561 |  | -/// | 
| 2562 |  | -/// `Cm` stands for "conditionally mutable". | 
| 2563 |  | -/// | 
| 2564 |  | -/// Prefer constructing it through [`Resolver::cm`] to ensure correctness. | 
| 2565 |  | -type CmResolver<'r, 'ra, 'tcx> = ref_mut::RefOrMut<'r, Resolver<'ra, 'tcx>>; | 
| 2566 |  | - | 
| 2567 |  | -#[derive(Default)] | 
| 2568 |  | -struct CmCell<T> { | 
| 2569 |  | -    value: Cell<T>, | 
| 2570 |  | -} | 
| 2571 |  | - | 
| 2572 |  | -impl<T: Copy + fmt::Debug> fmt::Debug for CmCell<T> { | 
| 2573 |  | -    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { | 
| 2574 |  | -        f.debug_struct("CmCell").field("value", &self.get()).finish() | 
| 2575 |  | -    } | 
| 2576 |  | -} | 
|  | 2572 | +    #[derive(Default)] | 
|  | 2573 | +    pub(crate) struct CmCell<T>(Cell<T>); | 
| 2577 | 2574 | 
 | 
| 2578 |  | -impl<T: Copy> Clone for CmCell<T> { | 
| 2579 |  | -    #[inline] | 
| 2580 |  | -    fn clone(&self) -> CmCell<T> { | 
| 2581 |  | -        CmCell::new(self.get()) | 
|  | 2575 | +    impl<T: Copy + fmt::Debug> fmt::Debug for CmCell<T> { | 
|  | 2576 | +        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
|  | 2577 | +            f.debug_struct("CmCell").field("value", &self.get()).finish() | 
|  | 2578 | +        } | 
| 2582 | 2579 |     } | 
| 2583 |  | -} | 
| 2584 | 2580 | 
 | 
| 2585 |  | -impl<T: Copy> CmCell<T> { | 
| 2586 |  | -    const fn get(&self) -> T { | 
| 2587 |  | -        self.value.get() | 
|  | 2581 | +    impl<T: Copy> Clone for CmCell<T> { | 
|  | 2582 | +        #[inline] | 
|  | 2583 | +        fn clone(&self) -> CmCell<T> { | 
|  | 2584 | +            CmCell::new(self.get()) | 
|  | 2585 | +        } | 
| 2588 | 2586 |     } | 
| 2589 | 2587 | 
 | 
| 2590 |  | -    fn update_unchecked(&self, f: impl FnOnce(T) -> T) | 
| 2591 |  | -    where | 
| 2592 |  | -        T: Copy, | 
| 2593 |  | -    { | 
| 2594 |  | -        let old = self.get(); | 
| 2595 |  | -        self.set_unchecked(f(old)); | 
| 2596 |  | -    } | 
| 2597 |  | -} | 
|  | 2588 | +    impl<T: Copy> CmCell<T> { | 
|  | 2589 | +        pub(crate) const fn get(&self) -> T { | 
|  | 2590 | +            self.0.get() | 
|  | 2591 | +        } | 
| 2598 | 2592 | 
 | 
| 2599 |  | -impl<T> CmCell<T> { | 
| 2600 |  | -    const fn new(value: T) -> CmCell<T> { | 
| 2601 |  | -        CmCell { value: Cell::new(value) } | 
|  | 2593 | +        pub(crate) fn update_unchecked(&self, f: impl FnOnce(T) -> T) | 
|  | 2594 | +        where | 
|  | 2595 | +            T: Copy, | 
|  | 2596 | +        { | 
|  | 2597 | +            let old = self.get(); | 
|  | 2598 | +            self.set_unchecked(f(old)); | 
|  | 2599 | +        } | 
| 2602 | 2600 |     } | 
| 2603 | 2601 | 
 | 
| 2604 |  | -    #[track_caller] | 
| 2605 |  | -    #[allow(dead_code)] | 
| 2606 |  | -    fn set<'ra, 'tcx>(&self, val: T, r: &Resolver<'ra, 'tcx>) { | 
| 2607 |  | -        if r.assert_speculative { | 
| 2608 |  | -            panic!("Not allowed to mutate CmCell during speculative resolution"); | 
|  | 2602 | +    impl<T> CmCell<T> { | 
|  | 2603 | +        pub(crate) const fn new(value: T) -> CmCell<T> { | 
|  | 2604 | +            CmCell(Cell::new(value)) | 
| 2609 | 2605 |         } | 
| 2610 |  | -        self.value.set(val); | 
| 2611 |  | -    } | 
| 2612 | 2606 | 
 | 
| 2613 |  | -    fn set_unchecked(&self, val: T) { | 
| 2614 |  | -        self.value.set(val); | 
| 2615 |  | -    } | 
|  | 2607 | +        pub(crate) fn set_unchecked(&self, val: T) { | 
|  | 2608 | +            self.0.set(val); | 
|  | 2609 | +        } | 
| 2616 | 2610 | 
 | 
| 2617 |  | -    fn into_inner(self) -> T { | 
| 2618 |  | -        self.value.into_inner() | 
|  | 2611 | +        pub(crate) fn into_inner(self) -> T { | 
|  | 2612 | +            self.0.into_inner() | 
|  | 2613 | +        } | 
| 2619 | 2614 |     } | 
| 2620 |  | -} | 
| 2621 |  | -#[derive(Default)] | 
| 2622 |  | -struct CmRefCell<T> { | 
| 2623 |  | -    ref_cell: RefCell<T>, | 
| 2624 |  | -} | 
| 2625 | 2615 | 
 | 
| 2626 |  | -impl<T> CmRefCell<T> { | 
| 2627 |  | -    const fn new(value: T) -> CmRefCell<T> { | 
| 2628 |  | -        CmRefCell { ref_cell: RefCell::new(value) } | 
| 2629 |  | -    } | 
|  | 2616 | +    #[derive(Default)] | 
|  | 2617 | +    pub(crate) struct CmRefCell<T>(RefCell<T>); | 
| 2630 | 2618 | 
 | 
| 2631 |  | -    #[inline] | 
| 2632 |  | -    #[track_caller] | 
| 2633 |  | -    #[allow(dead_code)] | 
| 2634 |  | -    fn borrow_mut<'ra, 'tcx>(&self, r: &Resolver<'ra, 'tcx>) -> RefMut<'_, T> { | 
| 2635 |  | -        if r.assert_speculative { | 
| 2636 |  | -            panic!("Not allowed to mutably borrow a CmRefCell during speculative resolution"); | 
|  | 2619 | +    impl<T> CmRefCell<T> { | 
|  | 2620 | +        pub(crate) const fn new(value: T) -> CmRefCell<T> { | 
|  | 2621 | +            CmRefCell(RefCell::new(value)) | 
| 2637 | 2622 |         } | 
| 2638 |  | -        self.ref_cell.borrow_mut() | 
| 2639 |  | -    } | 
| 2640 | 2623 | 
 | 
| 2641 |  | -    #[inline] | 
| 2642 |  | -    #[track_caller] | 
| 2643 |  | -    fn borrow_mut_unchecked(&self) -> RefMut<'_, T> { | 
| 2644 |  | -        self.ref_cell.borrow_mut() | 
| 2645 |  | -    } | 
|  | 2624 | +        #[inline] | 
|  | 2625 | +        #[track_caller] | 
|  | 2626 | +        pub(crate) fn borrow_mut_unchecked(&self) -> RefMut<'_, T> { | 
|  | 2627 | +            self.0.borrow_mut() | 
|  | 2628 | +        } | 
| 2646 | 2629 | 
 | 
| 2647 |  | -    #[inline] | 
| 2648 |  | -    #[track_caller] | 
| 2649 |  | -    fn try_borrow_mut_unchecked(&self) -> Result<RefMut<'_, T>, BorrowMutError> { | 
| 2650 |  | -        self.ref_cell.try_borrow_mut() | 
| 2651 |  | -    } | 
|  | 2630 | +        #[inline] | 
|  | 2631 | +        #[track_caller] | 
|  | 2632 | +        pub(crate) fn borrow_mut<'ra, 'tcx>(&self, r: &Resolver<'ra, 'tcx>) -> RefMut<'_, T> { | 
|  | 2633 | +            if r.assert_speculative { | 
|  | 2634 | +                panic!("Not allowed to mutably borrow a CmRefCell during speculative resolution"); | 
|  | 2635 | +            } | 
|  | 2636 | +            self.borrow_mut_unchecked() | 
|  | 2637 | +        } | 
| 2652 | 2638 | 
 | 
| 2653 |  | -    #[inline] | 
| 2654 |  | -    #[track_caller] | 
| 2655 |  | -    #[allow(dead_code)] | 
| 2656 |  | -    fn try_borrow_mut<'ra, 'tcx>( | 
| 2657 |  | -        &self, | 
| 2658 |  | -        r: Resolver<'ra, 'tcx>, | 
| 2659 |  | -    ) -> Result<RefMut<'_, T>, BorrowMutError> { | 
| 2660 |  | -        if r.assert_speculative { | 
| 2661 |  | -            panic!("Not allowed to mutably borrow a CmRefCell during speculative resolution"); | 
|  | 2639 | +        #[inline] | 
|  | 2640 | +        #[track_caller] | 
|  | 2641 | +        pub(crate) fn try_borrow_mut_unchecked(&self) -> Result<RefMut<'_, T>, BorrowMutError> { | 
|  | 2642 | +            self.0.try_borrow_mut() | 
| 2662 | 2643 |         } | 
| 2663 |  | -        self.ref_cell.try_borrow_mut() | 
| 2664 |  | -    } | 
| 2665 | 2644 | 
 | 
| 2666 |  | -    #[inline] | 
| 2667 |  | -    #[track_caller] | 
| 2668 |  | -    fn borrow(&self) -> Ref<'_, T> { | 
| 2669 |  | -        self.ref_cell.borrow() | 
|  | 2645 | +        #[inline] | 
|  | 2646 | +        #[track_caller] | 
|  | 2647 | +        pub(crate) fn borrow(&self) -> Ref<'_, T> { | 
|  | 2648 | +            self.0.borrow() | 
|  | 2649 | +        } | 
| 2670 | 2650 |     } | 
| 2671 | 2651 | } | 
0 commit comments