Skip to content

Do not try to reveal hidden types when trying to prove auto-traits in the defining scope #122192

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion compiler/rustc_const_eval/src/check_consts/qualifs.rs
Original file line number Diff line number Diff line change
@@ -100,7 +100,33 @@ 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)
// Avoid selecting for simple cases, such as builtin types.
if ty.is_trivially_freeze() {
return false;
}

// We do not use `ty.is_freeze` here, because that requires revealing opaque types, which
// requires borrowck, which in turn will invoke mir_const_qualifs again, causing a cycle error.
// Instead we invoke an obligation context manually, and provide the opaque type inference settings
// that allow the trait solver to just error out instead of cycling.
let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span));

let obligation = Obligation::new(
cx.tcx,
ObligationCause::dummy_with_span(cx.body.span),
cx.param_env,
ty::TraitRef::new(cx.tcx, freeze_def_id, [ty::GenericArg::from(ty)]),
);

let infcx = cx
.tcx
.infer_ctxt()
.with_opaque_type_inference(cx.body.source.def_id().expect_local())
.build();
let ocx = ObligationCtxt::new(&infcx);
ocx.register_obligation(obligation);
let errors = ocx.select_all_or_error();
!errors.is_empty()
}

fn in_adt_inherently<'tcx>(
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
@@ -1268,7 +1268,7 @@ impl<'tcx> Ty<'tcx> {
///
/// Returning true means the type is known to be `Freeze`. Returning
/// `false` means nothing -- could be `Freeze`, might not be.
fn is_trivially_freeze(self) -> bool {
pub fn is_trivially_freeze(self) -> bool {
match self.kind() {
ty::Int(_)
| ty::Uint(_)
Original file line number Diff line number Diff line change
@@ -772,7 +772,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
);
}

ty::Alias(ty::Opaque, _) => {
ty::Alias(ty::Opaque, alias) => {
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
// We do not generate an auto impl candidate for `impl Trait`s which already
// reference our auto trait.
@@ -787,6 +787,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// We do not emit auto trait candidates for opaque types in coherence.
// Doing so can result in weird dependency cycles.
candidates.ambiguous = true;
} else if self.infcx.can_define_opaque_ty(alias.def_id) {
// We do not emit auto trait candidates for opaque types in their defining scope, as
// we need to know the hidden type first, which we can't reliably know within the defining
// scope.
candidates.ambiguous = true;
} else {
candidates.vec.push(AutoImplCandidate)
}
18 changes: 11 additions & 7 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
@@ -2386,13 +2386,17 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
}

ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
// We can resolve the `impl Trait` to its concrete type,
// which enforces a DAG between the functions requiring
// the auto trait bounds in question.
match self.tcx().type_of_opaque(def_id) {
Ok(ty) => t.rebind(vec![ty.instantiate(self.tcx(), args)]),
Err(_) => {
return Err(SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id));
if self.infcx.can_define_opaque_ty(def_id) {
Copy link
Contributor

@lcnr lcnr Jun 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this applies to all auto traits, not just Freeze, so it can impact selection in an incomplete way. I feel a bit uncomfortable about this, as it will break in the new solver due to ambiguity. Can you explicitly limit this to Freeze and add the following as a test (with a revision for next solver)

fn is_trait<T: Trait<U>, U: Default>(_: T) -> U { Default::default() }

trait Trait<T> {}
impl<T: Send> Trait<u32> for T {}
impl<T> Trait<i32> for T {}
fn foo() -> impl Sized {
    if false {
        is_trait(foo())
    } else {
        Default::default()
    }
}

Copy link
Contributor

@lcnr lcnr Jun 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... we just recently made Freeze available for user defined bounds: #121675

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hopefully the new solver is stable before freeeze is :3

alternatively: can you change this to force ambiguity instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a thing, but it seems incomplete, I need to do some log analysis

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't do that in confirmnation, you have to change assemble_candidates_from_auto_impls instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

argml right. Old solver -.-

unreachable!()
} else {
// We can resolve the `impl Trait` to its concrete type,
// which enforces a DAG between the functions requiring
// the auto trait bounds in question.
match self.tcx().type_of_opaque(def_id) {
Ok(ty) => t.rebind(vec![ty.instantiate(self.tcx(), args)]),
Err(_) => {
return Err(SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id));
}
}
}
}
2 changes: 0 additions & 2 deletions tests/ui/const-generics/opaque_types.stderr
Original file line number Diff line number Diff line change
@@ -122,8 +122,6 @@ note: ...which requires const checking `main::{constant#0}`...
|
LL | foo::<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 opaque `Foo::{opaque#0}`, completing the cycle
note: cycle used when computing type of `Foo::{opaque#0}`
--> $DIR/opaque_types.rs:3:12
3 changes: 2 additions & 1 deletion tests/ui/consts/const-fn-cycle.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@
/// 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>(H);

impl<H, T> Parser<H>
@@ -18,7 +20,6 @@ where
}

pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
//~^ ERROR: cycle detected
Parser::new(|_| unimplemented!())
}
}
34 changes: 0 additions & 34 deletions tests/ui/consts/const-fn-cycle.stderr

This file was deleted.

45 changes: 7 additions & 38 deletions tests/ui/consts/const-promoted-opaque.atomic.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/const-promoted-opaque.rs:29:25
--> $DIR/const-promoted-opaque.rs:28:25
|
LL | let _: &'static _ = &FOO;
| ^^^^
@@ -9,7 +9,7 @@ LL | let _: &'static _ = &FOO;
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time
--> $DIR/const-promoted-opaque.rs:29:26
--> $DIR/const-promoted-opaque.rs:28:26
|
LL | let _: &'static _ = &FOO;
| ^^^ the destructor for this type cannot be evaluated in constants
@@ -18,13 +18,13 @@ LL | };
| - value is dropped here

error[E0492]: constants cannot refer to interior mutable data
--> $DIR/const-promoted-opaque.rs:34:19
--> $DIR/const-promoted-opaque.rs:33:19
|
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:38:26
--> $DIR/const-promoted-opaque.rs:37:26
|
LL | let _: &'static _ = &FOO;
| ---------- ^^^ creates a temporary value which is freed while still in use
@@ -34,38 +34,7 @@ LL |
LL | }
| - temporary value is freed at the end of this statement

error[E0391]: cycle detected when computing type of opaque `helper::Foo::{opaque#0}`
--> $DIR/const-promoted-opaque.rs:14:20
|
LL | pub type Foo = impl Sized;
| ^^^^^^^^^^
|
note: ...which requires borrow-checking `helper::FOO`...
--> $DIR/const-promoted-opaque.rs:21:5
|
LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
| ^^^^^^^^^^^^^^^^^^
note: ...which requires promoting constants in MIR for `helper::FOO`...
--> $DIR/const-promoted-opaque.rs:21:5
|
LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
| ^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `helper::FOO`...
--> $DIR/const-promoted-opaque.rs:21:5
|
LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
| ^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `helper::Foo` is freeze...
= note: ...which requires evaluating trait selection obligation `helper::Foo: core::marker::Freeze`...
= note: ...which again requires computing type of opaque `helper::Foo::{opaque#0}`, completing the cycle
note: cycle used when computing type of `helper::Foo::{opaque#0}`
--> $DIR/const-promoted-opaque.rs:14:20
|
LL | pub type Foo = impl Sized;
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 5 previous errors
error: aborting due to 4 previous errors

Some errors have detailed explanations: E0391, E0492, E0493, E0658, E0716.
For more information about an error, try `rustc --explain E0391`.
Some errors have detailed explanations: E0492, E0493, E0658, E0716.
For more information about an error, try `rustc --explain E0492`.
5 changes: 2 additions & 3 deletions tests/ui/consts/const-promoted-opaque.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@

