From dc028f3129b18c190e509e9f8e67bfd76f343cd4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 20 Jun 2024 08:22:40 +0000 Subject: [PATCH 1/6] Add regression test --- ...bind-hidden-type-in-projection-matching.rs | 25 +++++++++++++ ...-hidden-type-in-projection-matching.stderr | 36 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 tests/ui/impl-trait/bind-hidden-type-in-projection-matching.rs create mode 100644 tests/ui/impl-trait/bind-hidden-type-in-projection-matching.stderr diff --git a/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.rs b/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.rs new file mode 100644 index 0000000000000..6fec0ac8ea98a --- /dev/null +++ b/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] +trait Trait<'a> { + type Out; +} + +impl<'a, T> Trait<'a> for T { + type Out = T; +} + +type Foo = impl Sized; +//~^ ERROR: unconstrained opaque type + +fn weird_bound(x: &>::Out) -> X +//~^ ERROR: item does not constrain +where + for<'a> X: Trait<'a>, + for<'a> >::Out<()>: Copy, +{ + let x = *x; //~ ERROR: cannot move out of `*x` + todo!(); +} + +fn main() { + let _: () = weird_bound(&()); +} diff --git a/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.stderr b/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.stderr new file mode 100644 index 0000000000000..499514140c63b --- /dev/null +++ b/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.stderr @@ -0,0 +1,36 @@ +error: item does not constrain `Foo::{opaque#0}`, but has it in its signature + --> $DIR/bind-hidden-type-in-projection-matching.rs:13:4 + | +LL | fn weird_bound(x: &>::Out) -> X + | ^^^^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/bind-hidden-type-in-projection-matching.rs:10:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + +error: unconstrained opaque type + --> $DIR/bind-hidden-type-in-projection-matching.rs:10:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same module + +error[E0507]: cannot move out of `*x` which is behind a shared reference + --> $DIR/bind-hidden-type-in-projection-matching.rs:19:13 + | +LL | let x = *x; + | ^^ move occurs because `*x` has type `>::Out`, which does not implement the `Copy` trait + | +help: consider removing the dereference here + | +LL - let x = *x; +LL + let x = x; + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0507`. From 2f4fbf8a2984b12a3b726fad90fe897e238addb9 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 14 Jun 2024 11:36:07 +0000 Subject: [PATCH 2/6] Do not look in ParamEnv for opaque type bounds that could be satisfied --- .../src/traits/select/candidate_assembly.rs | 51 +++++++++++++------ 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 06b79ea63ca47..98136c98c3597 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -40,21 +40,42 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { predicate: self.infcx.resolve_vars_if_possible(obligation.predicate), }; - if obligation.predicate.skip_binder().self_ty().is_ty_var() { - debug!(ty = ?obligation.predicate.skip_binder().self_ty(), "ambiguous inference var or opaque type"); - // Self is a type variable (e.g., `_: AsRef`). - // - // This is somewhat problematic, as the current scheme can't really - // handle it turning to be a projection. This does end up as truly - // ambiguous in most cases anyway. - // - // Take the fast path out - this also improves - // performance by preventing assemble_candidates_from_impls from - // matching every impl for this trait. - return Ok(SelectionCandidateSet { vec: vec![], ambiguous: true }); - } - let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false }; + let def_id = obligation.predicate.def_id(); + let tcx = self.tcx(); + + match obligation.predicate.skip_binder().self_ty().kind() { + // Opaque types in their defining scope are just like inference vars... + ty::Alias(ty::Opaque, alias) if self.infcx.can_define_opaque_ty(alias.def_id) => { + if tcx.is_lang_item(def_id, LangItem::Unsize) { + self.assemble_candidates_for_unsizing(obligation, &mut candidates); + } + self.assemble_candidates_from_impls(obligation, &mut candidates); + // .. unless we are looking for candidates just on the opaque signature, ... + self.assemble_candidates_from_projected_tys(obligation, &mut candidates); + // .. or for auto traits, which look at the hidden type. + // Auto traits must be collected after projected tys, because opaque types + // do not emit auto trait candidates if a projection for the same auto trait + // already exists (e.g. due to the bounds on the opaque). + self.assemble_candidates_from_auto_impls(obligation, &mut candidates); + return Ok(candidates); + } + ty::Infer(ty::TyVar(vid)) => { + debug!(?vid, "ambiguous inference var"); + // Self is a type variable (e.g., `_: AsRef`). + // + // This is somewhat problematic, as the current scheme can't really + // handle it turning to be a projection. This does end up as truly + // ambiguous in most cases anyway. + // + // Take the fast path out - this also improves + // performance by preventing assemble_candidates_from_impls from + // matching every impl for this trait. + candidates.ambiguous = true; + return Ok(candidates); + } + _ => {} + } // Negative trait predicates have different rules than positive trait predicates. if obligation.polarity() == ty::PredicatePolarity::Negative { @@ -66,8 +87,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Other bounds. Consider both in-scope bounds from fn decl // and applicable impls. There is a certain set of precedence rules here. - let def_id = obligation.predicate.def_id(); - let tcx = self.tcx(); if tcx.is_lang_item(def_id, LangItem::Copy) { debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty()); From 2622e1a4d78379e716e44e74c7b2b58ee59f5021 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 14 Jun 2024 11:39:43 +0000 Subject: [PATCH 3/6] Allow defining opaque types in where clause candidate selection --- compiler/rustc_borrowck/src/type_check/mod.rs | 13 +++++++- .../src/traits/select/mod.rs | 2 +- ...-method-resolution-opaque-type.next.stderr | 2 +- ...e-method-resolution-opaque-type.old.stderr | 30 +++++------------ ...rm-before-method-resolution-opaque-type.rs | 5 ++- ...bind-hidden-type-in-projection-matching.rs | 3 +- ...-hidden-type-in-projection-matching.stderr | 30 +++++------------ tests/ui/impl-trait/nested_impl_trait.rs | 2 -- tests/ui/impl-trait/nested_impl_trait.stderr | 32 ++++--------------- 9 files changed, 40 insertions(+), 79 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index db4b5209145f0..cf0a056170556 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -19,6 +19,7 @@ use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::{ BoundRegion, BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, }; +use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -40,6 +41,7 @@ use rustc_span::symbol::sym; use rustc_span::Span; use rustc_span::DUMMY_SP; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; +use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; @@ -1799,7 +1801,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // `Sized` bound in no way depends on precise regions, so this // shouldn't affect `is_sized`. let erased_ty = tcx.erase_regions(ty); - if !erased_ty.is_sized(tcx, self.param_env) { + let sized_trait = tcx.require_lang_item(LangItem::Sized, Some(span)); + let trait_ref = ty::TraitRef::new(tcx, sized_trait, [erased_ty]); + + let is_sized = self.infcx.predicate_must_hold_modulo_regions(&Obligation::new( + tcx, + ObligationCause::dummy_with_span(span), + self.param_env, + trait_ref, + )); + if !is_sized { // in current MIR construction, all non-control-flow rvalue // expressions evaluate through `as_temp` or `into` a return // slot or local, so to find all unsized rvalues it is enough diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index c007cd5314a86..af2c02b104cc7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2675,7 +2675,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ); self.infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, predicate.trait_ref, trait_ref) + .eq(DefineOpaqueTypes::Yes, predicate.trait_ref, trait_ref) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| ()) } diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr index 72646b7bc768b..9e04e90a98ac0 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr @@ -1,5 +1,5 @@ error[E0284]: type annotations needed: cannot satisfy `Foo == _` - --> $DIR/norm-before-method-resolution-opaque-type.rs:16:19 + --> $DIR/norm-before-method-resolution-opaque-type.rs:15:19 | LL | fn weird_bound(x: &>::Out) -> X | ^ cannot satisfy `Foo == _` diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr index dbd0d5dc73323..328d1d5a45063 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr @@ -1,26 +1,11 @@ -error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/norm-before-method-resolution-opaque-type.rs:16:4 +error[E0161]: cannot move a value of type `>::Out` + --> $DIR/norm-before-method-resolution-opaque-type.rs:21:9 | -LL | fn weird_bound(x: &>::Out) -> X - | ^^^^^^^^^^^ - | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/norm-before-method-resolution-opaque-type.rs:13:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - -error: unconstrained opaque type - --> $DIR/norm-before-method-resolution-opaque-type.rs:13:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module +LL | let x = *x; + | ^ the size of `>::Out` cannot be statically determined error[E0507]: cannot move out of `*x` which is behind a shared reference - --> $DIR/norm-before-method-resolution-opaque-type.rs:23:13 + --> $DIR/norm-before-method-resolution-opaque-type.rs:21:13 | LL | let x = *x; | ^^ move occurs because `*x` has type `>::Out`, which does not implement the `Copy` trait @@ -31,6 +16,7 @@ LL - let x = *x; LL + let x = x; | -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0507`. +Some errors have detailed explanations: E0161, E0507. +For more information about an error, try `rustc --explain E0161`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs index cf752f814c90c..56640923bf7ef 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs @@ -11,16 +11,15 @@ impl<'a, T> Trait<'a> for T { } type Foo = impl Sized; -//[old]~^ ERROR: unconstrained opaque type fn weird_bound(x: &>::Out) -> X -//[old]~^ ERROR: item does not constrain -//[next]~^^ ERROR: cannot satisfy `Foo == _` +//[next]~^ ERROR: cannot satisfy `Foo == _` where for<'a> X: Trait<'a>, for<'a> >::Out<()>: Copy, { let x = *x; //[old]~ ERROR: cannot move out of `*x` + //[old]~^ ERROR: cannot move a value of type `>::Out` todo!(); } diff --git a/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.rs b/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.rs index 6fec0ac8ea98a..86c929b572fde 100644 --- a/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.rs +++ b/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.rs @@ -8,15 +8,14 @@ impl<'a, T> Trait<'a> for T { } type Foo = impl Sized; -//~^ ERROR: unconstrained opaque type fn weird_bound(x: &>::Out) -> X -//~^ ERROR: item does not constrain where for<'a> X: Trait<'a>, for<'a> >::Out<()>: Copy, { let x = *x; //~ ERROR: cannot move out of `*x` + //~^ ERROR: cannot move a value of type `>::Out` todo!(); } diff --git a/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.stderr b/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.stderr index 499514140c63b..2e43bd266096e 100644 --- a/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.stderr +++ b/tests/ui/impl-trait/bind-hidden-type-in-projection-matching.stderr @@ -1,26 +1,11 @@ -error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/bind-hidden-type-in-projection-matching.rs:13:4 +error[E0161]: cannot move a value of type `>::Out` + --> $DIR/bind-hidden-type-in-projection-matching.rs:17:9 | -LL | fn weird_bound(x: &>::Out) -> X - | ^^^^^^^^^^^ - | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/bind-hidden-type-in-projection-matching.rs:10:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - -error: unconstrained opaque type - --> $DIR/bind-hidden-type-in-projection-matching.rs:10:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module +LL | let x = *x; + | ^ the size of `>::Out` cannot be statically determined error[E0507]: cannot move out of `*x` which is behind a shared reference - --> $DIR/bind-hidden-type-in-projection-matching.rs:19:13 + --> $DIR/bind-hidden-type-in-projection-matching.rs:17:13 | LL | let x = *x; | ^^ move occurs because `*x` has type `>::Out`, which does not implement the `Copy` trait @@ -31,6 +16,7 @@ LL - let x = *x; LL + let x = x; | -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0507`. +Some errors have detailed explanations: E0161, E0507. +For more information about an error, try `rustc --explain E0161`. diff --git a/tests/ui/impl-trait/nested_impl_trait.rs b/tests/ui/impl-trait/nested_impl_trait.rs index 760102794c34e..6ab3a790b797a 100644 --- a/tests/ui/impl-trait/nested_impl_trait.rs +++ b/tests/ui/impl-trait/nested_impl_trait.rs @@ -5,7 +5,6 @@ fn fine(x: impl Into) -> impl Into { x } fn bad_in_ret_position(x: impl Into) -> impl Into { x } //~^ ERROR nested `impl Trait` is not allowed -//~| ERROR the trait bound `impl Debug: From>` is not satisfied fn bad_in_fn_syntax(x: fn() -> impl Into) {} //~^ ERROR nested `impl Trait` is not allowed @@ -18,7 +17,6 @@ struct X; impl X { fn bad(x: impl Into) -> impl Into { x } //~^ ERROR nested `impl Trait` is not allowed - //~| ERROR the trait bound `impl Debug: From>` is not satisfied } fn allowed_in_assoc_type() -> impl Iterator { diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index 83d1347aff431..b14c25f0441b2 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -8,7 +8,7 @@ LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:10:42 + --> $DIR/nested_impl_trait.rs:9:42 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | ----------^^^^^^^^^^- @@ -17,7 +17,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:14:37 + --> $DIR/nested_impl_trait.rs:13:37 | LL | fn bad_in_arg_position(_: impl Into) { } | ----------^^^^^^^^^^- @@ -26,7 +26,7 @@ LL | fn bad_in_arg_position(_: impl Into) { } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:19:44 + --> $DIR/nested_impl_trait.rs:18:44 | LL | fn bad(x: impl Into) -> impl Into { x } | ----------^^^^^^^^^^- @@ -35,32 +35,14 @@ LL | fn bad(x: impl Into) -> impl Into { x } | outer `impl Trait` error[E0562]: `impl Trait` is not allowed in `fn` pointer return types - --> $DIR/nested_impl_trait.rs:10:32 + --> $DIR/nested_impl_trait.rs:9:32 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | ^^^^^^^^^^^^^^^^^^^^^ | = note: `impl Trait` is only allowed in arguments and return types of functions and methods -error[E0277]: the trait bound `impl Debug: From>` is not satisfied - --> $DIR/nested_impl_trait.rs:6:46 - | -LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Debug`, which is required by `impl Into: Into` - | - = help: the trait `Into` is implemented for `T` - = note: required for `impl Into` to implement `Into` - -error[E0277]: the trait bound `impl Debug: From>` is not satisfied - --> $DIR/nested_impl_trait.rs:19:34 - | -LL | fn bad(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Debug`, which is required by `impl Into: Into` - | - = help: the trait `Into` is implemented for `T` - = note: required for `impl Into` to implement `Into` - -error: aborting due to 7 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0277, E0562, E0666. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0562, E0666. +For more information about an error, try `rustc --explain E0562`. From 2379e0ec0321b5f4c69340da9ea87ae48a86d966 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 14 Jun 2024 12:01:49 +0000 Subject: [PATCH 4/6] Allow impl selection and confirmation to define opaque types --- .../src/traits/select/mod.rs | 2 +- ...inherent_impl_on_rigid_type.current.stderr | 16 ------- ...on_inherent_impl_on_rigid_type.next.stderr | 2 +- ...l_method_on_inherent_impl_on_rigid_type.rs | 2 +- tests/ui/impl-trait/equality.rs | 13 +++--- tests/ui/impl-trait/equality.stderr | 15 ++----- .../recursive-bound-eval.current.stderr | 42 +++++++++++++++++++ .../recursive-bound-eval.next.stderr | 2 +- tests/ui/impl-trait/recursive-bound-eval.rs | 6 +-- ...rsive-type-alias-impl-trait-declaration.rs | 2 +- ...e-type-alias-impl-trait-declaration.stderr | 12 ++---- .../constrain_in_projection.current.stderr | 11 ----- .../constrain_in_projection.rs | 3 +- .../constrain_in_projection2.current.stderr | 18 +++++--- .../constrain_in_projection2.rs | 2 +- .../issue-84660-unsoundness.current.stderr | 17 +------- .../issue-84660-unsoundness.next.stderr | 3 +- .../issue-84660-unsoundness.rs | 1 - .../nested-tait-inference.current.stderr | 14 ------- .../nested-tait-inference.rs | 4 +- .../nested-tait-inference2.current.stderr | 19 +++++---- .../nested-tait-inference2.rs | 2 +- .../normalize-hidden-types.current.stderr | 21 ++++------ .../self-referential-2.current.stderr | 14 ------- .../self-referential-2.rs | 4 +- .../self-referential-3.rs | 2 +- .../self-referential-3.stderr | 12 ++---- 27 files changed, 109 insertions(+), 152 deletions(-) delete mode 100644 tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr create mode 100644 tests/ui/impl-trait/recursive-bound-eval.current.stderr delete mode 100644 tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr delete mode 100644 tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr delete mode 100644 tests/ui/type-alias-impl-trait/self-referential-2.current.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index af2c02b104cc7..2c52c23cbd4bd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2532,7 +2532,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref) + .eq(DefineOpaqueTypes::Yes, placeholder_obligation_trait_ref, impl_trait_ref) .map_err(|e| { debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) })?; diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr deleted file mode 100644 index 6ecb2b05fc56b..0000000000000 --- a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0599]: no method named `my_debug` found for reference `&impl Debug` in the current scope - --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:16:11 - | -LL | x.my_debug(); - | ^^^^^^^^ method not found in `&impl Debug` - | - = help: items from traits can only be used if the trait is implemented and in scope -note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it - --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:4:1 - | -LL | trait MyDebug { - | ^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr index 5fb0b8f1d14b2..e60f1bfb361c3 100644 --- a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed for `&_` - --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:14:13 + --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:15:13 | LL | let x = &my_foo(); | ^ diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs index 7fb2ff3b2bcc6..22ada7f1bea8a 100644 --- a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs @@ -1,5 +1,6 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver +//@[current] check-pass trait MyDebug { fn my_debug(&self); @@ -14,7 +15,6 @@ fn my_foo() -> impl std::fmt::Debug { let x = &my_foo(); //[next]~^ ERROR: type annotations needed x.my_debug(); - //[current]~^ ERROR: no method named `my_debug` } () } diff --git a/tests/ui/impl-trait/equality.rs b/tests/ui/impl-trait/equality.rs index 828b5aac896be..952f81f19784c 100644 --- a/tests/ui/impl-trait/equality.rs +++ b/tests/ui/impl-trait/equality.rs @@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo { 0 } else { n + sum_to(n - 1) - //~^ ERROR cannot add `impl Foo` to `u32` + //~^ ERROR cannot satisfy `>::Output == i32` } } @@ -32,12 +32,15 @@ trait Leak: Sized { } impl Leak for T { default type T = (); - default fn leak(self) -> Self::T { panic!() } + default fn leak(self) -> Self::T { + panic!() + } } impl Leak for i32 { type T = i32; - fn leak(self) -> i32 { self } + fn leak(self) -> i32 { + self + } } -fn main() { -} +fn main() {} diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index 12d886a002454..c9ba1a5ba32d1 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -22,20 +22,13 @@ help: change the type of the numeric literal from `u32` to `i32` LL | 0_i32 | ~~~ -error[E0277]: cannot add `impl Foo` to `u32` +error[E0284]: type annotations needed: cannot satisfy `>::Output == i32` --> $DIR/equality.rs:24:11 | LL | n + sum_to(n - 1) - | ^ no implementation for `u32 + impl Foo` - | - = help: the trait `Add` is not implemented for `u32` - = help: the following other types implement trait `Add`: - `&'a u32` implements `Add` - `&u32` implements `Add<&u32>` - `u32` implements `Add<&u32>` - `u32` implements `Add` + | ^ cannot satisfy `>::Output == i32` error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/impl-trait/recursive-bound-eval.current.stderr b/tests/ui/impl-trait/recursive-bound-eval.current.stderr new file mode 100644 index 0000000000000..f446e4eb3bc4b --- /dev/null +++ b/tests/ui/impl-trait/recursive-bound-eval.current.stderr @@ -0,0 +1,42 @@ +error[E0282]: type annotations needed + --> $DIR/recursive-bound-eval.rs:19:28 + | +LL | move || recursive_fn().parse() + | ^^^^^ cannot infer type + +error[E0599]: no method named `parse` found for opaque type `impl Parser<_>` in the current scope + --> $DIR/recursive-bound-eval.rs:19:28 + | +LL | move || recursive_fn().parse() + | ^^^^^ method not found in `impl Parser<_>` + | + = help: items from traits can only be used if the trait is implemented and in scope +help: trait `Parser` which provides `parse` is implemented but not in scope; perhaps you want to import it + | +LL + use Parser; + | + +error[E0391]: cycle detected when computing type of opaque `recursive_fn::{opaque#0}` + --> $DIR/recursive-bound-eval.rs:17:29 + | +LL | pub fn recursive_fn() -> impl Parser { + | ^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `recursive_fn`... + --> $DIR/recursive-bound-eval.rs:19:13 + | +LL | move || recursive_fn().parse() + | ^^^^^^^^^^^^^^ + = note: ...which requires evaluating trait selection obligation `recursive_fn::{opaque#0}: core::marker::Unpin`... + = note: ...which again requires computing type of opaque `recursive_fn::{opaque#0}`, completing the cycle +note: cycle used when computing type of `recursive_fn::{opaque#0}` + --> $DIR/recursive-bound-eval.rs:17:29 + | +LL | pub fn recursive_fn() -> impl Parser { + | ^^^^^^^^^^^^^^ + = 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 3 previous errors + +Some errors have detailed explanations: E0282, E0391, E0599. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/recursive-bound-eval.next.stderr b/tests/ui/impl-trait/recursive-bound-eval.next.stderr index 4bab290d71c3c..754b2c04dd49c 100644 --- a/tests/ui/impl-trait/recursive-bound-eval.next.stderr +++ b/tests/ui/impl-trait/recursive-bound-eval.next.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/recursive-bound-eval.rs:20:13 + --> $DIR/recursive-bound-eval.rs:19:13 | LL | move || recursive_fn().parse() | ^^^^^^^^^^^^^^ cannot infer type diff --git a/tests/ui/impl-trait/recursive-bound-eval.rs b/tests/ui/impl-trait/recursive-bound-eval.rs index 7859c8983fc89..97c004a2f7cde 100644 --- a/tests/ui/impl-trait/recursive-bound-eval.rs +++ b/tests/ui/impl-trait/recursive-bound-eval.rs @@ -4,8 +4,6 @@ //@revisions: next current //@[next] compile-flags: -Znext-solver -//@[current] check-pass - pub trait Parser { fn parse(&self) -> E; } @@ -17,8 +15,10 @@ impl E> Parser for T { } pub fn recursive_fn() -> impl Parser { + //[current]~^ ERROR: cycle move || recursive_fn().parse() - //[next]~^ ERROR: type annotations needed + //~^ ERROR: type annotations needed + //[current]~| ERROR: no method named `parse` } fn main() {} diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs index aab10be2de27a..7874a21f3aec5 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs @@ -11,7 +11,7 @@ impl PartialEq<(Bar, i32)> for Bar { } fn foo() -> Foo { - //~^ ERROR can't compare `Bar` with `(Foo, i32)` + //~^ ERROR overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` Bar } diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr index bc810c0f88f3d..2d4707f8a2799 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr @@ -1,15 +1,9 @@ -error[E0277]: can't compare `Bar` with `(Foo, i32)` +error[E0275]: overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` --> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13 | LL | fn foo() -> Foo { - | ^^^ no implementation for `Bar == (Foo, i32)` -LL | -LL | Bar - | --- return type was inferred to be `Bar` here - | - = help: the trait `PartialEq<(Foo, i32)>` is not implemented for `Bar` - = help: the trait `PartialEq<(Bar, i32)>` is implemented for `Bar` + | ^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr deleted file mode 100644 index c215d197db436..0000000000000 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0277]: the trait bound `Foo: Trait` is not satisfied - --> $DIR/constrain_in_projection.rs:24:14 - | -LL | let x = >::Assoc::default(); - | ^^^ the trait `Trait` is not implemented for `Foo` - | - = help: the trait `Trait<()>` is implemented for `Foo` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs index 7d7d16361ae6d..2a246900106cb 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs @@ -4,7 +4,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next]check-pass +//@check-pass #![feature(type_alias_impl_trait)] @@ -22,7 +22,6 @@ impl Trait<()> for Foo { fn bop(_: Bar) { let x = >::Assoc::default(); - //[current]~^ `Foo: Trait` is not satisfied } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr index 909f1f6d61cbe..0d6eac4216bae 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr @@ -1,13 +1,19 @@ -error[E0277]: the trait bound `Foo: Trait` is not satisfied +error[E0283]: type annotations needed: cannot satisfy `Foo: Trait` --> $DIR/constrain_in_projection2.rs:27:14 | LL | let x = >::Assoc::default(); - | ^^^ the trait `Trait` is not implemented for `Foo` + | ^^^ help: use the fully qualified path to an implementation: `::Assoc` | - = help: the following other types implement trait `Trait`: - `Foo` implements `Trait<()>` - `Foo` implements `Trait` +note: multiple `impl`s satisfying `Foo: Trait` found + --> $DIR/constrain_in_projection2.rs:18:1 + | +LL | impl Trait<()> for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Trait for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs index af222f6c15347..cbdaf251ebf1b 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs @@ -26,7 +26,7 @@ impl Trait for Foo { fn bop(_: Bar) { let x = >::Assoc::default(); //[next]~^ ERROR: cannot satisfy `Foo: Trait` - //[current]~^^ ERROR: `Foo: Trait` is not satisfied + //[current]~^^ ERROR: cannot satisfy `Foo: Trait` } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr index 2b064dcfc31a5..a7ff097e8bf38 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr @@ -1,18 +1,5 @@ -error: item does not constrain `Bar::{opaque#0}`, but has it in its signature - --> $DIR/issue-84660-unsoundness.rs:22:8 - | -LL | fn convert(_i: In) -> Self::Out { - | ^^^^^^^ - | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/issue-84660-unsoundness.rs:12:12 - | -LL | type Bar = impl Foo; - | ^^^^^^^^ - error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:29:1 + --> $DIR/issue-84660-unsoundness.rs:28:1 | LL | impl Trait for Out { | ------------------------------------ first implementation here @@ -20,6 +7,6 @@ LL | impl Trait for Out { LL | impl Trait<(), In> for Out { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr index 5a728a00138c8..d0b89bdf897e7 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr @@ -4,13 +4,12 @@ error[E0284]: type annotations needed: cannot satisfy `Bar == _` LL | fn convert(_i: In) -> Self::Out { | _____________________________________^ LL | | -LL | | LL | | unreachable!(); LL | | } | |_____^ cannot satisfy `Bar == _` error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:29:1 + --> $DIR/issue-84660-unsoundness.rs:28:1 | LL | impl Trait for Out { | ------------------------------------ first implementation here diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs index f3234bafd1153..f5ff73c7eeadd 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -21,7 +21,6 @@ impl Trait for Out { type Out = Out; fn convert(_i: In) -> Self::Out { //[next]~^ ERROR: cannot satisfy `Bar == _` - //[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`, but has it in its signature unreachable!(); } } diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr deleted file mode 100644 index 34532afcbbae4..0000000000000 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/nested-tait-inference.rs:17:13 - | -LL | fn foo() -> impl Foo { - | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` -... -LL | () - | -- return type was inferred to be `()` here - | - = help: the trait `Foo<()>` is implemented for `()` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs index 50d51c7faf91b..fb32451c14e3f 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -4,7 +4,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass use std::fmt::Debug; @@ -15,8 +15,6 @@ trait Foo {} impl Foo<()> for () {} fn foo() -> impl Foo { - //[current]~^ ERROR: the trait bound `(): Foo` is not satisfied - // FIXME(type-alias-impl-trait): We could probably make this work. () } diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr index 9da3926ac7081..c7b7af152ab32 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr @@ -1,16 +1,17 @@ -error[E0277]: the trait bound `(): Foo` is not satisfied +error[E0283]: type annotations needed: cannot satisfy `(): Foo` --> $DIR/nested-tait-inference2.rs:17:13 | LL | fn foo() -> impl Foo { - | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` -LL | -LL | () - | -- return type was inferred to be `()` here + | ^^^^^^^^^^^^^^ | - = help: the following other types implement trait `Foo`: - `()` implements `Foo<()>` - `()` implements `Foo` +note: multiple `impl`s satisfying `(): Foo` found + --> $DIR/nested-tait-inference2.rs:14:1 + | +LL | impl Foo<()> for () {} + | ^^^^^^^^^^^^^^^^^^^ +LL | impl Foo for () {} + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs index 28d72b0cbeede..fe2f76e552ad7 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -15,7 +15,7 @@ impl Foo<()> for () {} impl Foo for () {} fn foo() -> impl Foo { - //[current]~^ ERROR: the trait bound `(): Foo` is not satisfied + //[current]~^ ERROR: cannot satisfy `(): Foo` () //[next]~^ ERROR: cannot satisfy `impl Foo == ()` } diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr index a40dac06a01c3..eff29303bf18e 100644 --- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr @@ -22,21 +22,17 @@ note: previous use here LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } | ^^^^^^^^^^^^^^^^^ -error[E0308]: mismatched types +error: concrete type differs from previous defining opaque type use --> $DIR/normalize-hidden-types.rs:43:25 | -LL | type Opaque = impl Sized; - | ---------- the expected opaque type -... LL | let _: Opaque = dyn_hoops::(0); - | ------ ^^^^^^^^^^^^^^^^^^ expected opaque type, found `*const dyn FnOnce(())` - | | - | expected due to this - | - = note: expected opaque type `typeck::Opaque` - found raw pointer `*const (dyn FnOnce(()) + 'static)` - = help: consider constraining the associated type `::Gat<'_>` to `()` or calling a method that returns `::Gat<'_>` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + | ^^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` + | +note: previous use here + --> $DIR/normalize-hidden-types.rs:44:9 + | +LL | None + | ^^^^ error: concrete type differs from previous defining opaque type use --> $DIR/normalize-hidden-types.rs:52:25 @@ -52,4 +48,3 @@ LL | None error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr deleted file mode 100644 index 3ae3590ca7fe3..0000000000000 --- a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0277]: can't compare `i32` with `Foo` - --> $DIR/self-referential-2.rs:10:13 - | -LL | fn bar() -> Bar { - | ^^^ no implementation for `i32 == Foo` -LL | 42_i32 - | ------ return type was inferred to be `i32` here - | - = help: the trait `PartialEq` is not implemented for `i32` - = help: the trait `PartialEq` is implemented for `i32` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.rs b/tests/ui/type-alias-impl-trait/self-referential-2.rs index f96364ccfcddf..f4102f2e2cb71 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-2.rs @@ -1,14 +1,14 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass #![feature(type_alias_impl_trait)] type Foo = impl std::fmt::Debug; type Bar = impl PartialEq; fn bar() -> Bar { - 42_i32 //[current]~^ ERROR can't compare `i32` with `Foo` + 42_i32 } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs index b33051da2d779..3b015ab322aca 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-3.rs @@ -5,7 +5,7 @@ type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - //~^ ERROR can't compare `&i32` with `Bar<'a, 'b>` + //~^ ERROR overflow normalizing the type alias `Bar<'a, 'b>` i } diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index 32eac622e5181..caa9f9691dda5 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -1,15 +1,11 @@ -error[E0277]: can't compare `&i32` with `Bar<'a, 'b>` +error[E0275]: overflow normalizing the type alias `Bar<'a, 'b>` --> $DIR/self-referential-3.rs:7:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>` -LL | -LL | i - | - return type was inferred to be `&i32` here + | ^^^^^^^^^^^ | - = help: the trait `PartialEq>` is not implemented for `&i32` - = help: the trait `PartialEq` is implemented for `i32` + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0275`. From 2090303941b9863868ec485d9db62f3361247e10 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 19 Jun 2024 09:06:13 +0000 Subject: [PATCH 5/6] Switch DefineOpaqueTypes::No to Yes where the self type can't be an opaque anyway --- .../src/traits/select/candidate_assembly.rs | 7 +++---- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 98136c98c3597..73c7aa30b1575 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -899,10 +899,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } } - ty::Infer(ty::TyVar(_)) => { - debug!("assemble_candidates_from_object_ty: ambiguous"); - candidates.ambiguous = true; // could wind up being an object type - return; + ty::Infer(ty::TyVar(_)) => bug!("assemble_candidates_from_object_ty is already gated behind an infer var check"), + ty::Alias(ty::Opaque, alias) if self.infcx.can_define_opaque_ty(alias.def_id) => { + bug!("assemble_candidates_from_object_ty is already gated behind an opaque type "); } _ => return, }; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 2c52c23cbd4bd..fd5fa2a4f2b7d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1688,7 +1688,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); self.infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, placeholder_trait_ref, trait_bound) + .eq(DefineOpaqueTypes::Yes, placeholder_trait_ref, trait_bound) .map(|InferOk { obligations: _, value: () }| { // This method is called within a probe, so we can't have // inference variables and placeholders escape. From 513b139b633e84d0bd5a89d14ca9928821ddb6ec Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 26 Jun 2024 16:08:24 +0000 Subject: [PATCH 6/6] WIP --- .../rustc_trait_selection/src/traits/select/confirmation.rs | 2 +- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 9508a3e8e1509..4694587cbb59d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -195,7 +195,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligations.extend( self.infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate) + .eq(DefineOpaqueTypes::Yes, placeholder_trait_predicate, candidate) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| Unimplemented)?, ); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fd5fa2a4f2b7d..0f9ace28851f8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1752,7 +1752,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let is_match = self .infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, obligation.predicate, infer_projection) + .eq(DefineOpaqueTypes::Yes, obligation.predicate, infer_projection) .is_ok_and(|InferOk { obligations, value: () }| { self.evaluate_predicates_recursively( TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),