From 9567c1c62066a601d0ec88d7874c49881dacc8b2 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 3 Apr 2015 22:42:19 -0600 Subject: [PATCH 1/9] Fixed bug calling .note() instead of .help(). Added small note when two different closures fail typechecking. See #24036 --- src/librustc/middle/infer/error_reporting.rs | 2 +- src/librustc/middle/ty.rs | 10 +++++++++- src/librustc/session/mod.rs | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 36229a558e955..cc31e62ca2828 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -812,7 +812,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { } self.give_suggestion(same_regions); for &(ref trace, terr) in trace_origins { - self.report_type_error(trace.clone(), &terr); + self.report_and_explain_type_error(trace.clone(), &terr); } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 1123c9236312a..8dff4d2e5651e 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -5096,7 +5096,7 @@ pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) -> String { } } -pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) { +pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) { match *err { terr_regions_does_not_outlive(subregion, superregion) => { note_and_explain_region(cx, "", subregion, "..."); @@ -5127,6 +5127,14 @@ pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) { "expected concrete lifetime is ", conc_region, ""); } + terr_sorts(values) => { + let expected_str = ty_sort_string(cx, values.expected); + let found_str = ty_sort_string(cx, values.found); + if expected_str == found_str && expected_str == "closure" { + cx.sess.note(&format!("no two closures, even if identical, have the same type")); + cx.sess.help(&format!("consider boxing your closure and/or using it as a trait object")); + } + } _ => {} } } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3e3e5e17963cd..698b681bd55ae 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -155,7 +155,7 @@ impl Session { self.diagnostic().handler().note(msg) } pub fn help(&self, msg: &str) { - self.diagnostic().handler().note(msg) + self.diagnostic().handler().help(msg) } pub fn opt_span_bug(&self, opt_sp: Option, msg: &str) -> ! { match opt_sp { From 5f4858e101479859ec950bceefc5e2cda2e0f58e Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sat, 4 Apr 2015 12:03:15 -0600 Subject: [PATCH 2/9] Tidier --- src/librustc/middle/ty.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8dff4d2e5651e..ad525387b294d 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -5132,7 +5132,8 @@ pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) { let found_str = ty_sort_string(cx, values.found); if expected_str == found_str && expected_str == "closure" { cx.sess.note(&format!("no two closures, even if identical, have the same type")); - cx.sess.help(&format!("consider boxing your closure and/or using it as a trait object")); + cx.sess.help(&format!("consider boxing your closure and/or \ + using it as a trait object")); } } _ => {} From 3308c06e33855f89627b417fd6b57f76d9df50a1 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sat, 4 Apr 2015 14:30:23 -0600 Subject: [PATCH 3/9] Added test for #24036, using spans to display note/help for this message now --- src/librustc/middle/infer/error_reporting.rs | 3 +- src/librustc/middle/infer/mod.rs | 2 +- src/librustc/middle/ty.rs | 7 +++-- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- src/test/compile-fail/issue-24036.rs | 30 ++++++++++++++++++++ 6 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 src/test/compile-fail/issue-24036.rs diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index cc31e62ca2828..03e76f5ee2573 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -373,8 +373,9 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { fn report_and_explain_type_error(&self, trace: TypeTrace<'tcx>, terr: &ty::type_err<'tcx>) { + let span = trace.origin.span(); self.report_type_error(trace, terr); - ty::note_and_explain_type_err(self.tcx, terr); + ty::note_and_explain_type_err(self.tcx, terr, span); } /// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index b11e25c059d08..0f62b440bf32d 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -987,7 +987,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { error_str)); if let Some(err) = err { - ty::note_and_explain_type_err(self.tcx, err) + ty::note_and_explain_type_err(self.tcx, err, sp) } } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index ad525387b294d..76581529a46f0 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -5096,7 +5096,7 @@ pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) -> String { } } -pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) { +pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>, sp: Span) { match *err { terr_regions_does_not_outlive(subregion, superregion) => { note_and_explain_region(cx, "", subregion, "..."); @@ -5131,8 +5131,9 @@ pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) { let expected_str = ty_sort_string(cx, values.expected); let found_str = ty_sort_string(cx, values.found); if expected_str == found_str && expected_str == "closure" { - cx.sess.note(&format!("no two closures, even if identical, have the same type")); - cx.sess.help(&format!("consider boxing your closure and/or \ + cx.sess.span_note(sp, &format!("no two closures, even if identical, have the same \ + type")); + cx.sess.span_help(sp, &format!("consider boxing your closure and/or \ using it as a trait object")); } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 156fbfede9c98..ce4eab9988dd4 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3709,7 +3709,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, .ty_to_string( actual_structure_type), type_error_description); - ty::note_and_explain_type_err(tcx, &type_error); + ty::note_and_explain_type_err(tcx, &type_error, path.span); } } } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 9d6c04b1ad49d..be3fc860b2b12 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -200,7 +200,7 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>, msg(), ty::type_err_to_str(tcx, terr)); - ty::note_and_explain_type_err(tcx, terr); + ty::note_and_explain_type_err(tcx, terr, span); false } } diff --git a/src/test/compile-fail/issue-24036.rs b/src/test/compile-fail/issue-24036.rs new file mode 100644 index 0000000000000..3c8a64eaf7de4 --- /dev/null +++ b/src/test/compile-fail/issue-24036.rs @@ -0,0 +1,30 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn closure_to_loc() { + let mut x = |c| c + 1; + x = |c| c + 1; + //~^ ERROR mismatched types + //~| NOTE no two closures, even if identical, have the same type + //~| HELP consider boxing your closure and/or using it as a trait object +} + +fn closure_from_match() { + let x = match 1usize { + 1 => |c| c + 1, + 2 => |c| c - 1, + _ => |c| c - 1 + }; + //~^^^^^ ERROR match arms have incompatible types + //~| NOTE no two closures, even if identical, have the same type + //~| HELP consider boxing your closure and/or using it as a trait object +} + +fn main() { } From 117512348b1f63443508cc4acf3cb8ec48918ebe Mon Sep 17 00:00:00 2001 From: Luke Gallagher Date: Sat, 11 Apr 2015 17:13:24 +1000 Subject: [PATCH 4/9] Add tests for #16602 Closes #16602 --- src/test/run-pass/issue-16602-1.rs | 15 +++++++++++++ src/test/run-pass/issue-16602-2.rs | 21 ++++++++++++++++++ src/test/run-pass/issue-16602-3.rs | 34 ++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/test/run-pass/issue-16602-1.rs create mode 100644 src/test/run-pass/issue-16602-2.rs create mode 100644 src/test/run-pass/issue-16602-3.rs diff --git a/src/test/run-pass/issue-16602-1.rs b/src/test/run-pass/issue-16602-1.rs new file mode 100644 index 0000000000000..ee638edad6cb5 --- /dev/null +++ b/src/test/run-pass/issue-16602-1.rs @@ -0,0 +1,15 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let mut t = [1; 2]; + t = [t[1] * 2, t[0] * 2]; + assert_eq!(&t[..], &[2, 2]); +} diff --git a/src/test/run-pass/issue-16602-2.rs b/src/test/run-pass/issue-16602-2.rs new file mode 100644 index 0000000000000..742eb6c280e39 --- /dev/null +++ b/src/test/run-pass/issue-16602-2.rs @@ -0,0 +1,21 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct A { + pub x: u32, + pub y: u32, +} + +fn main() { + let mut a = A { x: 1, y: 1 }; + a = A { x: a.y * 2, y: a.x * 2 }; + assert_eq!(a.x, 2); + assert_eq!(a.y, 2); +} diff --git a/src/test/run-pass/issue-16602-3.rs b/src/test/run-pass/issue-16602-3.rs new file mode 100644 index 0000000000000..d29932dcf6836 --- /dev/null +++ b/src/test/run-pass/issue-16602-3.rs @@ -0,0 +1,34 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[derive(Debug)] +enum Foo { + Bar(u32, u32), + Baz(&'static u32, &'static u32) +} + +static NUM: u32 = 100; + +fn main () { + let mut b = Foo::Baz(&NUM, &NUM); + b = Foo::Bar(f(&b), g(&b)); +} + +static FNUM: u32 = 1; + +fn f (b: &Foo) -> u32 { + FNUM +} + +static GNUM: u32 = 2; + +fn g (b: &Foo) -> u32 { + GNUM +} From 91ca622cdf8502c37a867bea02f400a8ae5e9d4c Mon Sep 17 00:00:00 2001 From: Michael Alexander Date: Sun, 12 Apr 2015 10:42:05 +0800 Subject: [PATCH 5/9] Updated dead link in Traits chapter of book to point to Trait Objects chapter. --- src/doc/trpl/traits.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index 2986de4179b89..25f5c7cacc771 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -273,8 +273,8 @@ not, because both the trait and the type aren't in our crate. One last thing about traits: generic functions with a trait bound use *monomorphization* (*mono*: one, *morph*: form), so they are statically -dispatched. What's that mean? Check out the chapter on [static and dynamic -dispatch](static-and-dynamic-dispatch.html) for more. +dispatched. What's that mean? Check out the chapter on [trait +objects](trait-objects.html) for more. ## Multiple trait bounds From 912a872d3c7e12a5d9784c3bfd4cd3c911e468d9 Mon Sep 17 00:00:00 2001 From: Theo Belaire Date: Sun, 12 Apr 2015 01:10:53 -0400 Subject: [PATCH 6/9] Fixed with_extension documentation bug It was mistakenly calling it with "foo.txt" instead of "txt". I've also added an assert. --- src/libstd/path.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 4471b5afa84c8..9215c93ca1c6f 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1574,7 +1574,8 @@ impl Path { /// /// let path = Path::new("/tmp/foo.rs"); /// - /// let new_path = path.with_extension("foo.txt"); + /// let new_path = path.with_extension("txt"); + /// assert_eq!(new_path, PathBuf::from("/tmp/foo.txt")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn with_extension>(&self, extension: S) -> PathBuf { From 5c80b7aabbbcd140dfefee745a8bad41262ac753 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 9 Apr 2015 08:59:48 -0700 Subject: [PATCH 7/9] Simplify iterator logic for Fuse --- src/libcore/iter.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 527a7297f85b9..9f378748d2007 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2197,13 +2197,9 @@ impl Iterator for Fuse where I: Iterator { if self.done { None } else { - match self.iter.next() { - None => { - self.done = true; - None - } - x => x - } + let next = self.iter.next(); + self.done = next.is_none(); + next } } @@ -2224,13 +2220,9 @@ impl DoubleEndedIterator for Fuse where I: DoubleEndedIterator { if self.done { None } else { - match self.iter.next_back() { - None => { - self.done = true; - None - } - x => x - } + let next = self.iter.next_back(); + self.done = next.is_none(); + next } } } From 11c184616842e26836ed541e9ec1236f85c63334 Mon Sep 17 00:00:00 2001 From: Igor Strebezhev Date: Sun, 12 Apr 2015 14:48:19 +0400 Subject: [PATCH 8/9] mod.rs documentary fix Docs meant that Option is returned though the function returns Result. --- src/libcore/num/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 4e4a928d91f72..3fd179cf86f3a 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -2705,7 +2705,7 @@ macro_rules! from_str_radix_float_impl { /// /// # Return value /// - /// `Err(ParseIntError)` if the string did not represent a valid number. Otherwise, + /// `Err(ParseFloatError)` if the string did not represent a valid number. /// Otherwise, `Ok(n)` where `n` is the floating-point number represented by `src`. #[inline] #[allow(deprecated)] @@ -2734,7 +2734,7 @@ macro_rules! from_str_radix_float_impl { /// /// # Return value /// - /// `Err(ParseIntError)` if the string did not represent a valid number. Otherwise, + /// `Err(ParseFloatError)` if the string did not represent a valid number. /// Otherwise, `Ok(n)` where `n` is the floating-point number represented by `src`. fn from_str_radix(src: &str, radix: u32) -> Result<$T, ParseFloatError> { From dd82599cdfe959f748cffa7b698c67f943e53358 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sun, 12 Apr 2015 20:34:28 +0530 Subject: [PATCH 9/9] fixup --- src/libstd/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 9215c93ca1c6f..6f5d27e9da145 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1575,7 +1575,7 @@ impl Path { /// let path = Path::new("/tmp/foo.rs"); /// /// let new_path = path.with_extension("txt"); - /// assert_eq!(new_path, PathBuf::from("/tmp/foo.txt")); + /// assert_eq!(new_path, Path::new("/tmp/foo.txt")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn with_extension>(&self, extension: S) -> PathBuf {