mod helper {
pub type Foo = impl Sized;
//[string,atomic]~^ ERROR cycle detected

#[cfg(string)]
pub const FOO: Foo = String::new();
@@ -28,11 +27,11 @@ use helper::*;
const BAR: () = {
let _: &'static _ = &FOO;
//[string,atomic]~^ ERROR: destructor of `helper::Foo` cannot be evaluated at compile-time
//[string,atomic]~| ERROR: cannot borrow here
//[atomic]~| ERROR: cannot borrow here
};

const BAZ: &Foo = &FOO;
//[string,atomic]~^ ERROR: constants cannot refer to interior mutable data
//[atomic]~^ ERROR: constants cannot refer to interior mutable data

fn main() {
let _: &'static _ = &FOO;
57 changes: 5 additions & 52 deletions tests/ui/consts/const-promoted-opaque.string.stderr
Original file line number Diff line number Diff line change
@@ -1,30 +1,14 @@
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/const-promoted-opaque.rs:29:25
|
LL | let _: &'static _ = &FOO;
| ^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time
--> $DIR/const-promoted-opaque.rs:29:26
--> $DIR/const-promoted-opaque.rs:28:26
|
LL | let _: &'static _ = &FOO;
| ^^^ the destructor for this type cannot be evaluated in constants
...
LL | };
| - value is dropped here

error[E0492]: constants cannot refer to interior mutable data
--> $DIR/const-promoted-opaque.rs:34:19
|
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:38:26
--> $DIR/const-promoted-opaque.rs:37:26
|
LL | let _: &'static _ = &FOO;
| ---------- ^^^ creates a temporary value which is freed while still in use
@@ -34,38 +18,7 @@ LL |
LL | }
| - temporary value is freed at the end of this statement

error[E0391]: cycle detected when computing type of opaque `helper::Foo::{opaque#0}`
--> $DIR/const-promoted-opaque.rs:14:20
|
LL | pub type Foo = impl Sized;
| ^^^^^^^^^^
|
note: ...which requires borrow-checking `helper::FOO`...
--> $DIR/const-promoted-opaque.rs:18:5
|
LL | pub const FOO: Foo = String::new();
| ^^^^^^^^^^^^^^^^^^
note: ...which requires promoting constants in MIR for `helper::FOO`...
--> $DIR/const-promoted-opaque.rs:18:5
|
LL | pub const FOO: Foo = String::new();
| ^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `helper::FOO`...
--> $DIR/const-promoted-opaque.rs:18:5
|
LL | pub const FOO: Foo = String::new();
| ^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `helper::Foo` is freeze...
= note: ...which requires evaluating trait selection obligation `helper::Foo: core::marker::Freeze`...
= note: ...which again requires computing type of opaque `helper::Foo::{opaque#0}`, completing the cycle
note: cycle used when computing type of `helper::Foo::{opaque#0}`
--> $DIR/const-promoted-opaque.rs:14:20
|
LL | pub type Foo = impl Sized;
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 5 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0391, E0492, E0493, E0658, E0716.
For more information about an error, try `rustc --explain E0391`.
Some errors have detailed explanations: E0493, E0716.
For more information about an error, try `rustc --explain E0493`.
22 changes: 22 additions & 0 deletions tests/ui/impl-trait/auto-trait-selection-freeze.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0283]: type annotations needed
--> $DIR/auto-trait-selection-freeze.rs:19:16
|
LL | if false { is_trait(foo()) } else { Default::default() }
| ^^^^^^^^ ----- type must be known at this point
| |
| cannot infer type of the type parameter `T` declared on the function `is_trait`
|
= note: cannot satisfy `_: Trait<_>`
note: required by a bound in `is_trait`
--> $DIR/auto-trait-selection-freeze.rs:11:16
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
| ^^^^^^^^ required by this bound in `is_trait`
help: consider specifying the generic arguments
|
LL | if false { is_trait::<T, U>(foo()) } else { Default::default() }
| ++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
26 changes: 26 additions & 0 deletions tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error[E0283]: type annotations needed
--> $DIR/auto-trait-selection-freeze.rs:19:16
|
LL | if false { is_trait(foo()) } else { Default::default() }
| ^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `is_trait`
|
note: multiple `impl`s satisfying `impl Sized: Trait<_>` found
--> $DIR/auto-trait-selection-freeze.rs:16:1
|
LL | impl<T: Freeze> Trait<u32> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl<T> Trait<i32> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `is_trait`
--> $DIR/auto-trait-selection-freeze.rs:11:16
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
| ^^^^^^^^ required by this bound in `is_trait`
help: consider specifying the generic arguments
|
LL | if false { is_trait::<_, U>(foo()) } else { Default::default() }
| ++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
23 changes: 23 additions & 0 deletions tests/ui/impl-trait/auto-trait-selection-freeze.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! This test shows how we fail selection in a way that can influence
//! selection in a code path that succeeds.

