From bdcc7b03afb878570afe4da3927334466d673a76 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Fri, 17 Oct 2014 21:02:02 +0800 Subject: [PATCH 1/2] Split CString::new into CString::new and CString::new_owned --- src/libcoretest/ptr.rs | 8 +- src/libnative/io/addrinfo.rs | 2 +- src/libnative/io/file_unix.rs | 4 +- src/libnative/io/file_windows.rs | 4 +- src/librustc/back/write.rs | 6 +- src/librustc/middle/trans/base.rs | 4 +- src/librustc_llvm/lib.rs | 2 +- src/librustrt/c_str.rs | 86 ++++++++++++------- src/libstd/dynamic_lib.rs | 2 +- src/libstd/os.rs | 10 +-- src/libstd/rt/backtrace.rs | 6 +- src/test/run-pass/unix-process-spawn-errno.rs | 2 +- src/test/run-pass/variadic-ffi.rs | 2 +- 13 files changed, 83 insertions(+), 55 deletions(-) diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs index 754391a284ddf..7ac23189a7f69 100644 --- a/src/libcoretest/ptr.rs +++ b/src/libcoretest/ptr.rs @@ -211,7 +211,7 @@ fn test_ptr_array_each_with_len() { let mut ctr = 0; let mut iteration_count = 0; array_each_with_len(arr.as_ptr(), arr.len(), |e| { - let actual = CString::new(e, false); + let actual = CString::new(e); assert_eq!(actual.as_str(), expected_arr[ctr].as_str()); ctr += 1; iteration_count += 1; @@ -241,7 +241,7 @@ fn test_ptr_array_each() { let mut ctr = 0u; let mut iteration_count = 0u; array_each(arr_ptr, |e| { - let actual = CString::new(e, false); + let actual = CString::new(e); assert_eq!(actual.as_str(), expected_arr[ctr].as_str()); ctr += 1; iteration_count += 1; @@ -255,7 +255,7 @@ fn test_ptr_array_each() { fn test_ptr_array_each_with_len_null_ptr() { unsafe { array_each_with_len(0 as *const *const libc::c_char, 1, |e| { - CString::new(e, false).as_str().unwrap(); + CString::new(e).as_str().unwrap(); }); } } @@ -264,7 +264,7 @@ fn test_ptr_array_each_with_len_null_ptr() { fn test_ptr_array_each_null_ptr() { unsafe { array_each(0 as *const *const libc::c_char, |e| { - CString::new(e, false).as_str().unwrap(); + CString::new(e).as_str().unwrap(); }); } } diff --git a/src/libnative/io/addrinfo.rs b/src/libnative/io/addrinfo.rs index 7a07b6221277f..c309435533645 100644 --- a/src/libnative/io/addrinfo.rs +++ b/src/libnative/io/addrinfo.rs @@ -106,7 +106,7 @@ fn get_error(s: c_int) -> IoError { use std::c_str::CString; let err_str = unsafe { - CString::new(gai_strerror(s), false).as_str().unwrap().to_string() + CString::new(gai_strerror(s)).as_str().unwrap().to_string() }; IoError { code: s as uint, diff --git a/src/libnative/io/file_unix.rs b/src/libnative/io/file_unix.rs index 88f5061bbef17..91023050e5581 100644 --- a/src/libnative/io/file_unix.rs +++ b/src/libnative/io/file_unix.rs @@ -351,7 +351,7 @@ pub fn readdir(p: &CString) -> IoResult> { use libc::{opendir, readdir_r, closedir}; fn prune(root: &CString, dirs: Vec) -> Vec { - let root = unsafe { CString::new(root.as_ptr(), false) }; + let root = unsafe { CString::new(root.as_ptr()) }; let root = Path::new(root); dirs.into_iter().filter(|path| { @@ -376,7 +376,7 @@ pub fn readdir(p: &CString) -> IoResult> { while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } { if entry_ptr.is_null() { break } let cstr = unsafe { - CString::new(rust_list_dir_val(entry_ptr), false) + CString::new(rust_list_dir_val(entry_ptr)) }; paths.push(Path::new(cstr)); } diff --git a/src/libnative/io/file_windows.rs b/src/libnative/io/file_windows.rs index 6aa965948fd70..8c55045806315 100644 --- a/src/libnative/io/file_windows.rs +++ b/src/libnative/io/file_windows.rs @@ -343,7 +343,7 @@ pub fn mkdir(p: &CString, _mode: uint) -> IoResult<()> { pub fn readdir(p: &CString) -> IoResult> { fn prune(root: &CString, dirs: Vec) -> Vec { - let root = unsafe { CString::new(root.as_ptr(), false) }; + let root = unsafe { CString::new(root.as_ptr()) }; let root = Path::new(root); dirs.into_iter().filter(|path| { @@ -352,7 +352,7 @@ pub fn readdir(p: &CString) -> IoResult> { } let star = Path::new(unsafe { - CString::new(p.as_ptr(), false) + CString::new(p.as_ptr()) }).join("*"); let path = try!(to_utf16(&star.to_c_str())); diff --git a/src/librustc/back/write.rs b/src/librustc/back/write.rs index f1cd8b52e5ed3..e2c8bf26fccd1 100644 --- a/src/librustc/back/write.rs +++ b/src/librustc/back/write.rs @@ -46,10 +46,10 @@ pub enum OutputType { pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! { unsafe { let cstr = llvm::LLVMRustGetLastError(); - if cstr == ptr::null() { + if cstr as *const i8 == ptr::null() { handler.fatal(msg.as_slice()); } else { - let err = CString::new(cstr, true); + let err = CString::new_owned(cstr); let err = String::from_utf8_lossy(err.as_bytes()); handler.fatal(format!("{}: {}", msg.as_slice(), @@ -367,7 +367,7 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo match llvm::diagnostic::Diagnostic::unpack(info) { llvm::diagnostic::Optimization(opt) => { - let pass_name = CString::new(opt.pass_name, false); + let pass_name = CString::new(opt.pass_name); let pass_name = pass_name.as_str().expect("got a non-UTF8 pass name from LLVM"); let enabled = match cgcx.remark { AllPasses => true, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index c780969034444..027d5833640b4 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2965,7 +2965,7 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet) { continue } - let name = CString::new(llvm::LLVMGetValueName(val), false); + let name = CString::new(llvm::LLVMGetValueName(val)); declared.insert(name); } } @@ -2981,7 +2981,7 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet) { continue } - let name = CString::new(llvm::LLVMGetValueName(val), false); + let name = CString::new(llvm::LLVMGetValueName(val)); if !declared.contains(&name) && !reachable.contains_equiv(&name.as_str().unwrap()) { llvm::SetLinkage(val, llvm::InternalLinkage); diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index a1a6412af1135..1cf16fc486f57 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -1625,7 +1625,7 @@ extern { /** Returns a string describing the last error caused by an LLVMRust* call. */ - pub fn LLVMRustGetLastError() -> *const c_char; + pub fn LLVMRustGetLastError() -> *mut c_char; /// Print the pass timings since static dtors aren't picking them up. pub fn LLVMRustPrintPassTimings(); diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index a5ac70286fe81..f313b778c48cc 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -86,13 +86,17 @@ use core::slice; use core::str; use libc; +enum CStringInner { + Owned(*mut libc::c_char), + NotOwned(*const libc::c_char), +} + /// The representation of a C String. /// /// This structure wraps a `*libc::c_char`, and will automatically free the /// memory it is pointing to when it goes out of scope. pub struct CString { - buf: *const libc::c_char, - owns_buffer_: bool, + inner: CStringInner, } impl Clone for CString { @@ -102,19 +106,19 @@ impl Clone for CString { fn clone(&self) -> CString { let len = self.len() + 1; let buf = unsafe { malloc_raw(len) } as *mut libc::c_char; - unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, len); } - CString { buf: buf as *const libc::c_char, owns_buffer_: true } + unsafe { ptr::copy_nonoverlapping_memory(buf, self.as_ptr(), len); } + CString { inner: Owned(buf) } } } impl PartialEq for CString { fn eq(&self, other: &CString) -> bool { // Check if the two strings share the same buffer - if self.buf as uint == other.buf as uint { + if self.as_ptr() as uint == other.as_ptr() as uint { true } else { unsafe { - libc::strcmp(self.buf, other.buf) == 0 + libc::strcmp(self.as_ptr(), other.as_ptr()) == 0 } } } @@ -144,9 +148,20 @@ impl CString { ///# Failure /// /// Fails if `buf` is null - pub unsafe fn new(buf: *const libc::c_char, owns_buffer: bool) -> CString { + pub unsafe fn new(buf: *const libc::c_char) -> CString { + assert!(!buf.is_null()); + CString { inner: NotOwned(buf) } + } + + /// Like CString::new except that `buf` will be freed when the value goes + /// out of scope. + /// + ///# Failure + /// + /// Fails if `buf` is null + pub unsafe fn new_owned(buf: *mut libc::c_char) -> CString { assert!(!buf.is_null()); - CString { buf: buf, owns_buffer_: owns_buffer } + CString { inner: Owned(buf) } } /// Return a pointer to the NUL-terminated string data. @@ -179,8 +194,12 @@ impl CString { /// } /// } /// ``` + #[inline] pub fn as_ptr(&self) -> *const libc::c_char { - self.buf + match self.inner { + Owned(buf) => buf as *const libc::c_char, + NotOwned(buf) => buf, + } } /// Return a mutable pointer to the NUL-terminated string data. @@ -200,37 +219,44 @@ impl CString { /// // wrong (the CString will be freed, invalidating `p`) /// let p = foo.to_c_str().as_mut_ptr(); /// ``` + #[inline] pub fn as_mut_ptr(&mut self) -> *mut libc::c_char { - self.buf as *mut _ + match self.inner { + Owned(buf) => buf, + NotOwned(buf) => buf as *mut libc::c_char, + } } /// Calls a closure with a reference to the underlying `*libc::c_char`. #[deprecated="use `.as_ptr()`"] pub fn with_ref(&self, f: |*const libc::c_char| -> T) -> T { - f(self.buf) + f(self.as_ptr()) } /// Calls a closure with a mutable reference to the underlying `*libc::c_char`. #[deprecated="use `.as_mut_ptr()`"] pub fn with_mut_ref(&mut self, f: |*mut libc::c_char| -> T) -> T { - f(self.buf as *mut libc::c_char) + f(self.as_mut_ptr()) } /// Returns true if the CString is a null. #[deprecated="a CString cannot be null"] pub fn is_null(&self) -> bool { - self.buf.is_null() + self.as_ptr().is_null() } /// Returns true if the CString is not null. #[deprecated="a CString cannot be null"] pub fn is_not_null(&self) -> bool { - self.buf.is_not_null() + self.as_ptr().is_not_null() } /// Returns whether or not the `CString` owns the buffer. pub fn owns_buffer(&self) -> bool { - self.owns_buffer_ + match self.inner { + Owned(_) => true, + NotOwned(_) => false, + } } /// Converts the CString into a `&[u8]` without copying. @@ -238,7 +264,7 @@ impl CString { #[inline] pub fn as_bytes<'a>(&'a self) -> &'a [u8] { unsafe { - mem::transmute(Slice { data: self.buf, len: self.len() + 1 }) + mem::transmute(Slice { data: self.as_ptr(), len: self.len() + 1 }) } } @@ -247,7 +273,7 @@ impl CString { #[inline] pub fn as_bytes_no_nul<'a>(&'a self) -> &'a [u8] { unsafe { - mem::transmute(Slice { data: self.buf, len: self.len() }) + mem::transmute(Slice { data: self.as_ptr(), len: self.len() }) } } @@ -262,7 +288,7 @@ impl CString { /// Return a CString iterator. pub fn iter<'a>(&'a self) -> CChars<'a> { CChars { - ptr: self.buf, + ptr: self.as_ptr(), marker: marker::ContravariantLifetime, } } @@ -279,18 +305,20 @@ impl CString { /// Prefer `.as_ptr()` when just retrieving a pointer to the /// string data, as that does not relinquish ownership. pub unsafe fn unwrap(mut self) -> *const libc::c_char { - self.owns_buffer_ = false; - self.buf + let ret = self.as_ptr(); + self.inner = NotOwned(ret); + ret } } impl Drop for CString { fn drop(&mut self) { - if self.owns_buffer_ { - unsafe { - libc::free(self.buf as *mut libc::c_void) - } + match self.inner { + Owned(buf) => unsafe { + libc::free(buf as *mut libc::c_void) + }, + _ => {}, } } } @@ -299,7 +327,7 @@ impl Collection for CString { /// Return the number of bytes in the CString (not including the NUL terminator). #[inline] fn len(&self) -> uint { - let mut cur = self.buf; + let mut cur = self.as_ptr(); let mut len = 0; unsafe { while *cur != 0 { @@ -430,7 +458,7 @@ impl<'a> ToCStr for &'a [u8] { ptr::copy_memory(buf, self.as_ptr(), self_len); *buf.offset(self_len as int) = 0; - CString::new(buf as *const libc::c_char, true) + CString::new_owned(buf as *mut i8) } fn with_c_str(&self, f: |*const libc::c_char| -> T) -> T { @@ -515,7 +543,7 @@ pub unsafe fn from_c_multistring(buf: *const libc::c_char, }; while ((limited_count && ctr < limit) || !limited_count) && *(curr_ptr as *const libc::c_char) != 0 as libc::c_char { - let cstr = CString::new(curr_ptr as *const libc::c_char, false); + let cstr = CString::new(curr_ptr as *const libc::c_char); f(&cstr); curr_ptr += cstr.len() + 1; ctr += 1; @@ -680,7 +708,7 @@ mod tests { #[test] #[should_fail] fn test_new_fail() { - let _c_str = unsafe { CString::new(ptr::null(), false) }; + let _c_str = unsafe { CString::new(ptr::null()) }; } #[test] @@ -696,7 +724,7 @@ mod tests { let s = "test".to_string(); let c = s.to_c_str(); // give the closure a non-owned CString - let mut c_ = unsafe { CString::new(c.as_ptr(), false) }; + let mut c_ = unsafe { CString::new(c.as_ptr()) }; f(&c_); // muck with the buffer for later printing unsafe { *c_.as_mut_ptr() = 'X' as libc::c_char } diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index ed8ff821f5cad..d0a9770237381 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -243,7 +243,7 @@ pub mod dl { let ret = if ptr::null() == last_error { Ok(result) } else { - Err(String::from_str(CString::new(last_error, false).as_str() + Err(String::from_str(CString::new(last_error).as_str() .unwrap())) }; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index e758dec6bff94..f772984ec4e3e 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -98,7 +98,7 @@ pub fn getcwd() -> Path { if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() { fail!() } - Path::new(CString::new(buf.as_ptr(), false)) + Path::new(CString::new(buf.as_ptr())) } } @@ -286,7 +286,7 @@ pub fn env_as_bytes() -> Vec<(Vec,Vec)> { let mut result = Vec::new(); while *environ != 0 as *const _ { let env_pair = - CString::new(*environ, false).as_bytes_no_nul().to_vec(); + CString::new(*environ).as_bytes_no_nul().to_vec(); result.push(env_pair); environ = environ.offset(1); } @@ -353,7 +353,7 @@ pub fn getenv_as_bytes(n: &str) -> Option> { if s.is_null() { None } else { - Some(CString::new(s as *const i8, false).as_bytes_no_nul().to_vec()) + Some(CString::new(s as *const i8).as_bytes_no_nul().to_vec()) } }) } @@ -1101,7 +1101,7 @@ unsafe fn load_argc_and_argv(argc: int, use c_str::CString; Vec::from_fn(argc as uint, |i| { - CString::new(*argv.offset(i as int), false).as_bytes_no_nul().to_vec() + CString::new(*argv.offset(i as int)).as_bytes_no_nul().to_vec() }) } @@ -1168,7 +1168,7 @@ fn real_args_as_bytes() -> Vec> { let tmp = objc_msgSend(args, objectAtSel, i); let utf_c_str: *const libc::c_char = mem::transmute(objc_msgSend(tmp, utf8Sel)); - let s = CString::new(utf_c_str, false); + let s = CString::new(utf_c_str); res.push(s.as_bytes_no_nul().to_vec()) } } diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs index e05e533be56c5..992e226e9c2e7 100644 --- a/src/libstd/rt/backtrace.rs +++ b/src/libstd/rt/backtrace.rs @@ -383,7 +383,7 @@ mod imp { output(w, idx,addr, None) } else { output(w, idx, addr, Some(unsafe { - CString::new(info.dli_sname, false) + CString::new(info.dli_sname) })) } } @@ -518,7 +518,7 @@ mod imp { if ret == 0 || data.is_null() { output(w, idx, addr, None) } else { - output(w, idx, addr, Some(unsafe { CString::new(data, false) })) + output(w, idx, addr, Some(unsafe { CString::new(data) })) } } @@ -993,7 +993,7 @@ mod imp { if ret == libc::TRUE { try!(write!(w, " - ")); - let cstr = unsafe { CString::new(info.Name.as_ptr(), false) }; + let cstr = unsafe { CString::new(info.Name.as_ptr()) }; let bytes = cstr.as_bytes(); match cstr.as_str() { Some(s) => try!(super::demangle(w, s)), diff --git a/src/test/run-pass/unix-process-spawn-errno.rs b/src/test/run-pass/unix-process-spawn-errno.rs index 42b78e4ec6616..108f3144c38d8 100644 --- a/src/test/run-pass/unix-process-spawn-errno.rs +++ b/src/test/run-pass/unix-process-spawn-errno.rs @@ -24,7 +24,7 @@ use rustrt::c_str; macro_rules! c_string { ($s:expr) => { { let ptr = concat!($s, "\0").as_ptr() as *const i8; - unsafe { &c_str::CString::new(ptr, false) } + unsafe { &c_str::CString::new(ptr) } } } } diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index 570b881650ae8..9c911ad7ffbef 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -21,7 +21,7 @@ extern { unsafe fn check(expected: &str, f: |*mut c_char| -> T) { let mut x = [0i8, ..50]; f(&mut x[0] as *mut c_char); - let res = CString::new(&x[0], false); + let res = CString::new(&x[0]); assert_eq!(expected, res.as_str().unwrap()); } From 1970ccc2efe654e686f912564f5f0ed1cb00f4fa Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Fri, 17 Oct 2014 23:51:56 +0800 Subject: [PATCH 2/2] Change return type of StrSlice::slice_shift_char --- src/libcollections/str.rs | 4 ++-- src/libcore/str.rs | 18 +++++++++--------- src/libglob/lib.rs | 11 +++++------ src/libsyntax/ext/asm.rs | 4 ++-- src/libsyntax/print/pprust.rs | 2 +- src/liburl/lib.rs | 4 ++-- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index f49371b8e8862..5b65be36797f2 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1348,13 +1348,13 @@ mod tests { #[test] fn test_slice_shift_char() { let data = "ประเทศไทย中"; - assert_eq!(data.slice_shift_char(), (Some('ป'), "ระเทศไทย中")); + assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中"))); } #[test] fn test_slice_shift_char_2() { let empty = ""; - assert_eq!(empty.slice_shift_char(), (None, "")); + assert_eq!(empty.slice_shift_char(), None); } #[test] diff --git a/src/libcore/str.rs b/src/libcore/str.rs index e8cd93ba7dc42..0b70e4ffb2b00 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -1784,21 +1784,21 @@ pub trait StrSlice<'a> { /// it. This does not allocate a new string; instead, it returns a /// slice that point one character beyond the character that was /// shifted. If the string does not contain any characters, - /// a tuple of None and an empty string is returned instead. + /// None is returned instead. /// /// # Example /// /// ```rust /// let s = "Löwe 老虎 Léopard"; - /// let (c, s1) = s.slice_shift_char(); - /// assert_eq!(c, Some('L')); + /// let (c, s1) = s.slice_shift_char().unwrap(); + /// assert_eq!(c, 'L'); /// assert_eq!(s1, "öwe 老虎 Léopard"); /// - /// let (c, s2) = s1.slice_shift_char(); - /// assert_eq!(c, Some('ö')); + /// let (c, s2) = s1.slice_shift_char().unwrap(); + /// assert_eq!(c, 'ö'); /// assert_eq!(s2, "we 老虎 Léopard"); /// ``` - fn slice_shift_char(&self) -> (Option, &'a str); + fn slice_shift_char(&self) -> Option<(char, &'a str)>; /// Returns the byte offset of an inner slice relative to an enclosing outer slice. /// @@ -2148,13 +2148,13 @@ impl<'a> StrSlice<'a> for &'a str { } #[inline] - fn slice_shift_char(&self) -> (Option, &'a str) { + fn slice_shift_char(&self) -> Option<(char, &'a str)> { if self.is_empty() { - return (None, *self); + return None; } else { let CharRange {ch, next} = self.char_range_at(0u); let next_s = unsafe { raw::slice_bytes(*self, next, self.len()) }; - return (Some(ch), next_s); + return Some((ch, next_s)); } } diff --git a/src/libglob/lib.rs b/src/libglob/lib.rs index 0313c22933cfa..a12d7a361ee68 100644 --- a/src/libglob/lib.rs +++ b/src/libglob/lib.rs @@ -404,11 +404,11 @@ impl Pattern { return EntirePatternDoesntMatch; } - let (some_c, next) = file.slice_shift_char(); - if require_literal(some_c.unwrap()) { + let (c, next) = file.slice_shift_char().unwrap(); + if require_literal(c) { return SubPatternDoesntMatch; } - prev_char.set(some_c); + prev_char.set(Some(c)); file = next; } } @@ -417,8 +417,7 @@ impl Pattern { return EntirePatternDoesntMatch; } - let (some_c, next) = file.slice_shift_char(); - let c = some_c.unwrap(); + let (c, next) = file.slice_shift_char().unwrap(); let matches = match *token { AnyChar => { !require_literal(c) @@ -445,7 +444,7 @@ impl Pattern { if !matches { return SubPatternDoesntMatch; } - prev_char.set(some_c); + prev_char.set(Some(c)); file = next; } } diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index 702be0c0eeede..99e9b4513c5d5 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -96,8 +96,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) // cannot be shared with any other operand (usually when // a register is clobbered early.) let output = match constraint.get().slice_shift_char() { - (Some('='), _) => None, - (Some('+'), operand) => { + Some(('=', _)) => None, + Some(('+', operand)) => { Some(token::intern_and_get_ident(format!( "={}", operand).as_slice())) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d32828192e996..b6a2ea6871963 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1765,7 +1765,7 @@ impl<'a> State<'a> { try!(self.commasep(Inconsistent, a.outputs.as_slice(), |s, &(ref co, ref o, is_rw)| { match co.get().slice_shift_char() { - (Some('='), operand) if is_rw => { + Some(('=', operand)) if is_rw => { try!(s.print_string(format!("+{}", operand).as_slice(), ast::CookedStr)) } diff --git a/src/liburl/lib.rs b/src/liburl/lib.rs index bf9a959afffbd..cd957de5a9e31 100644 --- a/src/liburl/lib.rs +++ b/src/liburl/lib.rs @@ -706,8 +706,8 @@ fn get_query_fragment(rawurl: &str) -> DecodeResult<(Query, Option)> { }; match before_fragment.slice_shift_char() { - (Some('?'), rest) => Ok((try!(query_from_str(rest)), fragment)), - (None, "") => Ok((vec!(), fragment)), + Some(('?', rest)) => Ok((try!(query_from_str(rest)), fragment)), + None => Ok((vec!(), fragment)), _ => Err(format!("Query didn't start with '?': '{}..'", before_fragment)), } }