Home > Net >  Error about borrowing when nothing seems to be borrowed
Error about borrowing when nothing seems to be borrowed

Time:02-08

Writing a function to find the corresponding value to a given query name as an argument out of url, I got an error following:

error[E0515]: cannot return value referencing local variable `url`
  --> src/main.rs:55:25
   |
51 |   let mut queries = url.query_pairs();
   |                     ----------------- `url` is borrowed here
...
55 |     Some((_, value)) => value
   |                         ^^^^^ returns a value referencing data owned by the current function

code:

use url::{self, Url};

fn find_query(referer: String, query_name: &str) -> Cow<str> {
  let url_text = Url::parse(&referer).unwrap();
  let mut queries = url_text.query_pairs();
  let index_of_name = queries.find(|(key,_)| key == query_name);
  let result = match index_of_name {
    None => panic!("name didn't match any"),
    Some((_, value)) => value
  };
  result
}

Although I fixed it with the modification below, I still don't see why I had this type of error even though result itself was not borrowed. The message in the error "returns a value referencing data owned by the current function" sounds right.

Can anyone break down the reason behind this error?

Thank you in advance.

fixed code:

use url::{self, Url};

fn find_query(referer: String, query_name: &str) -> String {
  let url_text = Url::parse(&referer).unwrap();
  let queries = url_text.query_pairs();
  let index_of_name = queries.into_owned().find(|(key,_)| key == query_name);
  let result = match index_of_name {
    None => panic!("name didn't match any"),
    Some((_, value)) => value
  };
  result
}

CodePudding user response:

Writing:

let url: Url = todo!();
url.query_pairs()

is the same as writing:

let url: Url = todo!();
Url::query_pairs(&url)  // notice the borrow of url here

This is referred to as "unified function call syntax". Really, it's the foo.bar() syntax that is special, and Foo::foo(bar) is the "default" syntax.

You can also tell this is happening by looking at the function signature of query_pairs:

impl Url {
  pub fn query_pairs(&self) -> Parse<'_> {
    // ...
  }
}

The &self parameter denotes that this function takes the struct it is called on by immutable reference.

Hopefully this should illustrate why the call to into_owned() fixed the error

  •  Tags:  
  • Related