//@ revisions: next old
//@[next] compile-flags: -Znext-solver

#![feature(freeze)]

use std::marker::Freeze;

fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
Default::default()
}

trait Trait<T> {}
impl<T: Freeze> Trait<u32> for T {}
impl<T> Trait<i32> for T {}
fn foo() -> impl Sized {
if false { is_trait(foo()) } else { Default::default() }
//~^ ERROR: type annotations needed
}

fn main() {}
22 changes: 22 additions & 0 deletions tests/ui/impl-trait/auto-trait-selection.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0283]: type annotations needed
--> $DIR/auto-trait-selection.rs:15:16
|
LL | if false { is_trait(foo()) } else { Default::default() }
| ^^^^^^^^ ----- type must be known at this point
| |
| cannot infer type of the type parameter `T` declared on the function `is_trait`
|
= note: cannot satisfy `_: Trait<_>`
note: required by a bound in `is_trait`
--> $DIR/auto-trait-selection.rs:7:16
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
| ^^^^^^^^ required by this bound in `is_trait`
help: consider specifying the generic arguments
|
LL | if false { is_trait::<T, U>(foo()) } else { Default::default() }
| ++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
26 changes: 26 additions & 0 deletions tests/ui/impl-trait/auto-trait-selection.old.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error[E0283]: type annotations needed
--> $DIR/auto-trait-selection.rs:15:16
|
LL | if false { is_trait(foo()) } else { Default::default() }
| ^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `is_trait`
|
note: multiple `impl`s satisfying `impl Sized: Trait<_>` found
--> $DIR/auto-trait-selection.rs:12:1
|
LL | impl<T: Send> Trait<u32> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl<T> Trait<i32> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `is_trait`
--> $DIR/auto-trait-selection.rs:7:16
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
| ^^^^^^^^ required by this bound in `is_trait`
help: consider specifying the generic arguments
|
LL | if false { is_trait::<_, U>(foo()) } else { Default::default() }
| ++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
19 changes: 19 additions & 0 deletions tests/ui/impl-trait/auto-trait-selection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//! This test shows how we fail selection in a way that can influence
//! selection in a code path that succeeds.
//@ revisions: next old
//@[next] compile-flags: -Znext-solver

fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
Default::default()
}

