From 6857c93183480ba49647bcafb103458cf4adff70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Fri, 29 Nov 2019 12:11:12 +0300 Subject: [PATCH 01/14] Check break target availability when checking breaks with values Fixes #66702 --- src/librustc_typeck/check/expr.rs | 18 ++++++++++++++---- .../issue-66702-break-outside-loop-val.rs | 7 +++++++ .../issue-66702-break-outside-loop-val.stderr | 11 +++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/issues/issue-66702-break-outside-loop-val.rs create mode 100644 src/test/ui/issues/issue-66702-break-outside-loop-val.stderr diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 4766360c04897..5bfc60c754067 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -582,11 +582,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If this is a break with a value, we need to type-check // the expression. Get an expected type from the loop context. let opt_coerce_to = { + // We should release `enclosing_breakables` before the `check_expr_with_hint` + // below, so can't move this block of code to the enclosing scope and share + // `ctxt` with the second `encloding_breakables` borrow below. let mut enclosing_breakables = self.enclosing_breakables.borrow_mut(); - enclosing_breakables.find_breakable(target_id) - .coerce - .as_ref() - .map(|coerce| coerce.expected_ty()) + match enclosing_breakables.opt_find_breakable(target_id) { + Some(ctxt) => + ctxt.coerce.as_ref().map(|coerce| coerce.expected_ty()), + None => { // Avoid ICE when `break` is inside a closure (#65383). + self.tcx.sess.delay_span_bug( + expr.span, + "break was outside loop, but no error was emitted", + ); + return tcx.types.err; + } + } }; // If the loop context is not a `loop { }`, then break with diff --git a/src/test/ui/issues/issue-66702-break-outside-loop-val.rs b/src/test/ui/issues/issue-66702-break-outside-loop-val.rs new file mode 100644 index 0000000000000..bd3c00d262128 --- /dev/null +++ b/src/test/ui/issues/issue-66702-break-outside-loop-val.rs @@ -0,0 +1,7 @@ +// Breaks with values inside closures used to ICE (#66863) + +fn main() { + 'some_label: loop { + || break 'some_label (); //~ ERROR: `break` inside of a closure + } +} diff --git a/src/test/ui/issues/issue-66702-break-outside-loop-val.stderr b/src/test/ui/issues/issue-66702-break-outside-loop-val.stderr new file mode 100644 index 0000000000000..83bde9775b2ec --- /dev/null +++ b/src/test/ui/issues/issue-66702-break-outside-loop-val.stderr @@ -0,0 +1,11 @@ +error[E0267]: `break` inside of a closure + --> $DIR/issue-66702-break-outside-loop-val.rs:5:12 + | +LL | || break 'some_label (); + | -- ^^^^^^^^^^^^^^^^^^^^ cannot `break` inside of a closure + | | + | enclosing closure + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0267`. From 52649ddfbd7cd8c5eb1a66ef3f593cdfb6174d55 Mon Sep 17 00:00:00 2001 From: Sen Jiang Date: Tue, 3 Dec 2019 14:31:41 -0800 Subject: [PATCH 02/14] Fix documentation of pattern for str::matches() Made it the same as rmatches() --- src/libcore/str/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 25b7eec5b3343..b2a420f3c4377 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3371,8 +3371,8 @@ impl str { /// An iterator over the disjoint matches of a pattern within the given string /// slice. /// - /// The pattern can be any type that implements the Pattern trait. Notable - /// examples are `&str`, [`char`], and closures that determines the split. + /// The pattern can be a `&str`, [`char`], or a closure that determines if + /// a character matches. /// /// # Iterator behavior /// From 1fa948f4ccf73aa0a0d903878693c685710cd764 Mon Sep 17 00:00:00 2001 From: Andrew Banchich Date: Tue, 3 Dec 2019 19:11:53 -0500 Subject: [PATCH 03/14] capitalize Rust --- src/libcore/sync/atomic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index c9ccef972c2b5..69c4aa7f30f45 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -27,7 +27,7 @@ //! //! Atomic variables are safe to share between threads (they implement [`Sync`]) //! but they do not themselves provide the mechanism for sharing and follow the -//! [threading model](../../../std/thread/index.html#the-threading-model) of rust. +//! [threading model](../../../std/thread/index.html#the-threading-model) of Rust. //! The most common way to share an atomic variable is to put it into an [`Arc`][arc] (an //! atomically-reference-counted shared pointer). //! From f6b435d923e5979cd3579427901d2140a932dfc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 3 Dec 2019 19:01:42 -0800 Subject: [PATCH 04/14] Accurately portray raw identifiers in error messages When refering to or suggesting raw identifiers, refer to them with `r#`. Fix #65634. --- src/librustc/ty/print/pretty.rs | 3 +++ src/libsyntax_pos/symbol.rs | 6 +++++ .../ui/parser/raw/raw-literal-keywords.rs | 4 ++-- .../ui/parser/raw/raw-literal-keywords.stderr | 4 ++-- src/test/ui/raw-ident-suggestion.rs | 22 +++++++++++++++++++ src/test/ui/raw-ident-suggestion.stderr | 22 +++++++++++++++++++ .../ui/suggestions/raw-name-use-suggestion.rs | 2 +- .../raw-name-use-suggestion.stderr | 2 +- 8 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/raw-ident-suggestion.rs create mode 100644 src/test/ui/raw-ident-suggestion.stderr diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index fff2f06e87b8e..745f7d0276d80 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -1282,6 +1282,9 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { if !self.empty_path { write!(self, "::")?; } + if ast::Ident::from_str(&name).is_raw_guess() { + write!(self, "r#")?; + } write!(self, "{}", name)?; // FIXME(eddyb) this will print e.g. `{{closure}}#3`, but it diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 88a325112ac6c..73df24a836dc3 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -840,12 +840,18 @@ impl Hash for Ident { impl fmt::Debug for Ident { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.is_raw_guess() { + write!(f, "r#")?; + } write!(f, "{}{:?}", self.name, self.span.ctxt()) } } impl fmt::Display for Ident { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.is_raw_guess() { + write!(f, "r#")?; + } fmt::Display::fmt(&self.name, f) } } diff --git a/src/test/ui/parser/raw/raw-literal-keywords.rs b/src/test/ui/parser/raw/raw-literal-keywords.rs index bf9cbcdab2e89..a986980fab97b 100644 --- a/src/test/ui/parser/raw/raw-literal-keywords.rs +++ b/src/test/ui/parser/raw/raw-literal-keywords.rs @@ -11,11 +11,11 @@ fn test_union() { } fn test_if_2() { - let _ = r#if; //~ ERROR cannot find value `if` in this scope + let _ = r#if; //~ ERROR cannot find value `r#if` in this scope } fn test_struct_2() { - let _ = r#struct; //~ ERROR cannot find value `struct` in this scope + let _ = r#struct; //~ ERROR cannot find value `r#struct` in this scope } fn test_union_2() { diff --git a/src/test/ui/parser/raw/raw-literal-keywords.stderr b/src/test/ui/parser/raw/raw-literal-keywords.stderr index fd8eda3770d27..f7b6c894a90fe 100644 --- a/src/test/ui/parser/raw/raw-literal-keywords.stderr +++ b/src/test/ui/parser/raw/raw-literal-keywords.stderr @@ -16,13 +16,13 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found LL | r#union Test; | ^^^^ expected one of 8 possible tokens -error[E0425]: cannot find value `if` in this scope +error[E0425]: cannot find value `r#if` in this scope --> $DIR/raw-literal-keywords.rs:14:13 | LL | let _ = r#if; | ^^^^ not found in this scope -error[E0425]: cannot find value `struct` in this scope +error[E0425]: cannot find value `r#struct` in this scope --> $DIR/raw-literal-keywords.rs:18:13 | LL | let _ = r#struct; diff --git a/src/test/ui/raw-ident-suggestion.rs b/src/test/ui/raw-ident-suggestion.rs new file mode 100644 index 0000000000000..b928510258b2f --- /dev/null +++ b/src/test/ui/raw-ident-suggestion.rs @@ -0,0 +1,22 @@ +#![allow(non_camel_case_types)] + +trait r#async { + fn r#struct(&self) { + println!("async"); + } +} + +trait r#await { + fn r#struct(&self) { + println!("await"); + } +} + +struct r#fn {} + +impl r#async for r#fn {} +impl r#await for r#fn {} + +fn main() { + r#fn {}.r#struct(); //~ ERROR multiple applicable items in scope +} diff --git a/src/test/ui/raw-ident-suggestion.stderr b/src/test/ui/raw-ident-suggestion.stderr new file mode 100644 index 0000000000000..fddd9427ab786 --- /dev/null +++ b/src/test/ui/raw-ident-suggestion.stderr @@ -0,0 +1,22 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/raw-ident-suggestion.rs:21:13 + | +LL | r#fn {}.r#struct(); + | ^^^^^^^^ multiple `r#struct` found + | +note: candidate #1 is defined in an impl of the trait `async` for the type `r#fn` + --> $DIR/raw-ident-suggestion.rs:4:5 + | +LL | fn r#struct(&self) { + | ^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `async::r#struct(r#fn {})` instead +note: candidate #2 is defined in an impl of the trait `await` for the type `r#fn` + --> $DIR/raw-ident-suggestion.rs:10:5 + | +LL | fn r#struct(&self) { + | ^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `await::r#struct(r#fn {})` instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0034`. diff --git a/src/test/ui/suggestions/raw-name-use-suggestion.rs b/src/test/ui/suggestions/raw-name-use-suggestion.rs index 6c01383d9610d..0a8073c0be2ea 100644 --- a/src/test/ui/suggestions/raw-name-use-suggestion.rs +++ b/src/test/ui/suggestions/raw-name-use-suggestion.rs @@ -5,5 +5,5 @@ mod foo { fn main() { foo::let(); //~ ERROR expected identifier, found keyword `let` - r#break(); //~ ERROR cannot find function `break` in this scope + r#break(); //~ ERROR cannot find function `r#break` in this scope } diff --git a/src/test/ui/suggestions/raw-name-use-suggestion.stderr b/src/test/ui/suggestions/raw-name-use-suggestion.stderr index 58eb87c00a411..62b76318e09b5 100644 --- a/src/test/ui/suggestions/raw-name-use-suggestion.stderr +++ b/src/test/ui/suggestions/raw-name-use-suggestion.stderr @@ -20,7 +20,7 @@ help: you can escape reserved keywords to use them as identifiers LL | foo::r#let(); | ^^^^^ -error[E0425]: cannot find function `break` in this scope +error[E0425]: cannot find function `r#break` in this scope --> $DIR/raw-name-use-suggestion.rs:8:5 | LL | r#break(); From 168e35d56935b265d9c3ce767430f40ed7448d05 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 3 Dec 2019 22:20:05 -0500 Subject: [PATCH 05/14] Include a span in more `expected...found` notes In most places, we use a span when emitting `expected...found` errors. However, there were a couple of places where we didn't use any span, resulting in hard-to-interpret error messages. This commit attaches the relevant span to these notes, and additionally switches over to using `note_expected_found` instead of manually formatting the message --- src/librustc/infer/error_reporting/mod.rs | 15 ++++--- src/librustc/infer/error_reporting/note.rs | 20 +++++++--- .../project-fn-ret-invariant.transmute.stderr | 20 +++++++--- src/test/ui/c-variadic/variadic-ffi-4.stderr | 10 +++-- .../dyn-trait.stderr | 20 +++++++--- src/test/ui/issues/issue-16683.stderr | 10 +++-- src/test/ui/issues/issue-17758.stderr | 10 +++-- .../ui/issues/issue-20831-debruijn.stderr | 16 ++++++-- src/test/ui/issues/issue-52213.stderr | 10 +++-- src/test/ui/issues/issue-55796.stderr | 20 +++++++--- src/test/ui/nll/issue-55394.stderr | 10 +++-- .../ui/nll/normalization-bounds-error.stderr | 10 +++-- .../ui/nll/type-alias-free-regions.stderr | 40 +++++++++++++------ .../constant-in-expr-inherent-1.stderr | 10 +++-- .../constant-in-expr-trait-item-3.stderr | 10 +++-- .../object-lifetime-default-elision.stderr | 20 +++++++--- .../region-object-lifetime-in-coercion.stderr | 20 +++++++--- ...-type-region-bound-in-trait-not-met.stderr | 20 +++++++--- ...-type-static-bound-in-trait-not-met.stderr | 10 +++-- .../regions-close-object-into-object-2.stderr | 10 +++-- .../regions-close-object-into-object-4.stderr | 10 +++-- ...-close-over-type-parameter-multiple.stderr | 10 +++-- .../ui/regions/regions-creating-enums4.stderr | 20 +++++++--- .../ui/regions/regions-escape-method.stderr | 10 +++-- .../regions-escape-via-trait-or-not.stderr | 10 +++-- src/test/ui/regions/regions-nested-fns.stderr | 15 +++++-- ...ions-normalize-in-where-clause-list.stderr | 13 ++++-- .../ui/regions/regions-ret-borrowed-1.stderr | 10 +++-- .../ui/regions/regions-ret-borrowed.stderr | 10 +++-- .../regions-trait-object-subtyping.stderr | 10 +++-- .../ui/reject-specialized-drops-8142.stderr | 10 +++-- ...trait-has-wrong-lifetime-parameters.stderr | 10 +++-- .../dyn-trait-underscore.stderr | 10 +++-- 33 files changed, 325 insertions(+), 134 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 5a940f2f80aa2..58c1498faa9de 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1809,12 +1809,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { sub_region, "...", ); - err.note(&format!( - "...so that the {}:\nexpected {}\n found {}", - sup_trace.cause.as_requirement_str(), - sup_expected.content(), - sup_found.content() + err.span_note(sup_trace.cause.span, &format!( + "...so that the {}", + sup_trace.cause.as_requirement_str() )); + + err.note_expected_found( + &"", + sup_expected, + &"", + sup_found + ); err.emit(); return; } diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index c1f840ad67815..4b933735fc75f 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -13,12 +13,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { match *origin { infer::Subtype(ref trace) => { if let Some((expected, found)) = self.values_str(&trace.values) { - let expected = expected.content(); - let found = found.content(); - err.note(&format!("...so that the {}:\nexpected {}\n found {}", - trace.cause.as_requirement_str(), - expected, - found)); + err.span_note( + trace.cause.span, + &format!( + "...so that the {}", + trace.cause.as_requirement_str() + ) + ); + + err.note_expected_found( + &"", + expected, + &"", + found + ); } else { // FIXME: this really should be handled at some earlier stage. Our // handling of region checking when type errors are present is diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr index 627609c4a9c00..3e39c8a792446 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr @@ -9,13 +9,21 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined on the fun | LL | fn baz<'a,'b>(x: Type<'a>) -> Type<'static> { | ^^ - = note: ...so that the expression is assignable: - expected Type<'_> - found Type<'a> +note: ...so that the expression is assignable + --> $DIR/project-fn-ret-invariant.rs:48:13 + | +LL | bar(foo, x) + | ^ + = note: expected `Type<'_>` + found `Type<'a>` = note: but, the lifetime must be valid for the static lifetime... - = note: ...so that the expression is assignable: - expected Type<'static> - found Type<'_> +note: ...so that the expression is assignable + --> $DIR/project-fn-ret-invariant.rs:48:4 + | +LL | bar(foo, x) + | ^^^^^^^^^^^ + = note: expected `Type<'static>` + found `Type<'_>` error: aborting due to previous error diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr index c80ed5ebf5cef..cd4cd8b198de8 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr @@ -49,9 +49,13 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th | LL | let _ = ap.with_copy(|ap| { ap }); | ^^^^^^^^^^^ - = note: ...so that the expression is assignable: - expected core::ffi::VaList<'_, '_> - found core::ffi::VaList<'_, '_> +note: ...so that the expression is assignable + --> $DIR/variadic-ffi-4.rs:16:33 + | +LL | let _ = ap.with_copy(|ap| { ap }); + | ^^ + = note: expected `core::ffi::VaList<'_, '_>` + found `core::ffi::VaList<'_, '_>` note: but, the lifetime must be valid for the method call at 16:13... --> $DIR/variadic-ffi-4.rs:16:13 | diff --git a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr index 5e80c673258b8..3300293bb36ca 100644 --- a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr +++ b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr @@ -9,13 +9,21 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined on the fun | LL | fn with_dyn_debug_static<'a>(x: Box) { | ^^ - = note: ...so that the expression is assignable: - expected std::boxed::Box - found std::boxed::Box<(dyn std::fmt::Debug + 'a)> +note: ...so that the expression is assignable + --> $DIR/dyn-trait.rs:20:16 + | +LL | static_val(x); + | ^ + = note: expected `std::boxed::Box` + found `std::boxed::Box<(dyn std::fmt::Debug + 'a)>` = note: but, the lifetime must be valid for the static lifetime... - = note: ...so that the types are compatible: - expected StaticTrait - found StaticTrait +note: ...so that the types are compatible + --> $DIR/dyn-trait.rs:20:5 + | +LL | static_val(x); + | ^^^^^^^^^^ + = note: expected `StaticTrait` + found `StaticTrait` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-16683.stderr b/src/test/ui/issues/issue-16683.stderr index b663e213ed05e..99700f2084e4a 100644 --- a/src/test/ui/issues/issue-16683.stderr +++ b/src/test/ui/issues/issue-16683.stderr @@ -21,9 +21,13 @@ note: but, the lifetime must be valid for the lifetime `'a` as defined on the tr | LL | trait T<'a> { | ^^ - = note: ...so that the types are compatible: - expected &'a Self - found &Self +note: ...so that the types are compatible + --> $DIR/issue-16683.rs:4:14 + | +LL | self.a(); + | ^ + = note: expected `&'a Self` + found `&Self` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17758.stderr b/src/test/ui/issues/issue-17758.stderr index adcbb62e3d5bd..adfc3f5085826 100644 --- a/src/test/ui/issues/issue-17758.stderr +++ b/src/test/ui/issues/issue-17758.stderr @@ -22,9 +22,13 @@ note: but, the lifetime must be valid for the lifetime `'a` as defined on the tr | LL | trait Foo<'a> { | ^^ - = note: ...so that the types are compatible: - expected &'a Self - found &Self +note: ...so that the types are compatible + --> $DIR/issue-17758.rs:7:14 + | +LL | self.foo(); + | ^^^ + = note: expected `&'a Self` + found `&Self` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index 13c9c09461eae..c7fd134a129de 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -88,9 +88,19 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined on | LL | impl<'a> Publisher<'a> for MyStruct<'a> { | ^^ - = note: ...so that the types are compatible: - expected Publisher<'_> - found Publisher<'_> +note: ...so that the types are compatible + --> $DIR/issue-20831-debruijn.rs:28:5 + | +LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { +LL | | // Not obvious, but there is an implicit lifetime here -------^ +LL | | +LL | | +... | +LL | | self.sub = t; +LL | | } + | |_____^ + = note: expected `Publisher<'_>` + found `Publisher<'_>` error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-52213.stderr b/src/test/ui/issues/issue-52213.stderr index b79a5ddf3e1bf..a8960f7756367 100644 --- a/src/test/ui/issues/issue-52213.stderr +++ b/src/test/ui/issues/issue-52213.stderr @@ -9,9 +9,13 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined on the fun | LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { | ^^ - = note: ...so that the types are compatible: - expected (&&(T,),) - found (&&'a (T,),) +note: ...so that the types are compatible + --> $DIR/issue-52213.rs:2:11 + | +LL | match (&t,) { + | ^^^^^ + = note: expected `(&&(T,),)` + found `(&&'a (T,),)` note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 1:27... --> $DIR/issue-52213.rs:1:27 | diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr index 7b910f5e3e5a6..b8cafdc5c14b5 100644 --- a/src/test/ui/issues/issue-55796.stderr +++ b/src/test/ui/issues/issue-55796.stderr @@ -15,9 +15,13 @@ note: ...so that the type `std::iter::Map<>::EdgesIter, [closu LL | Box::new(self.out_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: but, the lifetime must be valid for the static lifetime... - = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> - found std::boxed::Box>::Node>> +note: ...so that the expression is assignable + --> $DIR/issue-55796.rs:16:9 + | +LL | Box::new(self.out_edges(u).map(|e| e.target())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)>` + found `std::boxed::Box>::Node>>` error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/issue-55796.rs:21:9 @@ -36,9 +40,13 @@ note: ...so that the type `std::iter::Map<>::EdgesIter, [closu LL | Box::new(self.in_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: but, the lifetime must be valid for the static lifetime... - = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> - found std::boxed::Box>::Node>> +note: ...so that the expression is assignable + --> $DIR/issue-55796.rs:21:9 + | +LL | Box::new(self.in_edges(u).map(|e| e.target())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)>` + found `std::boxed::Box>::Node>>` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/issue-55394.stderr b/src/test/ui/nll/issue-55394.stderr index 714a63b670c66..69a6ab004fd91 100644 --- a/src/test/ui/nll/issue-55394.stderr +++ b/src/test/ui/nll/issue-55394.stderr @@ -21,9 +21,13 @@ note: but, the lifetime must be valid for the lifetime `'_` as defined on the im | LL | impl Foo<'_> { | ^^ - = note: ...so that the expression is assignable: - expected Foo<'_> - found Foo<'_> +note: ...so that the expression is assignable + --> $DIR/issue-55394.rs:9:9 + | +LL | Foo { bar } + | ^^^^^^^^^^^ + = note: expected `Foo<'_>` + found `Foo<'_>` error: aborting due to previous error diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr index 3a152fbc6fce8..58f206742f4f5 100644 --- a/src/test/ui/nll/normalization-bounds-error.stderr +++ b/src/test/ui/nll/normalization-bounds-error.stderr @@ -14,9 +14,13 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined on | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} | ^^ - = note: ...so that the types are compatible: - expected Visitor<'d> - found Visitor<'_> +note: ...so that the types are compatible + --> $DIR/normalization-bounds-error.rs:12:1 + | +LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `Visitor<'d>` + found `Visitor<'_>` error: aborting due to previous error diff --git a/src/test/ui/nll/type-alias-free-regions.stderr b/src/test/ui/nll/type-alias-free-regions.stderr index 6986389af8814..5191deca281cc 100644 --- a/src/test/ui/nll/type-alias-free-regions.stderr +++ b/src/test/ui/nll/type-alias-free-regions.stderr @@ -11,17 +11,25 @@ LL | / fn from_box(b: Box) -> Self { LL | | C { f: b } LL | | } | |_____^ - = note: ...so that the expression is assignable: - expected std::boxed::Box> - found std::boxed::Box> +note: ...so that the expression is assignable + --> $DIR/type-alias-free-regions.rs:17:16 + | +LL | C { f: b } + | ^ + = note: expected `std::boxed::Box>` + found `std::boxed::Box>` note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 15:6... --> $DIR/type-alias-free-regions.rs:15:6 | LL | impl<'a> FromBox<'a> for C<'a> { | ^^ - = note: ...so that the expression is assignable: - expected C<'a> - found C<'_> +note: ...so that the expression is assignable + --> $DIR/type-alias-free-regions.rs:17:9 + | +LL | C { f: b } + | ^^^^^^^^^^ + = note: expected `C<'a>` + found `C<'_>` error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/type-alias-free-regions.rs:27:16 @@ -36,17 +44,25 @@ LL | / fn from_tuple(b: (B,)) -> Self { LL | | C { f: Box::new(b.0) } LL | | } | |_____^ - = note: ...so that the expression is assignable: - expected std::boxed::Box<&isize> - found std::boxed::Box<&isize> +note: ...so that the expression is assignable + --> $DIR/type-alias-free-regions.rs:27:25 + | +LL | C { f: Box::new(b.0) } + | ^^^ + = note: expected `std::boxed::Box<&isize>` + found `std::boxed::Box<&isize>` note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 25:6... --> $DIR/type-alias-free-regions.rs:25:6 | LL | impl<'a> FromTuple<'a> for C<'a> { | ^^ - = note: ...so that the expression is assignable: - expected C<'a> - found C<'_> +note: ...so that the expression is assignable + --> $DIR/type-alias-free-regions.rs:27:9 + | +LL | C { f: Box::new(b.0) } + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `C<'a>` + found `C<'_>` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr index 4ebd991078864..37be450fd0a79 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr @@ -9,9 +9,13 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined on the fun | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { | ^^ - = note: ...so that the types are compatible: - expected Foo<'_> - found Foo<'a> +note: ...so that the types are compatible + --> $DIR/constant-in-expr-inherent-1.rs:8:5 + | +LL | >::C + | ^^^^^^^^^^^^ + = note: expected `Foo<'_>` + found `Foo<'a>` = note: but, the lifetime must be valid for the static lifetime... note: ...so that reference does not outlive borrowed content --> $DIR/constant-in-expr-inherent-1.rs:8:5 diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr index d61659e7e9afc..4ee32847c5ec8 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr @@ -9,9 +9,13 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined on the fun | LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { | ^^ - = note: ...so that the types are compatible: - expected Foo<'_> - found Foo<'a> +note: ...so that the types are compatible + --> $DIR/constant-in-expr-trait-item-3.rs:10:5 + | +LL | T::C + | ^^^^ + = note: expected `Foo<'_>` + found `Foo<'a>` = note: but, the lifetime must be valid for the static lifetime... note: ...so that reference does not outlive borrowed content --> $DIR/constant-in-expr-trait-item-3.rs:10:5 diff --git a/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr b/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr index d66322c48ec98..1952ee8269d5b 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr @@ -19,9 +19,13 @@ note: but, the lifetime must be valid for the lifetime `'b` as defined on the fu | LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait { | ^^ - = note: ...so that the expression is assignable: - expected &'b (dyn SomeTrait + 'b) - found &dyn SomeTrait +note: ...so that the expression is assignable + --> $DIR/object-lifetime-default-elision.rs:71:5 + | +LL | ss + | ^^ + = note: expected `&'b (dyn SomeTrait + 'b)` + found `&dyn SomeTrait` error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/object-lifetime-default-elision.rs:71:5 @@ -44,9 +48,13 @@ note: but, the lifetime must be valid for the lifetime `'b` as defined on the fu | LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait { | ^^ - = note: ...so that the expression is assignable: - expected &'b (dyn SomeTrait + 'b) - found &dyn SomeTrait +note: ...so that the expression is assignable + --> $DIR/object-lifetime-default-elision.rs:71:5 + | +LL | ss + | ^^ + = note: expected `&'b (dyn SomeTrait + 'b)` + found `&dyn SomeTrait` error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 14934d6fa4899..e889651647034 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -34,17 +34,25 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined on the fun | LL | fn d<'a,'b>(v: &'a [u8]) -> Box { | ^^ - = note: ...so that the expression is assignable: - expected &[u8] - found &'a [u8] +note: ...so that the expression is assignable + --> $DIR/region-object-lifetime-in-coercion.rs:26:14 + | +LL | Box::new(v) + | ^ + = note: expected `&[u8]` + found `&'a [u8]` note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 25:9... --> $DIR/region-object-lifetime-in-coercion.rs:25:9 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box { | ^^ - = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn Foo + 'b)> - found std::boxed::Box +note: ...so that the expression is assignable + --> $DIR/region-object-lifetime-in-coercion.rs:26:5 + | +LL | Box::new(v) + | ^^^^^^^^^^^ + = note: expected `std::boxed::Box<(dyn Foo + 'b)>` + found `std::boxed::Box` error: aborting due to 4 previous errors diff --git a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr index a636c9ef22c83..865e967fba32e 100644 --- a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr +++ b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr @@ -9,9 +9,13 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined on the imp | LL | impl<'a> Foo<'static> for &'a i32 { | ^^ - = note: ...so that the types are compatible: - expected Foo<'static> - found Foo<'static> +note: ...so that the types are compatible + --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:14:10 + | +LL | impl<'a> Foo<'static> for &'a i32 { + | ^^^^^^^^^^^^ + = note: expected `Foo<'static>` + found `Foo<'static>` = note: but, the lifetime must be valid for the static lifetime... note: ...so that the type `&i32` will meet its required lifetime bounds --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:14:10 @@ -30,9 +34,13 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined on the imp | LL | impl<'a,'b> Foo<'b> for &'a i64 { | ^^ - = note: ...so that the types are compatible: - expected Foo<'b> - found Foo<'_> +note: ...so that the types are compatible + --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:19:13 + | +LL | impl<'a,'b> Foo<'b> for &'a i64 { + | ^^^^^^^ + = note: expected `Foo<'b>` + found `Foo<'_>` note: but, the lifetime must be valid for the lifetime `'b` as defined on the impl at 19:9... --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:19:9 | diff --git a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr index 81256e3b46cbb..6a34871c07efd 100644 --- a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr +++ b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr @@ -9,9 +9,13 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined on the imp | LL | impl<'a> Foo for &'a i32 { | ^^ - = note: ...so that the types are compatible: - expected Foo - found Foo +note: ...so that the types are compatible + --> $DIR/regions-assoc-type-static-bound-in-trait-not-met.rs:9:10 + | +LL | impl<'a> Foo for &'a i32 { + | ^^^ + = note: expected `Foo` + found `Foo` = note: but, the lifetime must be valid for the static lifetime... note: ...so that the type `&i32` will meet its required lifetime bounds --> $DIR/regions-assoc-type-static-bound-in-trait-not-met.rs:9:10 diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 8e473dad69341..28873ab807f8d 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -15,9 +15,13 @@ note: ...so that the type `(dyn A + 'a)` is not borrowed for too long LL | box B(&*v) as Box | ^^^ = note: but, the lifetime must be valid for the static lifetime... - = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn X + 'static)> - found std::boxed::Box +note: ...so that the expression is assignable + --> $DIR/regions-close-object-into-object-2.rs:10:5 + | +LL | box B(&*v) as Box + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `std::boxed::Box<(dyn X + 'static)>` + found `std::boxed::Box` error: aborting due to previous error diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index c80d13e15b147..449a5b5fdd4d6 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -15,9 +15,13 @@ note: ...so that the type `(dyn A + 'a)` is not borrowed for too long LL | box B(&*v) as Box | ^^^ = note: but, the lifetime must be valid for the static lifetime... - = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn X + 'static)> - found std::boxed::Box +note: ...so that the expression is assignable + --> $DIR/regions-close-object-into-object-4.rs:10:5 + | +LL | box B(&*v) as Box + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `std::boxed::Box<(dyn X + 'static)>` + found `std::boxed::Box` error: aborting due to previous error diff --git a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr b/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr index ef21316ea83ae..b2a7afaf1b452 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr +++ b/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr @@ -19,9 +19,13 @@ note: but, the lifetime must be valid for the lifetime `'c` as defined on the fu | LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box { | ^^ - = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn SomeTrait + 'c)> - found std::boxed::Box +note: ...so that the expression is assignable + --> $DIR/regions-close-over-type-parameter-multiple.rs:20:5 + | +LL | box v as Box + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `std::boxed::Box<(dyn SomeTrait + 'c)>` + found `std::boxed::Box` error: aborting due to previous error diff --git a/src/test/ui/regions/regions-creating-enums4.stderr b/src/test/ui/regions/regions-creating-enums4.stderr index 12b89787d5f18..58f74e4ee142d 100644 --- a/src/test/ui/regions/regions-creating-enums4.stderr +++ b/src/test/ui/regions/regions-creating-enums4.stderr @@ -9,17 +9,25 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined on the fun | LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { | ^^ - = note: ...so that the expression is assignable: - expected &Ast<'_> - found &Ast<'a> +note: ...so that the expression is assignable + --> $DIR/regions-creating-enums4.rs:7:14 + | +LL | Ast::Add(x, y) + | ^ + = note: expected `&Ast<'_>` + found `&Ast<'a>` note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 6:19... --> $DIR/regions-creating-enums4.rs:6:19 | LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { | ^^ - = note: ...so that the expression is assignable: - expected Ast<'b> - found Ast<'_> +note: ...so that the expression is assignable + --> $DIR/regions-creating-enums4.rs:7:5 + | +LL | Ast::Add(x, y) + | ^^^^^^^^^^^^^^ + = note: expected `Ast<'b>` + found `Ast<'_>` error: aborting due to previous error diff --git a/src/test/ui/regions/regions-escape-method.stderr b/src/test/ui/regions/regions-escape-method.stderr index b93dd0d4c57c9..ffc2a259485aa 100644 --- a/src/test/ui/regions/regions-escape-method.stderr +++ b/src/test/ui/regions/regions-escape-method.stderr @@ -9,9 +9,13 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th | LL | s.f(|p| p) | ^^^^^ - = note: ...so that the expression is assignable: - expected &i32 - found &i32 +note: ...so that the expression is assignable + --> $DIR/regions-escape-method.rs:15:13 + | +LL | s.f(|p| p) + | ^ + = note: expected `&i32` + found `&i32` note: but, the lifetime must be valid for the method call at 15:5... --> $DIR/regions-escape-method.rs:15:5 | diff --git a/src/test/ui/regions/regions-escape-via-trait-or-not.stderr b/src/test/ui/regions/regions-escape-via-trait-or-not.stderr index a6b165e2d4444..90823464c56d2 100644 --- a/src/test/ui/regions/regions-escape-via-trait-or-not.stderr +++ b/src/test/ui/regions/regions-escape-via-trait-or-not.stderr @@ -9,9 +9,13 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th | LL | with(|o| o) | ^^^^^ - = note: ...so that the expression is assignable: - expected &isize - found &isize +note: ...so that the expression is assignable + --> $DIR/regions-escape-via-trait-or-not.rs:18:14 + | +LL | with(|o| o) + | ^ + = note: expected `&isize` + found `&isize` note: but, the lifetime must be valid for the expression at 18:5... --> $DIR/regions-escape-via-trait-or-not.rs:18:5 | diff --git a/src/test/ui/regions/regions-nested-fns.stderr b/src/test/ui/regions/regions-nested-fns.stderr index f4eb5c8644f03..8fce1609d7830 100644 --- a/src/test/ui/regions/regions-nested-fns.stderr +++ b/src/test/ui/regions/regions-nested-fns.stderr @@ -29,9 +29,18 @@ LL | | if false { return ay; } LL | | return z; LL | | })); | |_____^ - = note: ...so that the types are compatible: - expected &isize - found &isize +note: ...so that the types are compatible + --> $DIR/regions-nested-fns.rs:13:76 + | +LL | ignore::< Box FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { + | ____________________________________________________________________________^ +LL | | if false { return x; } +LL | | if false { return ay; } +LL | | return z; +LL | | })); + | |_____^ + = note: expected `&isize` + found `&isize` error[E0312]: lifetime of reference outlives lifetime of borrowed content... --> $DIR/regions-nested-fns.rs:14:27 diff --git a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr index d29fd80943f73..8a600d2a1e695 100644 --- a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr +++ b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr @@ -17,9 +17,16 @@ note: ...but the lifetime must also be valid for the lifetime `'b` as defined on | LL | fn bar<'a, 'b>() | ^^ - = note: ...so that the types are compatible: - expected Project<'a, 'b> - found Project<'_, '_> +note: ...so that the types are compatible + --> $DIR/regions-normalize-in-where-clause-list.rs:22:1 + | +LL | / fn bar<'a, 'b>() +LL | | where <() as Project<'a, 'b>>::Item : Eq +LL | | { +LL | | } + | |_^ + = note: expected `Project<'a, 'b>` + found `Project<'_, '_>` error: aborting due to previous error diff --git a/src/test/ui/regions/regions-ret-borrowed-1.stderr b/src/test/ui/regions/regions-ret-borrowed-1.stderr index 49076673ad398..2895a0ccdeec8 100644 --- a/src/test/ui/regions/regions-ret-borrowed-1.stderr +++ b/src/test/ui/regions/regions-ret-borrowed-1.stderr @@ -9,9 +9,13 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th | LL | with(|o| o) | ^^^^^ - = note: ...so that the expression is assignable: - expected &isize - found &isize +note: ...so that the expression is assignable + --> $DIR/regions-ret-borrowed-1.rs:10:14 + | +LL | with(|o| o) + | ^ + = note: expected `&isize` + found `&isize` note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 9:14... --> $DIR/regions-ret-borrowed-1.rs:9:14 | diff --git a/src/test/ui/regions/regions-ret-borrowed.stderr b/src/test/ui/regions/regions-ret-borrowed.stderr index eb1ade27acea7..b74f10f5075eb 100644 --- a/src/test/ui/regions/regions-ret-borrowed.stderr +++ b/src/test/ui/regions/regions-ret-borrowed.stderr @@ -9,9 +9,13 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th | LL | with(|o| o) | ^^^^^ - = note: ...so that the expression is assignable: - expected &isize - found &isize +note: ...so that the expression is assignable + --> $DIR/regions-ret-borrowed.rs:13:14 + | +LL | with(|o| o) + | ^ + = note: expected `&isize` + found `&isize` note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 12:14... --> $DIR/regions-ret-borrowed.rs:12:14 | diff --git a/src/test/ui/regions/regions-trait-object-subtyping.stderr b/src/test/ui/regions/regions-trait-object-subtyping.stderr index ef69f2535dc1e..58b79d212700c 100644 --- a/src/test/ui/regions/regions-trait-object-subtyping.stderr +++ b/src/test/ui/regions/regions-trait-object-subtyping.stderr @@ -36,9 +36,13 @@ note: but, the lifetime must be valid for the lifetime `'b` as defined on the fu | LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { | ^^ - = note: ...so that the expression is assignable: - expected &'b mut (dyn Dummy + 'b) - found &mut (dyn Dummy + 'b) +note: ...so that the expression is assignable + --> $DIR/regions-trait-object-subtyping.rs:15:5 + | +LL | x + | ^ + = note: expected `&'b mut (dyn Dummy + 'b)` + found `&mut (dyn Dummy + 'b)` error[E0308]: mismatched types --> $DIR/regions-trait-object-subtyping.rs:22:5 diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr index e55f0232ff94b..527babb01208f 100644 --- a/src/test/ui/reject-specialized-drops-8142.stderr +++ b/src/test/ui/reject-specialized-drops-8142.stderr @@ -105,9 +105,13 @@ note: ...but the lifetime must also be valid for the lifetime `'l2` as defined o | LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^ - = note: ...so that the types are compatible: - expected W<'l1, 'l2> - found W<'_, '_> +note: ...so that the types are compatible + --> $DIR/reject-specialized-drops-8142.rs:54:1 + | +LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `W<'l1, 'l2>` + found `W<'_, '_>` error: aborting due to 8 previous errors diff --git a/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr b/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr index 88c9c473eb0c7..9fdcd4de495c0 100644 --- a/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr +++ b/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr @@ -14,9 +14,13 @@ note: ...but the lifetime must also be valid for the lifetime `'b` as defined on | LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { | ^^ - = note: ...so that the types are compatible: - expected T1<'a> - found T1<'_> +note: ...so that the types are compatible + --> $DIR/trait-impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:13 + | +LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { + | ^^^^^^^^^^ + = note: expected `T1<'a>` + found `T1<'_>` error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index d0475bf08c38d..e6029e0d4623a 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -18,9 +18,13 @@ note: ...so that reference does not outlive borrowed content LL | Box::new(items.iter()) | ^^^^^ = note: but, the lifetime must be valid for the static lifetime... - = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn std::iter::Iterator + 'static)> - found std::boxed::Box> +note: ...so that the expression is assignable + --> $DIR/dyn-trait-underscore.rs:8:5 + | +LL | Box::new(items.iter()) + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `std::boxed::Box<(dyn std::iter::Iterator + 'static)>` + found `std::boxed::Box>` error: aborting due to previous error From b5ad0cb03302d679e5dc7d7d1157c42ccd72b5b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 3 Dec 2019 22:25:15 -0800 Subject: [PATCH 06/14] review comments: move test --- .../issue-65634-raw-ident-suggestion.rs} | 0 .../issue-65634-raw-ident-suggestion.stderr} | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/test/ui/{raw-ident-suggestion.rs => issues/issue-65634-raw-ident-suggestion.rs} (100%) rename src/test/ui/{raw-ident-suggestion.stderr => issues/issue-65634-raw-ident-suggestion.stderr} (81%) diff --git a/src/test/ui/raw-ident-suggestion.rs b/src/test/ui/issues/issue-65634-raw-ident-suggestion.rs similarity index 100% rename from src/test/ui/raw-ident-suggestion.rs rename to src/test/ui/issues/issue-65634-raw-ident-suggestion.rs diff --git a/src/test/ui/raw-ident-suggestion.stderr b/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr similarity index 81% rename from src/test/ui/raw-ident-suggestion.stderr rename to src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr index fddd9427ab786..c7bb653dc1f14 100644 --- a/src/test/ui/raw-ident-suggestion.stderr +++ b/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr @@ -1,17 +1,17 @@ error[E0034]: multiple applicable items in scope - --> $DIR/raw-ident-suggestion.rs:21:13 + --> $DIR/issue-65634-raw-ident-suggestion.rs:21:13 | LL | r#fn {}.r#struct(); | ^^^^^^^^ multiple `r#struct` found | note: candidate #1 is defined in an impl of the trait `async` for the type `r#fn` - --> $DIR/raw-ident-suggestion.rs:4:5 + --> $DIR/issue-65634-raw-ident-suggestion.rs:4:5 | LL | fn r#struct(&self) { | ^^^^^^^^^^^^^^^^^^ = help: to disambiguate the method call, write `async::r#struct(r#fn {})` instead note: candidate #2 is defined in an impl of the trait `await` for the type `r#fn` - --> $DIR/raw-ident-suggestion.rs:10:5 + --> $DIR/issue-65634-raw-ident-suggestion.rs:10:5 | LL | fn r#struct(&self) { | ^^^^^^^^^^^^^^^^^^ From 0103308ad3745109600541e139af5571838b8791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 3 Dec 2019 22:25:44 -0800 Subject: [PATCH 07/14] Account for raw idents in module file finding --- src/librustc_parse/parser/module.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs index 59d7c2b423972..807defc51c1d3 100644 --- a/src/librustc_parse/parser/module.rs +++ b/src/librustc_parse/parser/module.rs @@ -212,13 +212,13 @@ impl<'a> Parser<'a> { // `./.rs` and `.//mod.rs`. let relative_prefix_string; let relative_prefix = if let Some(ident) = relative { - relative_prefix_string = format!("{}{}", ident, path::MAIN_SEPARATOR); + relative_prefix_string = format!("{}{}", ident.name, path::MAIN_SEPARATOR); &relative_prefix_string } else { "" }; - let mod_name = id.to_string(); + let mod_name = id.name.to_string(); let default_path_str = format!("{}{}.rs", relative_prefix, mod_name); let secondary_path_str = format!("{}{}{}mod.rs", relative_prefix, mod_name, path::MAIN_SEPARATOR); From 4746d37339f77fa4a07be6104e3f6385a8fb67bd Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 5 Dec 2019 04:36:53 +0100 Subject: [PATCH 08/14] E0023: handle expected != pat-tup-type --- src/librustc_typeck/check/demand.rs | 16 +++++++++++--- src/librustc_typeck/check/pat.rs | 21 ++++++++++++------ ...67037-pat-tup-scrut-ty-diff-less-fields.rs | 21 ++++++++++++++++++ ...7-pat-tup-scrut-ty-diff-less-fields.stderr | 22 +++++++++++++++++++ 4 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs create mode 100644 src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 4331d441aa0d2..32df6c4636c2d 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -65,13 +65,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn demand_eqtype_pat( + pub fn demand_eqtype_pat_diag( &self, cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, match_expr_span: Option, - ) { + ) -> Option> { let cause = if let Some(span) = match_expr_span { self.cause( cause_span, @@ -80,9 +80,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { self.misc(cause_span) }; - self.demand_eqtype_with_origin(&cause, expected, actual).map(|mut err| err.emit()); + self.demand_eqtype_with_origin(&cause, expected, actual) } + pub fn demand_eqtype_pat( + &self, + cause_span: Span, + expected: Ty<'tcx>, + actual: Ty<'tcx>, + match_expr_span: Option, + ) { + self.demand_eqtype_pat_diag(cause_span, expected, actual, match_expr_span) + .map(|mut err| err.emit()); + } pub fn demand_coerce(&self, expr: &hir::Expr, diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 9dd3bc624a51a..71d1cd869a6a2 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -703,7 +703,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pat_ty = pat_ty.fn_sig(tcx).output(); let pat_ty = pat_ty.no_bound_vars().expect("expected fn type"); - self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span); + // Type-check the tuple struct pattern against the expected type. + let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, match_arm_pat_span); + let had_err = diag.is_some(); + diag.map(|mut err| err.emit()); // Type-check subpatterns. if subpats.len() == variant.fields.len() @@ -721,7 +724,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } else { // Pattern has wrong number of fields. - self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected); + self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err); on_error(); return tcx.types.err; } @@ -734,8 +737,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { res: Res, qpath: &hir::QPath, subpats: &'tcx [P], - fields: &[ty::FieldDef], - expected: Ty<'tcx> + fields: &'tcx [ty::FieldDef], + expected: Ty<'tcx>, + had_err: bool, ) { let subpats_ending = pluralize!(subpats.len()); let fields_ending = pluralize!(fields.len()); @@ -763,9 +767,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // More generally, the expected type wants a tuple variant with one field of an // N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern // with the subpatterns directly in the tuple variant pattern, e.g., `V_i(p_0, .., p_N)`. - let missing_parenthesis = match expected.kind { - ty::Adt(_, substs) if fields.len() == 1 => { - let field_ty = fields[0].ty(self.tcx, substs); + let missing_parenthesis = match (&expected.kind, fields, had_err) { + // #67037: only do this if we could sucessfully type-check the expected type against + // the tuple struct pattern. Otherwise the substs could get out of range on e.g., + // `let P() = U;` where `P != U` with `struct P(T);`. + (ty::Adt(_, substs), [field], false) => { + let field_ty = self.field_ty(pat_span, field, substs); match field_ty.kind { ty::Tuple(_) => field_ty.tuple_fields().count() == subpats.len(), _ => false, diff --git a/src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs b/src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs new file mode 100644 index 0000000000000..44bd645598ae0 --- /dev/null +++ b/src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs @@ -0,0 +1,21 @@ +// Regression test for #67037. +// +// In type checking patterns, E0023 occurs when the tuple pattern and the expected +// tuple pattern have different number of fields. For example, as below, `P()`, +// the tuple struct pattern, has 0 fields, but requires 1 field. +// +// In emitting E0023, we try to see if this is a case of e.g., `Some(a, b, c)` but where +// the scrutinee was of type `Some((a, b, c))`, and suggest that parenthesis be added. +// +// However, we did not account for the expected type being different than the tuple pattern type. +// This caused an issue when the tuple pattern type (`P`) was generic. +// Specifically, we tried deriving the 0th field's type using the `substs` of the expected type. +// When attempting to substitute `T`, there was no such substitution, so "out of range" occured. + +struct U {} // 0 type parameters offered +struct P(T); // 1 type parameter wanted + +fn main() { + let P() = U {}; //~ ERROR mismatched types + //~^ ERROR this pattern has 0 fields, but the corresponding tuple struct has 1 field +} diff --git a/src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr b/src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr new file mode 100644 index 0000000000000..521dd0256f7d5 --- /dev/null +++ b/src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9 + | +LL | let P() = U {}; + | ^^^ expected struct `U`, found struct `P` + | + = note: expected struct `U` + found struct `P<_>` + +error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 1 field + --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9 + | +LL | struct P(T); // 1 type parameter wanted + | --------------- tuple struct defined here +... +LL | let P() = U {}; + | ^^^ expected 1 field, found 0 + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0023, E0308. +For more information about an error, try `rustc --explain E0023`. From 74804fa3e706d6217127bc6b8d2bf019a4653e74 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 5 Dec 2019 06:38:06 +0100 Subject: [PATCH 09/14] rustc_parser: cleanup imports --- Cargo.lock | 1 - src/librustc_parse/Cargo.toml | 9 ++++---- src/librustc_parse/config.rs | 2 +- src/librustc_parse/lexer/mod.rs | 11 +++++----- src/librustc_parse/lexer/tokentrees.rs | 8 +++----- src/librustc_parse/lexer/unicode_chars.rs | 4 ++-- src/librustc_parse/lib.rs | 4 ++-- src/librustc_parse/parser/attr.rs | 2 +- src/librustc_parse/parser/diagnostics.rs | 25 ++++++++++------------- src/librustc_parse/parser/expr.rs | 17 +++++++-------- src/librustc_parse/parser/generics.rs | 2 +- src/librustc_parse/parser/item.rs | 7 +++---- src/librustc_parse/parser/mod.rs | 13 +++++------- src/librustc_parse/parser/module.rs | 5 ++--- src/librustc_parse/parser/pat.rs | 4 ++-- src/librustc_parse/parser/path.rs | 4 ++-- src/librustc_parse/parser/stmt.rs | 6 +++--- src/librustc_parse/parser/ty.rs | 8 +++----- src/librustc_parse/validate_attr.rs | 2 +- 19 files changed, 58 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e83513af5b37..26727c5c1db60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3806,7 +3806,6 @@ dependencies = [ "rustc_errors", "rustc_feature", "rustc_lexer", - "rustc_target", "smallvec 1.0.0", "syntax", "syntax_pos", diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml index 95b3256f53a38..fb5cb742ab651 100644 --- a/src/librustc_parse/Cargo.toml +++ b/src/librustc_parse/Cargo.toml @@ -12,12 +12,11 @@ doctest = false [dependencies] bitflags = "1.0" log = "0.4" -syntax_pos = { path = "../libsyntax_pos" } -syntax = { path = "../libsyntax" } -errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_lexer = { path = "../librustc_lexer" } -rustc_target = { path = "../librustc_target" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_errors = { path = "../librustc_errors" } rustc_error_codes = { path = "../librustc_error_codes" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +syntax_pos = { path = "../libsyntax_pos" } +syntax = { path = "../libsyntax" } diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs index 1bf6e9ecbc060..30e056e52d25a 100644 --- a/src/librustc_parse/config.rs +++ b/src/librustc_parse/config.rs @@ -10,6 +10,7 @@ use crate::validate_attr; use rustc_feature::Features; +use rustc_errors::Applicability; use syntax::attr::HasAttrs; use syntax::feature_gate::{feature_err, get_features}; use syntax::attr; @@ -21,7 +22,6 @@ use syntax::sess::ParseSess; use syntax::util::map_in_place::MapInPlace; use syntax_pos::symbol::sym; -use errors::Applicability; use smallvec::SmallVec; /// A folder that strips out items that do not belong in the current configuration. diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs index 5de63cb39d16b..ddcfea1898004 100644 --- a/src/librustc_parse/lexer/mod.rs +++ b/src/librustc_parse/lexer/mod.rs @@ -1,16 +1,15 @@ +use rustc_data_structures::sync::Lrc; +use rustc_errors::{FatalError, DiagnosticBuilder}; +use rustc_lexer::Base; +use rustc_lexer::unescape; use syntax::token::{self, Token, TokenKind}; use syntax::sess::ParseSess; -use syntax::symbol::{sym, Symbol}; use syntax::util::comments; - -use errors::{FatalError, DiagnosticBuilder}; +use syntax_pos::symbol::{sym, Symbol}; use syntax_pos::{BytePos, Pos, Span}; -use rustc_lexer::Base; -use rustc_lexer::unescape; use std::char; use std::convert::TryInto; -use rustc_data_structures::sync::Lrc; use log::debug; mod tokentrees; diff --git a/src/librustc_parse/lexer/tokentrees.rs b/src/librustc_parse/lexer/tokentrees.rs index 1353591308b2e..5791c6396c584 100644 --- a/src/librustc_parse/lexer/tokentrees.rs +++ b/src/librustc_parse/lexer/tokentrees.rs @@ -1,13 +1,11 @@ -use rustc_data_structures::fx::FxHashMap; -use syntax_pos::Span; - use super::{StringReader, UnmatchedBrace}; +use rustc_data_structures::fx::FxHashMap; +use rustc_errors::PResult; use syntax::print::pprust::token_to_string; use syntax::token::{self, Token}; use syntax::tokenstream::{DelimSpan, IsJoint::{self, *}, TokenStream, TokenTree, TreeAndJoint}; - -use errors::PResult; +use syntax_pos::Span; impl<'a> StringReader<'a> { crate fn into_token_trees(self) -> (PResult<'a, TokenStream>, Vec) { diff --git a/src/librustc_parse/lexer/unicode_chars.rs b/src/librustc_parse/lexer/unicode_chars.rs index 6eb995b61d3fe..edfebc7de9403 100644 --- a/src/librustc_parse/lexer/unicode_chars.rs +++ b/src/librustc_parse/lexer/unicode_chars.rs @@ -2,9 +2,9 @@ // http://www.unicode.org/Public/security/10.0.0/confusables.txt use super::StringReader; -use errors::{Applicability, DiagnosticBuilder}; -use syntax_pos::{BytePos, Pos, Span, symbol::kw}; use crate::token; +use rustc_errors::{Applicability, DiagnosticBuilder}; +use syntax_pos::{BytePos, Pos, Span, symbol::kw}; #[rustfmt::skip] // for line breaks const UNICODE_ARRAY: &[(char, &str, char)] = &[ diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index a22b383e5f391..a222f3f00c463 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -8,7 +8,7 @@ use syntax::sess::ParseSess; use syntax::token::{self, Nonterminal}; use syntax::tokenstream::{self, TokenStream, TokenTree}; -use errors::{PResult, FatalError, Level, Diagnostic}; +use rustc_errors::{PResult, FatalError, Level, Diagnostic}; use rustc_data_structures::sync::Lrc; use syntax_pos::{Span, SourceFile, FileName}; @@ -53,7 +53,7 @@ pub enum DirectoryOwnership { macro_rules! panictry_buffer { ($handler:expr, $e:expr) => ({ use std::result::Result::{Ok, Err}; - use errors::FatalError; + use rustc_errors::FatalError; match $e { Ok(e) => e, Err(errs) => { diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index c7261404f54ef..b2ae934ce6474 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -1,10 +1,10 @@ use super::{SeqSep, Parser, TokenType, PathStyle}; +use rustc_errors::PResult; use syntax::attr; use syntax::ast; use syntax::util::comments; use syntax::token::{self, Nonterminal}; use syntax_pos::{Span, Symbol}; -use errors::PResult; use log::debug; diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index da8bf89ebf33b..ba125cacab48b 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -1,25 +1,22 @@ use super::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType, SeqSep, Parser}; -use syntax::ast::{ - self, Param, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind, - Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, -}; +use rustc_data_structures::fx::FxHashSet; +use rustc_errors::{self, PResult, Applicability, DiagnosticBuilder, Handler, pluralize}; +use rustc_error_codes::*; +use syntax::ast::{self, Param, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item}; +use syntax::ast::{ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind}; use syntax::token::{self, TokenKind, token_can_begin_expr}; use syntax::print::pprust; use syntax::ptr::P; -use syntax::symbol::{kw, sym}; use syntax::ThinVec; use syntax::util::parser::AssocOp; use syntax::struct_span_err; - -use errors::{PResult, Applicability, DiagnosticBuilder, pluralize}; -use rustc_data_structures::fx::FxHashSet; +use syntax_pos::symbol::{kw, sym}; use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError}; + use log::{debug, trace}; use std::mem; -use rustc_error_codes::*; - const TURBOFISH: &'static str = "use `::<...>` instead of `<...>` to specify type arguments"; /// Creates a placeholder argument. @@ -61,10 +58,10 @@ pub enum Error { } impl Error { - fn span_err>( + fn span_err( self, - sp: S, - handler: &errors::Handler, + sp: impl Into, + handler: &Handler, ) -> DiagnosticBuilder<'_> { match self { Error::FileNotFoundForModule { @@ -212,7 +209,7 @@ impl<'a> Parser<'a> { self.sess.span_diagnostic.span_bug(sp, m) } - pub(super) fn diagnostic(&self) -> &'a errors::Handler { + pub(super) fn diagnostic(&self) -> &'a Handler { &self.sess.span_diagnostic } diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 1112274dc46a5..3cd4988ce0be5 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -4,23 +4,20 @@ use super::pat::{GateOr, PARAM_EXPECTED}; use super::diagnostics::Error; use crate::maybe_recover_from_interpolated_ty_qpath; -use syntax::ast::{ - self, DUMMY_NODE_ID, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode, - Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm, Ty, TyKind, - FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst, Field, Lit, -}; +use rustc_data_structures::thin_vec::ThinVec; +use rustc_errors::{PResult, Applicability}; +use syntax::ast::{self, DUMMY_NODE_ID, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode}; +use syntax::ast::{Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm, Ty, TyKind}; +use syntax::ast::{FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst, Field, Lit}; use syntax::token::{self, Token, TokenKind}; use syntax::print::pprust; use syntax::ptr::P; -use syntax::source_map::{self, Span}; use syntax::util::classify; use syntax::util::literal::LitError; use syntax::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par}; -use syntax_pos::symbol::{kw, sym}; -use syntax_pos::Symbol; -use errors::{PResult, Applicability}; +use syntax_pos::source_map::{self, Span}; +use syntax_pos::symbol::{kw, sym, Symbol}; use std::mem; -use rustc_data_structures::thin_vec::ThinVec; /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression /// dropped into the token stream, which happens while parsing the result of diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs index ba5eafc0ed722..32819cca42b23 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/src/librustc_parse/parser/generics.rs @@ -1,11 +1,11 @@ use super::Parser; +use rustc_errors::PResult; use syntax::ast::{self, WhereClause, GenericParam, GenericParamKind, GenericBounds, Attribute}; use syntax::token; use syntax::source_map::DUMMY_SP; use syntax_pos::symbol::{kw, sym}; -use errors::PResult; impl<'a> Parser<'a> { /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`. diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 66a135274213e..ccf78e6402b3c 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -3,6 +3,8 @@ use super::diagnostics::{Error, dummy_arg, ConsumeClosingDelim}; use crate::maybe_whole; +use rustc_errors::{PResult, Applicability, DiagnosticBuilder, StashKey}; +use rustc_error_codes::*; use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item}; use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind}; use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit}; @@ -14,16 +16,13 @@ use syntax::ptr::P; use syntax::ThinVec; use syntax::token; use syntax::tokenstream::{DelimSpan, TokenTree, TokenStream}; -use syntax::source_map::{self, respan, Span}; use syntax::struct_span_err; use syntax_pos::BytePos; +use syntax_pos::source_map::{self, respan, Span}; use syntax_pos::symbol::{kw, sym, Symbol}; -use rustc_error_codes::*; - use log::debug; use std::mem; -use errors::{PResult, Applicability, DiagnosticBuilder, StashKey}; pub(super) type ItemInfo = (Ident, ItemKind, Option>); diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 28689720044e8..07e99cfe01292 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -14,23 +14,20 @@ use diagnostics::Error; use crate::{Directory, DirectoryOwnership}; use crate::lexer::UnmatchedBrace; -use syntax::ast::{ - self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident, StrLit, - IsAsync, MacArgs, MacDelimiter, Mutability, Visibility, VisibilityKind, Unsafety, -}; - +use rustc_errors::{PResult, Applicability, DiagnosticBuilder, FatalError}; +use rustc_data_structures::thin_vec::ThinVec; +use syntax::ast::{self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident, StrLit}; +use syntax::ast::{IsAsync, MacArgs, MacDelimiter, Mutability, Visibility, VisibilityKind, Unsafety}; use syntax::print::pprust; use syntax::ptr::P; use syntax::token::{self, Token, TokenKind, DelimToken}; use syntax::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint}; use syntax::sess::ParseSess; -use syntax::source_map::respan; use syntax::struct_span_err; use syntax::util::comments::{doc_comment_style, strip_doc_comment_decoration}; +use syntax_pos::source_map::respan; use syntax_pos::symbol::{kw, sym, Symbol}; use syntax_pos::{Span, BytePos, DUMMY_SP, FileName}; -use rustc_data_structures::thin_vec::ThinVec; -use errors::{PResult, Applicability, DiagnosticBuilder, FatalError}; use log::debug; use std::borrow::Cow; diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs index 59d7c2b423972..5b8526caa412f 100644 --- a/src/librustc_parse/parser/module.rs +++ b/src/librustc_parse/parser/module.rs @@ -4,13 +4,12 @@ use super::diagnostics::Error; use crate::{new_sub_parser_from_file, DirectoryOwnership}; +use rustc_errors::PResult; use syntax::attr; use syntax::ast::{self, Ident, Attribute, ItemKind, Mod, Crate}; use syntax::token::{self, TokenKind}; -use syntax::source_map::{SourceMap, Span, DUMMY_SP, FileName}; - +use syntax_pos::source_map::{SourceMap, Span, DUMMY_SP, FileName}; use syntax_pos::symbol::sym; -use errors::PResult; use std::path::{self, Path, PathBuf}; diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 1127c4b2d5f88..42ece96adb99a 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -1,5 +1,6 @@ use super::{Parser, PathStyle}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; +use rustc_errors::{PResult, Applicability, DiagnosticBuilder}; use syntax::ast::{self, Attribute, Pat, PatKind, FieldPat, RangeEnd, RangeSyntax, Mac}; use syntax::ast::{BindingMode, Ident, Mutability, Path, QSelf, Expr, ExprKind}; use syntax::mut_visit::{noop_visit_pat, noop_visit_mac, MutVisitor}; @@ -7,9 +8,8 @@ use syntax::ptr::P; use syntax::print::pprust; use syntax::ThinVec; use syntax::token; -use syntax::source_map::{respan, Span, Spanned}; +use syntax_pos::source_map::{respan, Span, Spanned}; use syntax_pos::symbol::{kw, sym}; -use errors::{PResult, Applicability, DiagnosticBuilder}; type Expected = Option<&'static str>; diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 75bb67d47bc48..70c3458e7c020 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -1,16 +1,16 @@ use super::{Parser, TokenType}; use crate::maybe_whole; +use rustc_errors::{PResult, Applicability, pluralize}; use syntax::ast::{self, QSelf, Path, PathSegment, Ident, ParenthesizedArgs, AngleBracketedArgs}; use syntax::ast::{AnonConst, GenericArg, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode}; use syntax::ast::MacArgs; use syntax::ThinVec; use syntax::token::{self, Token}; -use syntax::source_map::{Span, BytePos}; +use syntax_pos::source_map::{Span, BytePos}; use syntax_pos::symbol::{kw, sym}; use std::mem; use log::debug; -use errors::{PResult, Applicability, pluralize}; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index b952e8814a361..943b6ecc82554 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -6,6 +6,7 @@ use super::diagnostics::Error; use crate::maybe_whole; use crate::DirectoryOwnership; +use rustc_errors::{PResult, Applicability}; use syntax::ThinVec; use syntax::ptr::P; use syntax::ast; @@ -13,11 +14,10 @@ use syntax::ast::{DUMMY_NODE_ID, Stmt, StmtKind, Local, Block, BlockCheckMode, E use syntax::ast::{Attribute, AttrStyle, VisibilityKind, MacStmtStyle, Mac}; use syntax::util::classify; use syntax::token; -use syntax::source_map::{respan, Span}; -use syntax::symbol::{kw, sym}; +use syntax_pos::source_map::{respan, Span}; +use syntax_pos::symbol::{kw, sym}; use std::mem; -use errors::{PResult, Applicability}; impl<'a> Parser<'a> { /// Parses a statement. This stops just before trailing semicolons on everything but items. diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index 321427969051c..84ffef68e9a66 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -3,19 +3,17 @@ use super::item::ParamCfg; use crate::{maybe_whole, maybe_recover_from_interpolated_ty_qpath}; +use rustc_errors::{PResult, Applicability, pluralize}; +use rustc_error_codes::*; use syntax::ptr::P; use syntax::ast::{self, Ty, TyKind, MutTy, BareFnTy, FunctionRetTy, GenericParam, Lifetime, Ident}; use syntax::ast::{TraitBoundModifier, TraitObjectSyntax, GenericBound, GenericBounds, PolyTraitRef}; use syntax::ast::{Mutability, AnonConst, Mac}; use syntax::token::{self, Token}; -use syntax::source_map::Span; use syntax::struct_span_fatal; +use syntax_pos::source_map::Span; use syntax_pos::symbol::kw; -use errors::{PResult, Applicability, pluralize}; - -use rustc_error_codes::*; - /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT`, /// `IDENT<::AssocTy>`. /// diff --git a/src/librustc_parse/validate_attr.rs b/src/librustc_parse/validate_attr.rs index 8601add3f6f96..97e9cb8dcdf6f 100644 --- a/src/librustc_parse/validate_attr.rs +++ b/src/librustc_parse/validate_attr.rs @@ -1,6 +1,6 @@ //! Meta-syntax validation logic of attributes for post-expansion. -use errors::{PResult, Applicability}; +use rustc_errors::{PResult, Applicability}; use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP}; use syntax::ast::{self, Attribute, AttrKind, Ident, MacArgs, MetaItem, MetaItemKind}; use syntax::attr::mk_name_value_item_str; From 0f12711dd0e51cc839c66407c77c83560019c224 Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Thu, 5 Dec 2019 14:59:56 +0100 Subject: [PATCH 10/14] make const-qualif look at more `const fn`s the unstables ones in libcore, with the unstable feature disabled, were not checked --- src/librustc_mir/transform/check_consts/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/src/librustc_mir/transform/check_consts/mod.rs index 7095b3fa0aa83..abad622289005 100644 --- a/src/librustc_mir/transform/check_consts/mod.rs +++ b/src/librustc_mir/transform/check_consts/mod.rs @@ -77,7 +77,11 @@ impl ConstKind { let mode = match tcx.hir().body_owner_kind(hir_id) { HirKind::Closure => return None, - HirKind::Fn if tcx.is_const_fn(def_id) => ConstKind::ConstFn, + // Note: this is deliberately checking for `is_const_fn_raw`, as the `is_const_fn` + // checks take into account the `rustc_const_unstable` attribute combined with enabled + // feature gates. An unstable `const fn` could otherwise be considered "not const" + // by const qualification. See issue #67053 for more details. + HirKind::Fn if tcx.is_const_fn_raw(def_id) => ConstKind::ConstFn, HirKind::Fn => return None, HirKind::Const => ConstKind::Const, From bc0df79db39c00cdb7dae4b6aff62ff9f2efc405 Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Thu, 5 Dec 2019 15:01:30 +0100 Subject: [PATCH 11/14] libcore: rnable 2 unstable const fn features So that we can bootstrap successfully --- src/libcore/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index ec19392450a4b..188ea1a963116 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -74,6 +74,8 @@ #![feature(const_fn)] #![feature(const_fn_union)] #![feature(const_generics)] +#![cfg_attr(not(bootstrap), feature(const_ptr_offset_from))] +#![cfg_attr(not(bootstrap), feature(const_type_name))] #![feature(custom_inner_attributes)] #![feature(decl_macro)] #![feature(doc_cfg)] From 4a760c6ea12a1d15334879b40787f6f0a7056d9d Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Thu, 5 Dec 2019 15:02:41 +0100 Subject: [PATCH 12/14] add regression test for issue 67053 --- .../ui/consts/unstable-const-fn-in-libcore.rs | 29 +++++++++++++++++++ .../unstable-const-fn-in-libcore.stderr | 22 ++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/test/ui/consts/unstable-const-fn-in-libcore.rs create mode 100644 src/test/ui/consts/unstable-const-fn-in-libcore.stderr diff --git a/src/test/ui/consts/unstable-const-fn-in-libcore.rs b/src/test/ui/consts/unstable-const-fn-in-libcore.rs new file mode 100644 index 0000000000000..cad1516fc78d0 --- /dev/null +++ b/src/test/ui/consts/unstable-const-fn-in-libcore.rs @@ -0,0 +1,29 @@ +// This is a non-regression test for const-qualification of unstable items in libcore +// as explained in issue #67053. +// const-qualification could miss some `const fn`s if they were unstable and the feature +// gate was not enabled in libcore. + +#![stable(feature = "core", since = "1.6.0")] +#![feature(const_if_match)] +#![feature(rustc_const_unstable)] +#![feature(staged_api)] + +enum Opt { + Some(T), + None, +} + +impl Opt { + #[rustc_const_unstable(feature = "foo")] + #[stable(feature = "rust1", since = "1.0.0")] + const fn unwrap_or_else T>(self, f: F) -> T { + //~^ ERROR destructors cannot be evaluated at compile-time + //~| ERROR destructors cannot be evaluated at compile-time + match self { + Opt::Some(t) => t, + Opt::None => f(), //~ ERROR E0015 + } + } +} + +fn main() {} diff --git a/src/test/ui/consts/unstable-const-fn-in-libcore.stderr b/src/test/ui/consts/unstable-const-fn-in-libcore.stderr new file mode 100644 index 0000000000000..a8455cefd01cf --- /dev/null +++ b/src/test/ui/consts/unstable-const-fn-in-libcore.stderr @@ -0,0 +1,22 @@ +error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants + --> $DIR/unstable-const-fn-in-libcore.rs:24:26 + | +LL | Opt::None => f(), + | ^^^ + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/unstable-const-fn-in-libcore.rs:19:53 + | +LL | const fn unwrap_or_else T>(self, f: F) -> T { + | ^ constant functions cannot evaluate destructors + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/unstable-const-fn-in-libcore.rs:19:47 + | +LL | const fn unwrap_or_else T>(self, f: F) -> T { + | ^^^^ constant functions cannot evaluate destructors + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0015, E0493. +For more information about an error, try `rustc --explain E0015`. From 473151070bd939239aa8f9bf218e2753b8a479cf Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Sun, 24 Nov 2019 19:00:25 +0100 Subject: [PATCH 13/14] weak-into-raw: Clarify some details in Safety Clarify it is OK to pass a pointer that never owned a weak count (one from Weak::new) back into it as it was created from it. Relates to discussion in #60728. --- src/liballoc/rc.rs | 24 ++++++++++++++---------- src/liballoc/sync.rs | 24 ++++++++++++++---------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index a11f9e8c14579..0f1af8be850ae 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1619,10 +1619,8 @@ impl Weak { /// Returns a raw pointer to the object `T` pointed to by this `Weak`. /// - /// It is up to the caller to ensure that the object is still alive when accessing it through - /// the pointer. - /// - /// The pointer may be [`null`] or be dangling in case the object has already been destroyed. + /// The pointer is valid only if there are some strong references. The pointer may be dangling + /// or even [`null`] otherwise. /// /// # Examples /// @@ -1702,14 +1700,18 @@ impl Weak { /// This can be used to safely get a strong reference (by calling [`upgrade`] /// later) or to deallocate the weak count by dropping the `Weak`. /// - /// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is - /// returned. + /// It takes ownership of one weak count (with the exception of pointers created by [`new`], + /// as these don't have any corresponding weak count). /// /// # Safety /// - /// The pointer must represent one valid weak count. In other words, it must point to `T` which - /// is or *was* managed by an [`Rc`] and the weak count of that [`Rc`] must not have reached - /// 0. It is allowed for the strong count to be 0. + /// The pointer must have originated from the [`into_raw`] (or [`as_raw`], provided there was + /// a corresponding [`forget`] on the `Weak`) and must still own its potential weak reference + /// count. + /// + /// It is allowed for the strong count to be 0 at the time of calling this, but the weak count + /// must be non-zero or the pointer must have originated from a dangling `Weak` (one created + /// by [`new`]). /// /// # Examples /// @@ -1734,11 +1736,13 @@ impl Weak { /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); /// ``` /// - /// [`null`]: ../../std/ptr/fn.null.html /// [`into_raw`]: struct.Weak.html#method.into_raw /// [`upgrade`]: struct.Weak.html#method.upgrade /// [`Rc`]: struct.Rc.html /// [`Weak`]: struct.Weak.html + /// [`as_raw`]: struct.Weak.html#method.as_raw + /// [`new`]: struct.Weak.html#method.new + /// [`forget`]: ../../std/mem/fn.forget.html #[unstable(feature = "weak_into_raw", issue = "60728")] pub unsafe fn from_raw(ptr: *const T) -> Self { if ptr.is_null() { diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 4b10f089c2950..be2d127b133d0 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1295,10 +1295,8 @@ impl Weak { /// Returns a raw pointer to the object `T` pointed to by this `Weak`. /// - /// It is up to the caller to ensure that the object is still alive when accessing it through - /// the pointer. - /// - /// The pointer may be [`null`] or be dangling in case the object has already been destroyed. + /// The pointer is valid only if there are some strong references. The pointer may be dangling + /// or even [`null`] otherwise. /// /// # Examples /// @@ -1379,14 +1377,18 @@ impl Weak { /// This can be used to safely get a strong reference (by calling [`upgrade`] /// later) or to deallocate the weak count by dropping the `Weak`. /// - /// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is - /// returned. + /// It takes ownership of one weak count (with the exception of pointers created by [`new`], + /// as these don't have any corresponding weak count). /// /// # Safety /// - /// The pointer must represent one valid weak count. In other words, it must point to `T` which - /// is or *was* managed by an [`Arc`] and the weak count of that [`Arc`] must not have reached - /// 0. It is allowed for the strong count to be 0. + /// The pointer must have originated from the [`into_raw`] (or [`as_raw'], provided there was + /// a corresponding [`forget`] on the `Weak`) and must still own its potential weak reference + /// count. + /// + /// It is allowed for the strong count to be 0 at the time of calling this, but the weak count + /// must be non-zero or the pointer must have originated from a dangling `Weak` (one created + /// by [`new`]). /// /// # Examples /// @@ -1411,11 +1413,13 @@ impl Weak { /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); /// ``` /// - /// [`null`]: ../../std/ptr/fn.null.html + /// [`as_raw`]: struct.Weak.html#method.as_raw + /// [`new`]: struct.Weak.html#method.new /// [`into_raw`]: struct.Weak.html#method.into_raw /// [`upgrade`]: struct.Weak.html#method.upgrade /// [`Weak`]: struct.Weak.html /// [`Arc`]: struct.Arc.html + /// [`forget`]: ../../std/mem/fn.forget.html #[unstable(feature = "weak_into_raw", issue = "60728")] pub unsafe fn from_raw(ptr: *const T) -> Self { if ptr.is_null() { From 2d83b7608070d6ad250e8cd6d9d5a7d4be628dc4 Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Thu, 5 Dec 2019 17:41:25 +0100 Subject: [PATCH 14/14] update comment to explain the importance of this check more clearly --- src/librustc_mir/transform/check_consts/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/src/librustc_mir/transform/check_consts/mod.rs index abad622289005..82ffafbedf858 100644 --- a/src/librustc_mir/transform/check_consts/mod.rs +++ b/src/librustc_mir/transform/check_consts/mod.rs @@ -79,8 +79,9 @@ impl ConstKind { // Note: this is deliberately checking for `is_const_fn_raw`, as the `is_const_fn` // checks take into account the `rustc_const_unstable` attribute combined with enabled - // feature gates. An unstable `const fn` could otherwise be considered "not const" - // by const qualification. See issue #67053 for more details. + // feature gates. Otherwise, const qualification would _not check_ whether this + // function body follows the `const fn` rules, as an unstable `const fn` would + // be considered "not const". More details are available in issue #67053. HirKind::Fn if tcx.is_const_fn_raw(def_id) => ConstKind::ConstFn, HirKind::Fn => return None,