From 21012714f304e29962a890d6d0e8c0611fc94273 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 10 Jul 2023 14:26:31 +0000 Subject: [PATCH 1/3] Add regression test --- tests/ui/consts/const-fn-cycle.rs | 28 +++++++++++++ tests/ui/consts/const-fn-cycle.stderr | 39 +++++++++++++++++++ .../const-promoted-opaque.atomic.stderr | 39 +++++++++++++++++++ tests/ui/consts/const-promoted-opaque.rs | 33 ++++++++++++++++ .../const-promoted-opaque.string.stderr | 39 +++++++++++++++++++ 5 files changed, 178 insertions(+) create mode 100644 tests/ui/consts/const-fn-cycle.rs create mode 100644 tests/ui/consts/const-fn-cycle.stderr create mode 100644 tests/ui/consts/const-promoted-opaque.atomic.stderr create mode 100644 tests/ui/consts/const-promoted-opaque.rs create mode 100644 tests/ui/consts/const-promoted-opaque.string.stderr diff --git a/tests/ui/consts/const-fn-cycle.rs b/tests/ui/consts/const-fn-cycle.rs new file mode 100644 index 0000000000000..5175296a53e5b --- /dev/null +++ b/tests/ui/consts/const-fn-cycle.rs @@ -0,0 +1,28 @@ +/// Discovered in https://github.com/rust-lang/rust/issues/112602. +/// This caused a cycle error, which made no sense. +/// Removing the `const` part of the `many` function would make the +/// test pass again. +/// The issue was that we were running const qualif checks on +/// `const fn`s, but never using them. During const qualif checks we tend +/// to end up revealing opaque types (the RPIT in `many`'s return type), +/// which can quickly lead to cycles. + +pub struct Parser(H); + +impl Parser +where + H: for<'a> Fn(&'a str) -> T, +{ + pub const fn new(handler: H) -> Parser { + Parser(handler) + } + + pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + //~^ ERROR: cycle detected + Parser::new(|_| unimplemented!()) + } +} + +fn main() { + println!("Hello, world!"); +} diff --git a/tests/ui/consts/const-fn-cycle.stderr b/tests/ui/consts/const-fn-cycle.stderr new file mode 100644 index 0000000000000..7149e72fbb233 --- /dev/null +++ b/tests/ui/consts/const-fn-cycle.stderr @@ -0,0 +1,39 @@ +error[E0391]: cycle detected when computing type of `::many::{opaque#0}` + --> $DIR/const-fn-cycle.rs:20:47 + | +LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires borrow-checking `::many`... + --> $DIR/const-fn-cycle.rs:20:5 + | +LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires promoting constants in MIR for `::many`... + --> $DIR/const-fn-cycle.rs:20:5 + | +LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const checking `::many`... + --> $DIR/const-fn-cycle.rs:20:5 + | +LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing whether `Parser<::many::{opaque#0}>` is freeze... + = note: ...which requires evaluating trait selection obligation `Parser<::many::{opaque#0}>: core::marker::Freeze`... + = note: ...which again requires computing type of `::many::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/const-fn-cycle.rs:1:1 + | +LL | / /// Discovered in https://github.com/rust-lang/rust/issues/112602. +LL | | /// This caused a cycle error, which made no sense. +LL | | /// Removing the `const` part of the `many` function would make the +LL | | /// test pass again. +... | +LL | | println!("Hello, world!"); +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/consts/const-promoted-opaque.atomic.stderr b/tests/ui/consts/const-promoted-opaque.atomic.stderr new file mode 100644 index 0000000000000..67d6ca6853eed --- /dev/null +++ b/tests/ui/consts/const-promoted-opaque.atomic.stderr @@ -0,0 +1,39 @@ +error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` + --> $DIR/const-promoted-opaque.rs:13:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + | +note: ...which requires borrow-checking `FOO`... + --> $DIR/const-promoted-opaque.rs:20:1 + | +LL | const FOO: Foo = std::sync::atomic::AtomicU8::new(42); + | ^^^^^^^^^^^^^^ +note: ...which requires promoting constants in MIR for `FOO`... + --> $DIR/const-promoted-opaque.rs:20:1 + | +LL | const FOO: Foo = std::sync::atomic::AtomicU8::new(42); + | ^^^^^^^^^^^^^^ +note: ...which requires const checking `FOO`... + --> $DIR/const-promoted-opaque.rs:20:1 + | +LL | const FOO: Foo = std::sync::atomic::AtomicU8::new(42); + | ^^^^^^^^^^^^^^ + = note: ...which requires computing whether `Foo` is freeze... + = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Freeze`... + = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/const-promoted-opaque.rs:2:1 + | +LL | / #![feature(type_alias_impl_trait)] +LL | | +LL | | //! Check that we do not cause cycle errors when trying to +LL | | //! obtain information about interior mutability of an opaque type. +... | +LL | | let _: &'static _ = &FOO; +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/consts/const-promoted-opaque.rs b/tests/ui/consts/const-promoted-opaque.rs new file mode 100644 index 0000000000000..11ddab7fb3231 --- /dev/null +++ b/tests/ui/consts/const-promoted-opaque.rs @@ -0,0 +1,33 @@ +// revisions: string unit atomic +#![feature(type_alias_impl_trait)] + +//! Check that we do not cause cycle errors when trying to +//! obtain information about interior mutability of an opaque type. +//! This used to happen, because when the body-analysis failed, we +//! checked the type instead, but the constant was also defining the +//! hidden type of the opaque type. Thus we ended up relying on the +//! result of our analysis to compute the result of our analysis. + +//[unit] check-pass + +type Foo = impl Sized; +//[string,atomic]~^ ERROR cycle detected + +#[cfg(string)] +const FOO: Foo = String::new(); + +#[cfg(atomic)] +const FOO: Foo = std::sync::atomic::AtomicU8::new(42); + +#[cfg(unit)] +const FOO: Foo = (); + +const BAR: () = { + let _: &'static _ = &FOO; +}; + +const BAZ: &Foo = &FOO; + +fn main() { + let _: &'static _ = &FOO; +} diff --git a/tests/ui/consts/const-promoted-opaque.string.stderr b/tests/ui/consts/const-promoted-opaque.string.stderr new file mode 100644 index 0000000000000..7fd4218e36666 --- /dev/null +++ b/tests/ui/consts/const-promoted-opaque.string.stderr @@ -0,0 +1,39 @@ +error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` + --> $DIR/const-promoted-opaque.rs:13:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + | +note: ...which requires borrow-checking `FOO`... + --> $DIR/const-promoted-opaque.rs:17:1 + | +LL | const FOO: Foo = String::new(); + | ^^^^^^^^^^^^^^ +note: ...which requires promoting constants in MIR for `FOO`... + --> $DIR/const-promoted-opaque.rs:17:1 + | +LL | const FOO: Foo = String::new(); + | ^^^^^^^^^^^^^^ +note: ...which requires const checking `FOO`... + --> $DIR/const-promoted-opaque.rs:17:1 + | +LL | const FOO: Foo = String::new(); + | ^^^^^^^^^^^^^^ + = note: ...which requires computing whether `Foo` is freeze... + = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Freeze`... + = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/const-promoted-opaque.rs:2:1 + | +LL | / #![feature(type_alias_impl_trait)] +LL | | +LL | | //! Check that we do not cause cycle errors when trying to +LL | | //! obtain information about interior mutability of an opaque type. +... | +LL | | let _: &'static _ = &FOO; +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. From 55bfcb8c850cbd73ff703da56e1aad8c29f2dee4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 10 Jul 2023 14:26:24 +0000 Subject: [PATCH 2/3] Only call `mir_const_qualif` if absolutely necessary --- compiler/rustc_mir_transform/src/lib.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index fa8257cf9849c..e703b2f518e6a 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -19,6 +19,7 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; +use hir::ConstContext; use required_consts::RequiredConstsVisitor; use rustc_const_eval::util; use rustc_data_structures::fx::FxIndexSet; @@ -231,8 +232,12 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { let const_kind = tcx.hir().body_const_context(def); // No need to const-check a non-const `fn`. - if const_kind.is_none() { - return Default::default(); + match const_kind { + Some(ConstContext::Const | ConstContext::Static(_)) | Some(ConstContext::ConstFn) => {} + None => span_bug!( + tcx.def_span(def), + "`mir_const_qualif` should only be called on const fns and const items" + ), } // N.B., this `borrow()` is guaranteed to be valid (i.e., the value @@ -297,7 +302,21 @@ fn mir_promoted( // Ensure that we compute the `mir_const_qualif` for constants at // this point, before we steal the mir-const result. // Also this means promotion can rely on all const checks having been done. - let const_qualifs = tcx.mir_const_qualif(def); + + let const_qualifs = match tcx.def_kind(def) { + DefKind::Fn | DefKind::AssocFn | DefKind::Closure + if tcx.constness(def) == hir::Constness::Const + || tcx.is_const_default_method(def.to_def_id()) => + { + tcx.mir_const_qualif(def) + } + DefKind::AssocConst + | DefKind::Const + | DefKind::Static(_) + | DefKind::InlineConst + | DefKind::AnonConst => tcx.mir_const_qualif(def), + _ => ConstQualifs::default(), + }; let mut body = tcx.mir_const(def).steal(); if let Some(error_reported) = const_qualifs.tainted_by_errors { body.tainted_by_errors = Some(error_reported); From b39f4594704afe57927c4459d1f0c25a56c0fb01 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 10 Jul 2023 14:38:02 +0000 Subject: [PATCH 3/3] Pessimistically assume opaque types are `!Freeze` --- .../src/transform/check_consts/qualifs.rs | 4 +- tests/ui/consts/const-fn-cycle-tait.rs | 17 +++++ tests/ui/consts/const-fn-cycle-tait.stderr | 11 +++ tests/ui/consts/const-fn-cycle.rs | 19 +++--- tests/ui/consts/const-fn-cycle.stderr | 39 ----------- .../const-promoted-opaque.atomic.stderr | 68 ++++++++++--------- tests/ui/consts/const-promoted-opaque.rs | 5 +- .../const-promoted-opaque.string.stderr | 68 ++++++++++--------- 8 files changed, 115 insertions(+), 116 deletions(-) create mode 100644 tests/ui/consts/const-fn-cycle-tait.rs create mode 100644 tests/ui/consts/const-fn-cycle-tait.stderr delete mode 100644 tests/ui/consts/const-fn-cycle.stderr diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 015a4aa94cd42..963654e466b58 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -7,6 +7,7 @@ use rustc_hir::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir; use rustc_middle::mir::*; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty}; use rustc_trait_selection::traits::{ self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext, @@ -91,7 +92,8 @@ impl Qualif for HasMutInterior { } fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool { - !ty.is_freeze(cx.tcx, cx.param_env) + // Pessimistically assume opaque types are `!Freeze` + ty.has_opaque_types() || !ty.is_freeze(cx.tcx, cx.param_env) } fn in_adt_inherently<'tcx>( diff --git a/tests/ui/consts/const-fn-cycle-tait.rs b/tests/ui/consts/const-fn-cycle-tait.rs new file mode 100644 index 0000000000000..f8a63ea00c961 --- /dev/null +++ b/tests/ui/consts/const-fn-cycle-tait.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_impl_trait)] + +//! Test that we pessimistically assume the `Drop` impl of +//! a hidden type is not const. + +pub struct Parser(H); + +type Tait = impl Sized; + +const fn constrain() -> Tait {} + +pub const fn take(_: Tait) {} +//~^ ERROR: destructor of `Tait` cannot be evaluated at compile-time + +fn main() { + println!("Hello, world!"); +} diff --git a/tests/ui/consts/const-fn-cycle-tait.stderr b/tests/ui/consts/const-fn-cycle-tait.stderr new file mode 100644 index 0000000000000..3e025178a25bc --- /dev/null +++ b/tests/ui/consts/const-fn-cycle-tait.stderr @@ -0,0 +1,11 @@ +error[E0493]: destructor of `Tait` cannot be evaluated at compile-time + --> $DIR/const-fn-cycle-tait.rs:12:19 + | +LL | pub const fn take(_: Tait) {} + | ^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/const-fn-cycle.rs b/tests/ui/consts/const-fn-cycle.rs index 5175296a53e5b..033f9f0a1a735 100644 --- a/tests/ui/consts/const-fn-cycle.rs +++ b/tests/ui/consts/const-fn-cycle.rs @@ -1,11 +1,13 @@ -/// Discovered in https://github.com/rust-lang/rust/issues/112602. -/// This caused a cycle error, which made no sense. -/// Removing the `const` part of the `many` function would make the -/// test pass again. -/// The issue was that we were running const qualif checks on -/// `const fn`s, but never using them. During const qualif checks we tend -/// to end up revealing opaque types (the RPIT in `many`'s return type), -/// which can quickly lead to cycles. +//! Discovered in https://github.com/rust-lang/rust/issues/112602. +//! This caused a cycle error, which made no sense. +//! Removing the `const` part of the `many` function would make the +//! test pass again. +//! The issue was that we were running const qualif checks on +//! `const fn`s, but never using them. During const qualif checks we tend +//! to end up revealing opaque types (the RPIT in `many`'s return type), +//! which can quickly lead to cycles. + +// check-pass pub struct Parser(H); @@ -18,7 +20,6 @@ where } pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { - //~^ ERROR: cycle detected Parser::new(|_| unimplemented!()) } } diff --git a/tests/ui/consts/const-fn-cycle.stderr b/tests/ui/consts/const-fn-cycle.stderr deleted file mode 100644 index 7149e72fbb233..0000000000000 --- a/tests/ui/consts/const-fn-cycle.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0391]: cycle detected when computing type of `::many::{opaque#0}` - --> $DIR/const-fn-cycle.rs:20:47 - | -LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires borrow-checking `::many`... - --> $DIR/const-fn-cycle.rs:20:5 - | -LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires promoting constants in MIR for `::many`... - --> $DIR/const-fn-cycle.rs:20:5 - | -LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const checking `::many`... - --> $DIR/const-fn-cycle.rs:20:5 - | -LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing whether `Parser<::many::{opaque#0}>` is freeze... - = note: ...which requires evaluating trait selection obligation `Parser<::many::{opaque#0}>: core::marker::Freeze`... - = note: ...which again requires computing type of `::many::{opaque#0}`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/const-fn-cycle.rs:1:1 - | -LL | / /// Discovered in https://github.com/rust-lang/rust/issues/112602. -LL | | /// This caused a cycle error, which made no sense. -LL | | /// Removing the `const` part of the `many` function would make the -LL | | /// test pass again. -... | -LL | | println!("Hello, world!"); -LL | | } - | |_^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/consts/const-promoted-opaque.atomic.stderr b/tests/ui/consts/const-promoted-opaque.atomic.stderr index 67d6ca6853eed..38c3cadab056a 100644 --- a/tests/ui/consts/const-promoted-opaque.atomic.stderr +++ b/tests/ui/consts/const-promoted-opaque.atomic.stderr @@ -1,39 +1,41 @@ -error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` - --> $DIR/const-promoted-opaque.rs:13:12 +error[E0493]: destructor of `Foo` cannot be evaluated at compile-time + --> $DIR/const-promoted-opaque.rs:25:26 | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - | -note: ...which requires borrow-checking `FOO`... - --> $DIR/const-promoted-opaque.rs:20:1 - | -LL | const FOO: Foo = std::sync::atomic::AtomicU8::new(42); - | ^^^^^^^^^^^^^^ -note: ...which requires promoting constants in MIR for `FOO`... - --> $DIR/const-promoted-opaque.rs:20:1 +LL | let _: &'static _ = &FOO; + | ^^^ the destructor for this type cannot be evaluated in constants +... +LL | }; + | - value is dropped here + +error[E0716]: temporary value dropped while borrowed + --> $DIR/const-promoted-opaque.rs:25:26 | -LL | const FOO: Foo = std::sync::atomic::AtomicU8::new(42); - | ^^^^^^^^^^^^^^ -note: ...which requires const checking `FOO`... - --> $DIR/const-promoted-opaque.rs:20:1 +LL | let _: &'static _ = &FOO; + | ---------- ^^^ creates a temporary value which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +... +LL | }; + | - temporary value is freed at the end of this statement + +error[E0492]: constants cannot refer to interior mutable data + --> $DIR/const-promoted-opaque.rs:30:19 | -LL | const FOO: Foo = std::sync::atomic::AtomicU8::new(42); - | ^^^^^^^^^^^^^^ - = note: ...which requires computing whether `Foo` is freeze... - = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Freeze`... - = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/const-promoted-opaque.rs:2:1 +LL | const BAZ: &Foo = &FOO; + | ^^^^ this borrow of an interior mutable value may end up in the final value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/const-promoted-opaque.rs:34:26 | -LL | / #![feature(type_alias_impl_trait)] -LL | | -LL | | //! Check that we do not cause cycle errors when trying to -LL | | //! obtain information about interior mutability of an opaque type. -... | -LL | | let _: &'static _ = &FOO; -LL | | } - | |_^ +LL | let _: &'static _ = &FOO; + | ---------- ^^^ creates a temporary value which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +LL | +LL | } + | - temporary value is freed at the end of this statement -error: aborting due to previous error +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0492, E0493, E0716. +For more information about an error, try `rustc --explain E0492`. diff --git a/tests/ui/consts/const-promoted-opaque.rs b/tests/ui/consts/const-promoted-opaque.rs index 11ddab7fb3231..265cfa44b2f55 100644 --- a/tests/ui/consts/const-promoted-opaque.rs +++ b/tests/ui/consts/const-promoted-opaque.rs @@ -11,7 +11,6 @@ //[unit] check-pass type Foo = impl Sized; -//[string,atomic]~^ ERROR cycle detected #[cfg(string)] const FOO: Foo = String::new(); @@ -24,10 +23,14 @@ const FOO: Foo = (); const BAR: () = { let _: &'static _ = &FOO; + //[string,atomic]~^ ERROR: destructor of `Foo` cannot be evaluated at compile-time + //[string,atomic]~| ERROR: temporary value dropped while borrowed }; const BAZ: &Foo = &FOO; +//[string,atomic]~^ ERROR: constants cannot refer to interior mutable data fn main() { let _: &'static _ = &FOO; + //[string,atomic]~^ ERROR: temporary value dropped while borrowed } diff --git a/tests/ui/consts/const-promoted-opaque.string.stderr b/tests/ui/consts/const-promoted-opaque.string.stderr index 7fd4218e36666..38c3cadab056a 100644 --- a/tests/ui/consts/const-promoted-opaque.string.stderr +++ b/tests/ui/consts/const-promoted-opaque.string.stderr @@ -1,39 +1,41 @@ -error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` - --> $DIR/const-promoted-opaque.rs:13:12 +error[E0493]: destructor of `Foo` cannot be evaluated at compile-time + --> $DIR/const-promoted-opaque.rs:25:26 | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - | -note: ...which requires borrow-checking `FOO`... - --> $DIR/const-promoted-opaque.rs:17:1 - | -LL | const FOO: Foo = String::new(); - | ^^^^^^^^^^^^^^ -note: ...which requires promoting constants in MIR for `FOO`... - --> $DIR/const-promoted-opaque.rs:17:1 +LL | let _: &'static _ = &FOO; + | ^^^ the destructor for this type cannot be evaluated in constants +... +LL | }; + | - value is dropped here + +error[E0716]: temporary value dropped while borrowed + --> $DIR/const-promoted-opaque.rs:25:26 | -LL | const FOO: Foo = String::new(); - | ^^^^^^^^^^^^^^ -note: ...which requires const checking `FOO`... - --> $DIR/const-promoted-opaque.rs:17:1 +LL | let _: &'static _ = &FOO; + | ---------- ^^^ creates a temporary value which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +... +LL | }; + | - temporary value is freed at the end of this statement + +error[E0492]: constants cannot refer to interior mutable data + --> $DIR/const-promoted-opaque.rs:30:19 | -LL | const FOO: Foo = String::new(); - | ^^^^^^^^^^^^^^ - = note: ...which requires computing whether `Foo` is freeze... - = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Freeze`... - = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/const-promoted-opaque.rs:2:1 +LL | const BAZ: &Foo = &FOO; + | ^^^^ this borrow of an interior mutable value may end up in the final value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/const-promoted-opaque.rs:34:26 | -LL | / #![feature(type_alias_impl_trait)] -LL | | -LL | | //! Check that we do not cause cycle errors when trying to -LL | | //! obtain information about interior mutability of an opaque type. -... | -LL | | let _: &'static _ = &FOO; -LL | | } - | |_^ +LL | let _: &'static _ = &FOO; + | ---------- ^^^ creates a temporary value which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +LL | +LL | } + | - temporary value is freed at the end of this statement -error: aborting due to previous error +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0492, E0493, E0716. +For more information about an error, try `rustc --explain E0492`.