trait Trait<T> {}
impl<T: Send> Trait<u32> for T {}
impl<T> Trait<i32> for T {}
fn foo() -> impl Sized {
if false { is_trait(foo()) } else { Default::default() }
//~^ ERROR: type annotations needed
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0599]: no method named `my_debug` found for opaque type `impl Debug` in the current scope
--> $DIR/call_method_on_inherent_impl_ref.rs:20:11
--> $DIR/call_method_on_inherent_impl_ref.rs:19:11
|
LL | fn my_debug(&self);
| -------- the method is available for `&impl Debug` here
@@ -14,27 +14,6 @@ note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it
LL | trait MyDebug {
| ^^^^^^^^^^^^^

error[E0391]: cycle detected when computing type of opaque `my_foo::{opaque#0}`
--> $DIR/call_method_on_inherent_impl_ref.rs:15:16
|
LL | fn my_foo() -> impl std::fmt::Debug {
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `my_foo`...
--> $DIR/call_method_on_inherent_impl_ref.rs:20:9
|
LL | x.my_debug();
| ^
= note: ...which requires evaluating trait selection obligation `my_foo::{opaque#0}: core::marker::Unpin`...
= note: ...which again requires computing type of opaque `my_foo::{opaque#0}`, completing the cycle
note: cycle used when computing type of `my_foo::{opaque#0}`
--> $DIR/call_method_on_inherent_impl_ref.rs:15:16
|
LL | fn my_foo() -> impl std::fmt::Debug {
| ^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 2 previous errors
error: aborting due to 1 previous error

Some errors have detailed explanations: E0391, E0599.
For more information about an error, try `rustc --explain E0391`.
For more information about this error, try `rustc --explain E0599`.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0282]: type annotations needed
--> $DIR/call_method_on_inherent_impl_ref.rs:18:13
--> $DIR/call_method_on_inherent_impl_ref.rs:17:13
|
LL | let x = my_foo();
| ^
@@ -13,7 +13,7 @@ LL | let x: /* Type */ = my_foo();
| ++++++++++++

error[E0282]: type annotations needed for `&_`
--> $DIR/call_method_on_inherent_impl_ref.rs:28:13
--> $DIR/call_method_on_inherent_impl_ref.rs:27:13
|
LL | let x = &my_bar();
| ^
1 change: 0 additions & 1 deletion tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,6 @@ where
}

fn my_foo() -> impl std::fmt::Debug {
//[current]~^ cycle
if false {
let x = my_foo();
//[next]~^ type annotations needed
14 changes: 14 additions & 0 deletions tests/ui/impl-trait/rpit/const_check_false_cycle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! This test caused a cycle error when checking whether the
//! return type is `Freeze` during const checking, even though
//! the information is readily available.
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ check-pass

const fn f() -> impl Eq {
g()
}
const fn g() {}

fn main() {}
4 changes: 2 additions & 2 deletions tests/ui/impl-trait/unsized_coercion3.next.stderr
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ LL | let x = hello();
| ^^^^^^^ types differ

error[E0308]: mismatched types
--> $DIR/unsized_coercion3.rs:19:14
--> $DIR/unsized_coercion3.rs:18:14
|
LL | fn hello() -> Box<impl Trait + ?Sized> {
| ------------------- the expected opaque type
@@ -21,7 +21,7 @@ note: associated function defined here
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL

error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
--> $DIR/unsized_coercion3.rs:19:14
--> $DIR/unsized_coercion3.rs:18:14
|
LL | Box::new(1u32)
| -------- ^^^^ doesn't have a size known at compile-time
16 changes: 1 addition & 15 deletions tests/ui/impl-trait/unsized_coercion3.old.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
error: cannot check whether the hidden type of opaque type satisfies auto traits
--> $DIR/unsized_coercion3.rs:15:32
|
LL | let y: Box<dyn Send> = x;
| ^
|
= note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
note: opaque type is declared here
--> $DIR/unsized_coercion3.rs:11:19
|
LL | fn hello() -> Box<impl Trait + ?Sized> {
| ^^^^^^^^^^^^^^^^^^^
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Send>`

error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
--> $DIR/unsized_coercion3.rs:15:32
|
@@ -21,6 +7,6 @@ LL | let y: Box<dyn Send> = x;
= help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Send>`

error: aborting due to 2 previous errors
error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
1 change: 0 additions & 1 deletion tests/ui/impl-trait/unsized_coercion3.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@ fn hello() -> Box<impl Trait + ?Sized> {
//[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
let y: Box<dyn Send> = x;
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
//[old]~| ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
}
Box::new(1u32)
//[next]~^ ERROR: mismatched types
16 changes: 1 addition & 15 deletions tests/ui/impl-trait/unsized_coercion5.old.stderr
Original file line number Diff line number Diff line change
@@ -9,20 +9,6 @@ LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
= note: expected struct `Box<dyn Send>`
found struct `Box<dyn Trait + Send>`

error: cannot check whether the hidden type of opaque type satisfies auto traits
--> $DIR/unsized_coercion5.rs:16:32
|
LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
| ^
|
= note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
note: opaque type is declared here
--> $DIR/unsized_coercion5.rs:13:19
|
LL | fn hello() -> Box<impl Trait + ?Sized> {
| ^^^^^^^^^^^^^^^^^^^
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Trait + Send>`

error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
--> $DIR/unsized_coercion5.rs:16:32
|
@@ -32,7 +18,7 @@ LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
= help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Trait + Send>`

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
3 changes: 1 addition & 2 deletions tests/ui/impl-trait/unsized_coercion5.rs
Original file line number Diff line number Diff line change
@@ -15,8 +15,7 @@ fn hello() -> Box<impl Trait + ?Sized> {
let x = hello();
let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
//[old]~| ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
//~^^^ ERROR: mismatched types
//~^^ ERROR: mismatched types
}
Box::new(1u32)
}
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@ impl MyTrait for i32 {
//~| ERROR functions in trait impls cannot be declared const
//~| ERROR functions cannot be both `const` and `async`
//~| ERROR method `bar` is not a member
//~| ERROR cycle detected when computing type
main8().await;
//~^ ERROR cannot find function
}
Original file line number Diff line number Diff line change
@@ -61,46 +61,15 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
= help: use `-Znext-solver` to enable

error[E0425]: cannot find function `main8` in this scope
--> $DIR/ice-120503-async-const-method.rs:13:9
--> $DIR/ice-120503-async-const-method.rs:12:9
|
LL | main8().await;
| ^^^^^ help: a function with a similar name exists: `main`
...
LL | fn main() {}
| --------- similarly named function `main` defined here

error[E0391]: cycle detected when computing type of opaque `<impl at $DIR/ice-120503-async-const-method.rs:6:1: 6:21>::bar::{opaque#0}`
--> $DIR/ice-120503-async-const-method.rs:7:5
|
LL | async const fn bar(&self) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires borrow-checking `<impl at $DIR/ice-120503-async-const-method.rs:6:1: 6:21>::bar`...
--> $DIR/ice-120503-async-const-method.rs:7:5
|
LL | async const fn bar(&self) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires promoting constants in MIR for `<impl at $DIR/ice-120503-async-const-method.rs:6:1: 6:21>::bar`...
--> $DIR/ice-120503-async-const-method.rs:7:5
|
LL | async const fn bar(&self) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `<impl at $DIR/ice-120503-async-const-method.rs:6:1: 6:21>::bar`...
--> $DIR/ice-120503-async-const-method.rs:7:5
|
LL | async const fn bar(&self) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `<impl at $DIR/ice-120503-async-const-method.rs:6:1: 6:21>::bar::{opaque#0}` is freeze...
= note: ...which requires evaluating trait selection obligation `<impl at $DIR/ice-120503-async-const-method.rs:6:1: 6:21>::bar::{opaque#0}: core::marker::Freeze`...
= note: ...which again requires computing type of opaque `<impl at $DIR/ice-120503-async-const-method.rs:6:1: 6:21>::bar::{opaque#0}`, completing the cycle
note: cycle used when computing type of `<impl at $DIR/ice-120503-async-const-method.rs:6:1: 6:21>::bar::{opaque#0}`
--> $DIR/ice-120503-async-const-method.rs:7:5
|
LL | async const fn bar(&self) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 7 previous errors; 1 warning emitted
error: aborting due to 6 previous errors; 1 warning emitted

Some errors have detailed explanations: E0379, E0391, E0407, E0425.
Some errors have detailed explanations: E0379, E0407, E0425.
For more information about an error, try `rustc --explain E0379`.
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/in-where-clause.rs
Original file line number Diff line number Diff line change
@@ -4,13 +4,13 @@
#![feature(type_alias_impl_trait)]
type Bar = impl Sized;
//~^ ERROR: cycle
//~| ERROR: cycle

fn foo() -> Bar
where
Bar: Send,
{
[0; 1 + 2]
//~^ ERROR: type annotations needed: cannot satisfy `Bar: Send`
}

fn main() {}
31 changes: 14 additions & 17 deletions tests/ui/type-alias-impl-trait/in-where-clause.stderr
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ note: ...which requires computing type of opaque `Bar::{opaque#0}`...
LL | type Bar = impl Sized;
| ^^^^^^^^^^
note: ...which requires type-checking `foo`...
--> $DIR/in-where-clause.rs:9:1
--> $DIR/in-where-clause.rs:8:1
|
LL | / fn foo() -> Bar
LL | | where
@@ -25,26 +25,23 @@ LL | type Bar = impl Sized;
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error[E0391]: cycle detected when computing type of opaque `Bar::{opaque#0}`
--> $DIR/in-where-clause.rs:5:12
|
LL | type Bar = impl Sized;
| ^^^^^^^^^^
|
note: ...which requires type-checking `foo`...
--> $DIR/in-where-clause.rs:13:9
error[E0283]: type annotations needed: cannot satisfy `Bar: Send`
--> $DIR/in-where-clause.rs:12:9
|
LL | [0; 1 + 2]
| ^^^^^
= note: ...which requires evaluating trait selection obligation `Bar: core::marker::Send`...
= note: ...which again requires computing type of opaque `Bar::{opaque#0}`, completing the cycle
note: cycle used when computing type of `Bar::{opaque#0}`
--> $DIR/in-where-clause.rs:5:12
|
LL | type Bar = impl Sized;
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
= note: cannot satisfy `Bar: Send`
note: required by a bound in `foo`
--> $DIR/in-where-clause.rs:10:10
|
LL | fn foo() -> Bar
| --- required by a bound in this function
LL | where
LL | Bar: Send,
| ^^^^ required by this bound in `foo`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0391`.
Some errors have detailed explanations: E0283, E0391.
For more information about an error, try `rustc --explain E0283`.
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/reveal_local.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ fn not_gooder() -> Foo {
// while we could know this from the hidden type, it would
// need extra roundabout logic to support it.
is_send::<Foo>();
//~^ ERROR: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits
//~^ ERROR: type annotations needed: cannot satisfy `Foo: Send`

x
}
10 changes: 3 additions & 7 deletions tests/ui/type-alias-impl-trait/reveal_local.stderr
Original file line number Diff line number Diff line change
@@ -16,18 +16,13 @@ note: required by a bound in `is_send`
LL | fn is_send<T: Send>() {}
| ^^^^ required by this bound in `is_send`

error: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits
error[E0283]: type annotations needed: cannot satisfy `Foo: Send`
--> $DIR/reveal_local.rs:22:15
|
LL | is_send::<Foo>();
| ^^^
|
= note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
note: opaque type is declared here
--> $DIR/reveal_local.rs:5:12
|
LL | type Foo = impl Debug;
| ^^^^^^^^^^
= note: cannot satisfy `Foo: Send`
note: required by a bound in `is_send`
--> $DIR/reveal_local.rs:7:15
|
@@ -36,3 +31,4 @@ LL | fn is_send<T: Send>() {}

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0283`.