Jelajahi Sumber

Auto merge of #454 - servo:nll, r=nox

Fix a lifetime bug uncovered by NLL, thanks @lqd

A similar error message was: https://play.rust-lang.org/?gist=4c5f4002623da9a3df723c9540dd125e&version=nightly&mode=debug&edition=2015

```rust
error[E0509]: cannot move out of type `S<'_>`, which implements the `Drop` trait
  --> src/main.rs:15:17
   |
15 |         let S { url } = self;
   |                 ^^^ cannot move out of here
```

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-url/454)
<!-- Reviewable:end -->
bors-servo 8 tahun lalu
induk
melakukan
555f275e01
3 mengubah file dengan 16 tambahan dan 6 penghapusan
  1. 1 1
      Cargo.toml
  2. 10 2
      src/form_urlencoded.rs
  3. 5 3
      src/lib.rs

+ 1 - 1
Cargo.toml

@@ -2,7 +2,7 @@
 
 name = "url"
 # When updating version, also modify html_root_url in the lib.rs
-version = "1.7.0"
+version = "1.7.1"
 authors = ["The rust-url developers"]
 
 description = "URL library for Rust, based on the WHATWG URL Standard"

+ 10 - 2
src/form_urlencoded.rs

@@ -257,8 +257,16 @@ impl<'a> Target for &'a mut String {
 // * `Serializer` keeps its target in a private field
 // * Unlike in other `Target` impls, `UrlQuery::finished` does not return `Self`.
 impl<'a> Target for ::UrlQuery<'a> {
-    fn as_mut_string(&mut self) -> &mut String { &mut self.url.serialization }
-    fn finish(self) -> &'a mut ::Url { self.url }
+    fn as_mut_string(&mut self) -> &mut String {
+        &mut self.url.as_mut().unwrap().serialization
+    }
+
+    fn finish(mut self) -> &'a mut ::Url {
+        let url = self.url.take().unwrap();
+        url.restore_already_parsed_fragment(self.fragment.take());
+        url
+    }
+
     type Finished = &'a mut ::Url;
 }
 

+ 5 - 3
src/lib.rs

@@ -1343,7 +1343,7 @@ impl Url {
             self.serialization.push('?');
         }
 
-        let query = UrlQuery { url: self, fragment: fragment };
+        let query = UrlQuery { url: Some(self), fragment: fragment };
         form_urlencoded::Serializer::for_suffix(query, query_start + "?".len())
     }
 
@@ -2423,13 +2423,15 @@ fn io_error<T>(reason: &str) -> io::Result<T> {
 /// Implementation detail of `Url::query_pairs_mut`. Typically not used directly.
 #[derive(Debug)]
 pub struct UrlQuery<'a> {
-    url: &'a mut Url,
+    url: Option<&'a mut Url>,
     fragment: Option<String>,
 }
 
 impl<'a> Drop for UrlQuery<'a> {
     fn drop(&mut self) {
-        self.url.restore_already_parsed_fragment(self.fragment.take())
+        if let Some(url) = self.url.take() {
+            url.restore_already_parsed_fragment(self.fragment.take())
+        }
     }
 }