Why the parameter of a function is droped afer the temporary variable in return of the function?

struct A(i32);
impl Drop for A{
    fn drop(& mut self){
        println!("drop a = {}",self.0);
    }
}
fn fun(a:A){
    match &A(2){
        v=>{}
    }
}
fn main(){
    fun(A(1));
}

The output is

drop a = 2
drop a = 1

which means, the temporary variable is first dropped, then the parameter. However, according to the Rust Reference, which says:

Drop scopes are nested within one another as follows. When multiple scopes are left at once, such as when returning from a function, variables are dropped from the inside outwards.

  • The entire function scope is the outer most scope.
  • The function body block is contained within the scope of the entire function.

All function parameters are in the scope of the entire function body, so are dropped last when evaluating the function.

Apart from lifetime extension, the temporary scope of an expression is the smallest scope that contains the expression and is one of the following:

  • The entire function.

IIUC, because the function body block is nested within the entire function, and the parameter is in the scope of the entire function body while the temporary is in the entier function, which means the temporary variable should be dropped after the parameter.

An arguable place is that, does "the scope of the entire function body" have the same meaning as "function body block"?

How to interpret the output?

No, they are different. A block in Rust is an expression bounded by curly braces, like { ... }. The function body block is block expression that comes after the fn signature. That is, it’s everything inside the outermost { .... } braces of the function. Only variables declared inside of the curly braces have this scope:

fn foo() { ... }
//       ^^^^^^^ function body block

This “function body block” scope is contained within another scope, called the “entire function scope” or “entire function body”:

  • The entire function scope is the outer most scope.
  • The function body block is contained within the scope of the entire function.

This outermost “entire function” scope is where the parameters live, so parameters are always dropped last:

All function parameters are in the scope of the entire function body, so are dropped last when evaluating the function.

However, the temporary variable is also in the entire function/entire function body. Do you mean the case is regulated by the following rule:

Each variable or temporary is associated to a drop scope. When control flow leaves a drop scope all variables associated to that scope are dropped in reverse order of declaration (for variables) or creation (for temporaries).

Because the temporary variable is created after the parameter?

The temporary variable is in the “function body block” scope, which in turn is inside the “entire function” scope.

An inner scope ends before its outer/parent scope, so the variables associated to the inner scope are dropped before variables associated the outer scope. For example:

{ // outer scope begins.
    let a; // `a` is associated to the outer scope.
    { // inner scope begins.
        let b; // `b` associated to the inner scope.
    } // inner scope ends. `b` is dropped here.
} // outer scope ends. `a` is dropped here.

For any function, the “entire function” scope is the outermost scope, and the “function body block” scope is within it:

// entire function scope begins
fn fun(a: A)
{ // function body block begins
    let b: A;
} // function body block ends. `b` is dropped here.
// entire function scope ends. `a` is dropped here.

In your example, the temporary actually has an even shorter scope than the function block body, because each expression is its own drop scope. So, for example:

// entire function begins.
fn fun(a:A) // `a` associated to entire function.
{ // function body block begins.
    match &A(2) { // match expression begins. temporary associated to match expression.
        v => {}
    } // match expression ends. temporary is dropped here.
    { // inner block begins.
        let b = A(3); // `b` associated to inner block.
    } // inner block ends. `b` is dropped here.
}
// entire function ends. `a` is dropped here.

If you call the above code with fun(A(1)) then it will print:

drop a = 2
drop a = 3
drop a = 1

The tail expression is not a statement, so, the temporary scope of the temporary variable in the match expression that is the tail expression is The entire function. That is the case in Destructors - The Rust Reference

Ah, you are correct. In that case, both values are associated to the same scope, so this rule applies:

When control flow leaves a drop scope all variables associated to that scope are dropped in reverse order of declaration (for variables) or creation (for temporaries).

Because a is created/declared before the temporary, it is dropped after the temporary.