/// self.async_fn_summary is a summary of the closure that results from rewriting
/// the current function body into a generator. The preconditions found in this
/// summary are expressed in terms of the closure fields that capture the parameters
/// of the current function. The pre-conditions are also governed by a path condition
/// that requires the closure (enum) to be in state 0 (have a discriminant value of 0).
/// This function rewrites the pre-conditions to instead refer to the parameters of the
/// current function and eliminates the condition based on the closure discriminant value.
self.async_fn_summary is a summary of the closure that results from rewriting
the current function body into a generator. The preconditions found in this
summary are expressed in terms of the closure fields that capture the parameters
of the current function. The pre-conditions are also governed by a path condition
that requires the closure (enum) to be in state 0 (have a discriminant value of 0).
This function rewrites the pre-conditions to instead refer to the parameters of the
current function and eliminates the condition based on the closure discriminant value.
self . async_fn_summary is a summary of the closure that results from rewriting the current function body into a generator . The preconditions found in this summary are expressed in terms of the closure fields that capture the parameters of the current function . The pre - conditions are also governed by a path condition that requires the closure ( enum ) to be in state 0 ( have a discriminant value of 0 ) . This function rewrites the pre - conditions to instead refer to the parameters of the current function and eliminates the condition based on the closure discriminant value .
fn translate_async_preconditions(&mut self) -> Vec<Precondition> {
        // In order to specialize the closure preconditions to the current context,
        // we need to allocate a closure object from the heap and to populate its fields
        // with the (unknown) values of the parameters and locals of the current context.
        // The byte size of the closure object is not used, so we just fake it.
        let zero: Rc<AbstractValue> = Rc::new(0u128.into());
        let closure_object = self.get_new_heap_block(
            zero.clone(),
            zero,
            false,
            self.tcx.types.trait_object_dummy_self,
        );
        let closure_path: Rc<Path> = match &closure_object.expression {
            Expression::HeapBlock { .. } => Rc::new(
                PathEnum::HeapBlock {
                    value: closure_object.clone(),
                }
                .into(),
            ),
            _ => assume_unreachable!(),
        };
        // Setting the discriminant to 0 allows the related conditions in the closure's preconditions
        // to get simplified away.
        let discriminant = Path::new_discriminant(
            Path::new_field(closure_path.clone(), 0).refine_paths(&self.current_environment, 0),
        );
        let discriminant_val = self.get_u128_const_val(0);
        // Populate the closure object fields with the parameters and locals of the current context.
        self.current_environment
            .update_value_at(discriminant, discriminant_val);
        for (i, loc) in self.mir.local_decls.iter().skip(1).enumerate() {
            let qualifier = closure_path.clone();
            let closure_path = Path::new_field(Path::new_field(qualifier, 0), i)
                .refine_paths(&self.current_environment, 0);
            // skip(1) above ensures this
            assume!(i < usize::max_value());
            let path = if i < self.mir.arg_count {
                Path::new_parameter(i + 1)
            } else {
                Path::new_local(i + 1)
            };
            let specialized_type = self
                .type_visitor
                .specialize_generic_argument_type(loc.ty, &self.type_visitor.generic_argument_map);
            let value = self.lookup_path_and_refine_result(path, specialized_type);
            self.current_environment
                .update_value_at(closure_path, value);
        }
        // Now set up the dummy closure object as the actual argument used to specialize
        // the summary of the closure function.
        let actual_args = vec![(closure_path, closure_object)];
        // Now specialize/refine the closure summary's preconditions so that they can be used
        // as the preconditions of the current function (from which the closure function was
        // derived when turning it into a generator).
        self.async_fn_summary
            .as_ref()
            .unwrap()
            .preconditions
            .iter()
            .map(|precondition| {
                let refined_condition = precondition.condition.refine_parameters_and_paths(
                    &actual_args,
                    &None,
                    &self.current_environment,
                    &self.current_environment,
                    self.fresh_variable_offset,
                );
                Precondition {
                    condition: refined_condition,
                    message: precondition.message.clone(),
                    provenance: precondition.provenance.clone(),
                    spans: precondition.spans.clone(),
                }
            })
            .collect()
    }
fn translate_async_preconditions ( & mut self ) -> Vec < Precondition > { // In order to specialize the closure preconditions to the current context, // we need to allocate a closure object from the heap and to populate its fields // with the (unknown) values of the parameters and locals of the current context. // The byte size of the closure object is not used, so we just fake it. let zero : Rc < AbstractValue > = Rc :: new ( 0u128 . into ( ) ) ; let closure_object = self . get_new_heap_block ( zero . clone ( ) , zero , false , self . tcx . types . trait_object_dummy_self , ) ; let closure_path : Rc < Path > = match & closure_object . expression { Expression :: HeapBlock { .. } => Rc :: new ( PathEnum :: HeapBlock { value : closure_object . clone ( ) , } . into ( ) , ) , _ => assume_unreachable ! ( ) , } ; // Setting the discriminant to 0 allows the related conditions in the closure's preconditions // to get simplified away. let discriminant = Path :: new_discriminant ( Path :: new_field ( closure_path . clone ( ) , 0 ) . refine_paths ( & self . current_environment , 0 ) , ) ; let discriminant_val = self . get_u128_const_val ( 0 ) ; // Populate the closure object fields with the parameters and locals of the current context. self . current_environment . update_value_at ( discriminant , discriminant_val ) ; for ( i , loc ) in self . mir . local_decls . iter ( ) . skip ( 1 ) . enumerate ( ) { let qualifier = closure_path . clone ( ) ; let closure_path = Path :: new_field ( Path :: new_field ( qualifier , 0 ) , i ) . refine_paths ( & self . current_environment , 0 ) ; // skip(1) above ensures this assume ! ( i usize max_value ( ) ) ; let path = if i < self . mir . arg_count { Path :: new_parameter ( i + 1 ) } else { Path :: new_local ( i + 1 ) } ; let specialized_type = self . type_visitor . specialize_generic_argument_type ( loc . ty , & self . type_visitor . generic_argument_map ) ; let value = self . lookup_path_and_refine_result ( path , specialized_type ) ; self . current_environment . update_value_at ( closure_path , value ) ; } // Now set up the dummy closure object as the actual argument used to specialize // the summary of the closure function. let actual_args = vec ! [ ( closure_path closure_object ) ] ; // Now specialize/refine the closure summary's preconditions so that they can be used // as the preconditions of the current function (from which the closure function was // derived when turning it into a generator). self . async_fn_summary . as_ref ( ) . unwrap ( ) . preconditions . iter ( ) . map ( | precondition | { let refined_condition = precondition . condition . refine_parameters_and_paths ( & actual_args , & None , & self . current_environment , & self . current_environment , self . fresh_variable_offset , ) ; Precondition { condition : refined_condition , message : precondition . message . clone ( ) , provenance : precondition . provenance . clone ( ) , spans : precondition . spans . clone ( ) , } } ) . collect ( ) }
self.async_fn_summary is a summary of the closure that results from rewriting
the current function body into a generator.
self . async_fn_summary is a summary of the closure that results from rewriting the current function body into a generator .
&mut self