diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 7ed73a3f6fe6d..2a6c341b662c1 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -67,8 +67,8 @@ impl<'tcx> MirPass<'tcx> for Validator { unwind_edge_count: 0, reachable_blocks: traversal::reachable_as_bitset(body), storage_liveness, - place_cache: Vec::new(), - value_cache: Vec::new(), + place_cache: FxHashSet::default(), + value_cache: FxHashSet::default(), }; checker.visit_body(body); checker.check_cleanup_control_flow(); @@ -95,8 +95,8 @@ struct TypeChecker<'a, 'tcx> { unwind_edge_count: usize, reachable_blocks: BitSet, storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive<'static>>, - place_cache: Vec>, - value_cache: Vec, + place_cache: FxHashSet>, + value_cache: FxHashSet, } impl<'a, 'tcx> TypeChecker<'a, 'tcx> { @@ -951,10 +951,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.value_cache.clear(); self.value_cache.extend(targets.iter().map(|(value, _)| value)); - let all_len = self.value_cache.len(); - self.value_cache.sort_unstable(); - self.value_cache.dedup(); - let has_duplicates = all_len != self.value_cache.len(); + let has_duplicates = targets.iter().len() != self.value_cache.len(); if has_duplicates { self.fail( location, @@ -987,16 +984,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // passed by a reference to the callee. Consequently they must be non-overlapping. // Currently this simply checks for duplicate places. self.place_cache.clear(); - self.place_cache.push(destination.as_ref()); + self.place_cache.insert(destination.as_ref()); + let mut has_duplicates = false; for arg in args { if let Operand::Move(place) = arg { - self.place_cache.push(place.as_ref()); + has_duplicates |= !self.place_cache.insert(place.as_ref()); } } - let all_len = self.place_cache.len(); - let mut dedup = FxHashSet::default(); - self.place_cache.retain(|p| dedup.insert(*p)); - let has_duplicates = all_len != self.place_cache.len(); + if has_duplicates { self.fail( location, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 2999e1fd89ba4..22e576e345e1f 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -669,11 +669,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( ) .fold_with(&mut collector); - debug_assert_ne!( - collector.types.len(), - 0, - "expect >1 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`" - ); + if !unnormalized_trait_sig.output().references_error() { + debug_assert_ne!( + collector.types.len(), + 0, + "expect >1 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`" + ); + } let trait_sig = ocx.normalize(&norm_cause, param_env, unnormalized_trait_sig); trait_sig.error_reported()?; diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index b5a7d0326a88d..9f440f39849a8 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -25,9 +25,11 @@ impl<'tcx> InferCtxt<'tcx> { "impl has stricter requirements than trait" ); - if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) { - let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); - err.span_label(span, format!("definition of `{}` from trait", item_name)); + if !self.tcx.is_impl_trait_in_trait(trait_item_def_id) { + if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) { + let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); + err.span_label(span, format!("definition of `{}` from trait", item_name)); + } } err.span_label(error_span, format!("impl has extra requirement {}", requirement)); diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 6fb788e296f21..74dfbdddbab95 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -837,7 +837,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - pub(super) fn can_define_opaque_ty(&mut self, def_id: LocalDefId) -> bool { + pub(super) fn can_define_opaque_ty(&self, def_id: LocalDefId) -> bool { self.infcx.opaque_type_origin(def_id).is_some() } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index 366e9aa793d71..0800738a3f2bc 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -173,10 +173,18 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>( victim_idx >= other_idx } (_, CandidateSource::ParamEnv(_)) => true, + + ( + CandidateSource::BuiltinImpl(BuiltinImplSource::Object), + CandidateSource::BuiltinImpl(BuiltinImplSource::Object), + ) => false, + (_, CandidateSource::BuiltinImpl(BuiltinImplSource::Object)) => true, + (CandidateSource::Impl(victim_def_id), CandidateSource::Impl(other_def_id)) => { tcx.specializes((other_def_id, victim_def_id)) && other.result.value.certainty == Certainty::Yes } + _ => false, } } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 7ff47295e7cad..cd68626bed1ae 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -7,6 +7,7 @@ use rustc_hir::{LangItem, Movability}; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::util::supertraits; use rustc_middle::traits::solve::{CanonicalResponse, Certainty, Goal, QueryResult}; +use rustc_middle::traits::Reveal; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections}; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; use rustc_middle::ty::{TraitPredicate, TypeVisitableExt}; @@ -118,6 +119,32 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { return result; } + // Don't call `type_of` on a local TAIT that's in the defining scope, + // since that may require calling `typeck` on the same item we're + // currently type checking, which will result in a fatal cycle that + // ideally we want to avoid, since we can make progress on this goal + // via an alias bound or a locally-inferred hidden type instead. + // + // Also, don't call `type_of` on a TAIT in `Reveal::All` mode, since + // we already normalize the self type in + // `assemble_candidates_after_normalizing_self_ty`, and we'd + // just be registering an identical candidate here. + // + // Returning `Err(NoSolution)` here is ok in `SolverMode::Coherence` + // since we'll always be registering an ambiguous candidate in + // `assemble_candidates_after_normalizing_self_ty` due to normalizing + // the TAIT. + if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() { + if matches!(goal.param_env.reveal(), Reveal::All) + || opaque_ty + .def_id + .as_local() + .is_some_and(|def_id| ecx.can_define_opaque_ty(def_id)) + { + return Err(NoSolution); + } + } + ecx.probe_and_evaluate_goal_for_constituent_tys( goal, structural_traits::instantiate_constituent_tys_for_auto_trait, diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index fa23367593dbc..8ef2bac9282cd 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1319,56 +1319,39 @@ impl Clone for Box { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq> for Box -where - T: ?Sized + PartialEq, - A1: Allocator, - A2: Allocator, -{ +impl PartialEq for Box { #[inline] - fn eq(&self, other: &Box) -> bool { + fn eq(&self, other: &Self) -> bool { PartialEq::eq(&**self, &**other) } - #[inline] - fn ne(&self, other: &Box) -> bool { + fn ne(&self, other: &Self) -> bool { PartialEq::ne(&**self, &**other) } } - #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd> for Box -where - T: ?Sized + PartialOrd, - A1: Allocator, - A2: Allocator, -{ +impl PartialOrd for Box { #[inline] - fn partial_cmp(&self, other: &Box) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { PartialOrd::partial_cmp(&**self, &**other) } - #[inline] - fn lt(&self, other: &Box) -> bool { + fn lt(&self, other: &Self) -> bool { PartialOrd::lt(&**self, &**other) } - #[inline] - fn le(&self, other: &Box) -> bool { + fn le(&self, other: &Self) -> bool { PartialOrd::le(&**self, &**other) } - #[inline] - fn ge(&self, other: &Box) -> bool { + fn ge(&self, other: &Self) -> bool { PartialOrd::ge(&**self, &**other) } - #[inline] - fn gt(&self, other: &Box) -> bool { + fn gt(&self, other: &Self) -> bool { PartialOrd::gt(&**self, &**other) } } - #[stable(feature = "rust1", since = "1.0.0")] impl Ord for Box { #[inline] diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index a66e6ccf67312..7097dfef88d4e 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -53,7 +53,7 @@ pub struct BufReader { } impl BufReader { - /// Creates a new `BufReader` with a default buffer capacity. The default is currently 8 KB, + /// Creates a new `BufReader` with a default buffer capacity. The default is currently 8 KiB, /// but may change in the future. /// /// # Examples diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs index 0e2450655e5bf..0f04f29111793 100644 --- a/library/std/src/io/buffered/bufwriter.rs +++ b/library/std/src/io/buffered/bufwriter.rs @@ -81,7 +81,7 @@ pub struct BufWriter { } impl BufWriter { - /// Creates a new `BufWriter` with a default buffer capacity. The default is currently 8 KB, + /// Creates a new `BufWriter` with a default buffer capacity. The default is currently 8 KiB, /// but may change in the future. /// /// # Examples diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr new file mode 100644 index 0000000000000..56973a1d11a94 --- /dev/null +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr @@ -0,0 +1,39 @@ +error[E0726]: implicit elided lifetime not allowed here + --> $DIR/return-not-existing-pair.rs:12:20 + | +LL | impl<'a, 'b, T, U> MyTrait for U { + | ^^^^^^^^^^ expected lifetime parameters + | +help: indicate the anonymous lifetimes + | +LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U { + | +++++++ + +error[E0412]: cannot find type `ConnImpl` in this scope + --> $DIR/return-not-existing-pair.rs:8:48 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); + | ^^^^^^^^ not found in this scope + +error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl + --> $DIR/return-not-existing-pair.rs:14:5 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); + | ------------------------------------------------------------ `&self` used in trait +... +LL | async fn foo(_: T) -> (&'a U, &'b T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl + +error[E0308]: mismatched types + --> $DIR/return-not-existing-pair.rs:14:42 + | +LL | async fn foo(_: T) -> (&'a U, &'b T) {} + | ^^ expected `(&U, &T)`, found `()` + | + = note: expected tuple `(&'a U, &'b T)` + found unit type `()` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0186, E0308, E0412, E0726. +For more information about an error, try `rustc --explain E0186`. diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr new file mode 100644 index 0000000000000..56973a1d11a94 --- /dev/null +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr @@ -0,0 +1,39 @@ +error[E0726]: implicit elided lifetime not allowed here + --> $DIR/return-not-existing-pair.rs:12:20 + | +LL | impl<'a, 'b, T, U> MyTrait for U { + | ^^^^^^^^^^ expected lifetime parameters + | +help: indicate the anonymous lifetimes + | +LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U { + | +++++++ + +error[E0412]: cannot find type `ConnImpl` in this scope + --> $DIR/return-not-existing-pair.rs:8:48 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); + | ^^^^^^^^ not found in this scope + +error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl + --> $DIR/return-not-existing-pair.rs:14:5 + | +LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); + | ------------------------------------------------------------ `&self` used in trait +... +LL | async fn foo(_: T) -> (&'a U, &'b T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl + +error[E0308]: mismatched types + --> $DIR/return-not-existing-pair.rs:14:42 + | +LL | async fn foo(_: T) -> (&'a U, &'b T) {} + | ^^ expected `(&U, &T)`, found `()` + | + = note: expected tuple `(&'a U, &'b T)` + found unit type `()` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0186, E0308, E0412, E0726. +For more information about an error, try `rustc --explain E0186`. diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.rs b/tests/ui/async-await/in-trait/return-not-existing-pair.rs new file mode 100644 index 0000000000000..d1b3832d12b56 --- /dev/null +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.rs @@ -0,0 +1,19 @@ +// edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + +#![feature(async_fn_in_trait)] + +trait MyTrait<'a, 'b, T> { + async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); + //~^ ERROR: cannot find type `ConnImpl` in this scope [E0412] +} + +impl<'a, 'b, T, U> MyTrait for U { + //~^ ERROR: implicit elided lifetime not allowed here [E0726] + async fn foo(_: T) -> (&'a U, &'b T) {} + //~^ ERROR: method `foo` has a `&self` declaration in the trait, but not in the impl [E0186] + //~| ERROR: mismatched types [E0308] +} + +fn main() {} diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr new file mode 100644 index 0000000000000..2564d68d591af --- /dev/null +++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/return-not-existing-type-wrapping-rpitit.rs:10:25 + | +LL | fn bar() -> Wrapper>; + | ^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr new file mode 100644 index 0000000000000..2564d68d591af --- /dev/null +++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/return-not-existing-type-wrapping-rpitit.rs:10:25 + | +LL | fn bar() -> Wrapper>; + | ^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs new file mode 100644 index 0000000000000..37c02827e8d1a --- /dev/null +++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs @@ -0,0 +1,20 @@ +// edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + +#![feature(return_position_impl_trait_in_trait)] + +struct Wrapper(T); + +trait Foo { + fn bar() -> Wrapper>; + //~^ ERROR: cannot find type `Missing` in this scope [E0412] +} + +impl Foo for () { + fn bar() -> Wrapper { + Wrapper(0) + } +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs index 08c08e8307628..028222f4e6dba 100644 --- a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs +++ b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs @@ -1,5 +1,5 @@ // compile-flags: -Ztrait-solver=next -// known-bug: #112825 +// check-pass // Makes sure we don't prepopulate the MIR typeck of `define` // with `Foo = T`, but instead, `Foo = B`, so that diff --git a/tests/ui/traits/new-solver/dont-remap-tait-substs.stderr b/tests/ui/traits/new-solver/dont-remap-tait-substs.stderr deleted file mode 100644 index 769eea7dfd68b..0000000000000 --- a/tests/ui/traits/new-solver/dont-remap-tait-substs.stderr +++ /dev/null @@ -1,99 +0,0 @@ -error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` - --> $DIR/dont-remap-tait-substs.rs:10:24 - | -LL | type Foo = impl NeedsSend; - | ^^^^^^^^^^^^^^^^^ - | -note: ...which requires borrow-checking `define`... - --> $DIR/dont-remap-tait-substs.rs:15:1 - | -LL | fn define(a: A, b: B) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = 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/dont-remap-tait-substs.rs:8:1 - | -LL | / #![feature(type_alias_impl_trait)] -LL | | -LL | | type Foo = impl NeedsSend; -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ - -error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` - --> $DIR/dont-remap-tait-substs.rs:10:24 - | -LL | type Foo = impl NeedsSend; - | ^^^^^^^^^^^^^^^^^ - | -note: ...which requires borrow-checking `define`... - --> $DIR/dont-remap-tait-substs.rs:15:1 - | -LL | fn define(a: A, b: B) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = 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/dont-remap-tait-substs.rs:8:1 - | -LL | / #![feature(type_alias_impl_trait)] -LL | | -LL | | type Foo = impl NeedsSend; -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ - -error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` - --> $DIR/dont-remap-tait-substs.rs:10:24 - | -LL | type Foo = impl NeedsSend; - | ^^^^^^^^^^^^^^^^^ - | -note: ...which requires borrow-checking `define`... - --> $DIR/dont-remap-tait-substs.rs:15:1 - | -LL | fn define(a: A, b: B) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = 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/dont-remap-tait-substs.rs:8:1 - | -LL | / #![feature(type_alias_impl_trait)] -LL | | -LL | | type Foo = impl NeedsSend; -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ - -error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` - --> $DIR/dont-remap-tait-substs.rs:10:24 - | -LL | type Foo = impl NeedsSend; - | ^^^^^^^^^^^^^^^^^ - | -note: ...which requires borrow-checking `define`... - --> $DIR/dont-remap-tait-substs.rs:15:1 - | -LL | fn define(a: A, b: B) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = 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/dont-remap-tait-substs.rs:8:1 - | -LL | / #![feature(type_alias_impl_trait)] -LL | | -LL | | type Foo = impl NeedsSend; -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr new file mode 100644 index 0000000000000..ec1c3231abc71 --- /dev/null +++ b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr @@ -0,0 +1,16 @@ +error[E0283]: type annotations needed: cannot satisfy `Foo: Send` + --> $DIR/dont-type_of-tait-in-defining-scope.rs:16:5 + | +LL | needs_send::(); + | ^^^^^^^^^^^^^^^^^ + | + = note: cannot satisfy `Foo: Send` +note: required by a bound in `needs_send` + --> $DIR/dont-type_of-tait-in-defining-scope.rs:13:18 + | +LL | fn needs_send() {} + | ^^^^ required by this bound in `needs_send` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs new file mode 100644 index 0000000000000..5a0dcd0e8ccea --- /dev/null +++ b/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs @@ -0,0 +1,22 @@ +// revisions: is_send not_send +// compile-flags: -Ztrait-solver=next +//[is_send] check-pass + +#![feature(type_alias_impl_trait)] + +#[cfg(is_send)] +type Foo = impl Send; + +#[cfg(not_send)] +type Foo = impl Sized; + +fn needs_send() {} + +fn test() { + needs_send::(); + //[not_send]~^ ERROR type annotations needed: cannot satisfy `Foo: Send` +} + +fn main() { + let _: Foo = (); +} diff --git a/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs b/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs new file mode 100644 index 0000000000000..7d15b8c639250 --- /dev/null +++ b/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs @@ -0,0 +1,13 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +use std::any::Any; + +fn needs_usize(_: &usize) {} + +fn main() { + let x: &dyn Any = &1usize; + if let Some(x) = x.downcast_ref::() { + needs_usize(x); + } +} diff --git a/tests/ui/type-alias-impl-trait/issue-109054.rs b/tests/ui/type-alias-impl-trait/issue-109054.rs new file mode 100644 index 0000000000000..1fbec47b14bcd --- /dev/null +++ b/tests/ui/type-alias-impl-trait/issue-109054.rs @@ -0,0 +1,22 @@ +// edition:2021 + +#![feature(type_alias_impl_trait)] + +struct CallMe; + +type ReturnType<'a> = impl std::future::Future + 'a; +type FnType = impl Fn(&u32) -> ReturnType; + +impl std::ops::Deref for CallMe { + type Target = FnType; + + fn deref(&self) -> &Self::Target { + fn inner(val: &u32) -> ReturnType { + async move { *val * 2 } + } + + &inner //~ ERROR: expected generic lifetime parameter, found `'_` + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-109054.stderr b/tests/ui/type-alias-impl-trait/issue-109054.stderr new file mode 100644 index 0000000000000..a611b9fe448e1 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/issue-109054.stderr @@ -0,0 +1,12 @@ +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/issue-109054.rs:18:9 + | +LL | type ReturnType<'a> = impl std::future::Future + 'a; + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | &inner + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-inference/issue-113283-alllocator-trait-eq.rs b/tests/ui/type-inference/issue-113283-alllocator-trait-eq.rs new file mode 100644 index 0000000000000..5d0e456d9ddc0 --- /dev/null +++ b/tests/ui/type-inference/issue-113283-alllocator-trait-eq.rs @@ -0,0 +1,18 @@ +// run-pass +// Verify that PartialEq implementations do not break type inference when +// accepting types with different allocators + +use std::rc::Rc; +use std::sync::Arc; + + +fn main() { + let boxed: Vec> = vec![]; + assert_eq!(boxed, vec![]); + + let rc: Vec> = vec![]; + assert_eq!(rc, vec![]); + + let arc: Vec> = vec![]; + assert_eq!(arc, vec![]); +}