From cdaef2c435f9b15cbc7a63365a2b27e7a71230fb Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 24 May 2023 16:07:35 +0000 Subject: [PATCH 1/8] Simplify duplicate checks for mir validator --- .../src/transform/validate.rs | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 3c350e25ba6ec..0d4899d09dacc 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> { @@ -958,10 +958,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, @@ -994,16 +991,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, From 5488a64654d34530ecc3c512c8b87361faea137f Mon Sep 17 00:00:00 2001 From: Kathryn R Date: Fri, 26 May 2023 13:39:10 -0700 Subject: [PATCH 2/8] Fix incorrect documented default bufsize in bufreader/writer --- library/std/src/io/buffered/bufreader.rs | 2 +- library/std/src/io/buffered/bufwriter.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 4f339a18a480e..0cc63dcb47d63 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 14c455d4fa3c9..aac52ec354013 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 From 8725c5d01f06bd70a2ce3ffe4c10be49fd30807d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 28 Jun 2023 17:41:04 +0000 Subject: [PATCH 3/8] Don't call type_of on TAIT in defining scope in new solver --- .../src/solve/eval_ctxt.rs | 2 +- .../src/solve/trait_goals.rs | 27 +++++++++++++++++++ ..._of-tait-in-defining-scope.not_send.stderr | 16 +++++++++++ .../dont-type_of-tait-in-defining-scope.rs | 22 +++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr create mode 100644 tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 6aca40b8dbd98..533426bea4b11 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -785,7 +785,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/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 18fec6d9c890a..bf36a8a1cce02 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -8,6 +8,7 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::util::supertraits; use rustc_middle::traits::solve::inspect::CandidateKind; 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}; @@ -120,6 +121,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/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 = (); +} From 86728e74e043aca318643d0d1bae724f3078bc33 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 29 Jun 2023 23:55:34 +0900 Subject: [PATCH 4/8] Add a regression test for #109054 Signed-off-by: Yuki Okushi --- .../ui/type-alias-impl-trait/issue-109054.rs | 22 +++++++++++++++++++ .../type-alias-impl-trait/issue-109054.stderr | 12 ++++++++++ 2 files changed, 34 insertions(+) create mode 100644 tests/ui/type-alias-impl-trait/issue-109054.rs create mode 100644 tests/ui/type-alias-impl-trait/issue-109054.stderr 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`. From 3acaa568c25b7ab8cfb08d5b85f638f6baefae14 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 6 Jul 2023 04:48:33 +0000 Subject: [PATCH 5/8] Prefer object candidates over impl candidates in new selection --- .../src/solve/eval_ctxt/select.rs | 8 ++++++++ .../traits/new-solver/dyn-any-dont-prefer-impl.rs | 13 +++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs 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 18332d6811d56..ed238b36ee5fa 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/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); + } +} From eab00717e1da74d07cf155d866deed01c4c6bd2a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 4 Jul 2023 17:36:26 +0000 Subject: [PATCH 6/8] Remove an AFIT test that isn't an AFIT test --- .../in-trait/async-associated-types2.rs | 30 ------------------- 1 file changed, 30 deletions(-) delete mode 100644 tests/ui/async-await/in-trait/async-associated-types2.rs diff --git a/tests/ui/async-await/in-trait/async-associated-types2.rs b/tests/ui/async-await/in-trait/async-associated-types2.rs deleted file mode 100644 index b889f616a0311..0000000000000 --- a/tests/ui/async-await/in-trait/async-associated-types2.rs +++ /dev/null @@ -1,30 +0,0 @@ -// check-pass -// edition: 2021 -// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty -// revisions: current next - -#![feature(async_fn_in_trait)] -#![feature(impl_trait_in_assoc_type)] -#![allow(incomplete_features)] - -use std::future::Future; - -trait MyTrait { - type Fut<'a>: Future - where - Self: 'a; - - fn foo<'a>(&'a self) -> Self::Fut<'a>; -} - -impl MyTrait for i32 { - type Fut<'a> = impl Future + 'a - where - Self: 'a; - - fn foo<'a>(&'a self) -> Self::Fut<'a> { - async { *self } - } -} - -fn main() {} From 545ce3ebc47761936f70d047e6690641dc4ab527 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 4 Jul 2023 17:54:23 +0000 Subject: [PATCH 7/8] Mark more hanging new-solver tests --- tests/ui/issues/issue-67552.rs | 1 + tests/ui/issues/issue-67552.stderr | 4 ++-- tests/ui/recursion/issue-95134.rs | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/ui/issues/issue-67552.rs b/tests/ui/issues/issue-67552.rs index ec1997ccd5d66..7336b873dd643 100644 --- a/tests/ui/issues/issue-67552.rs +++ b/tests/ui/issues/issue-67552.rs @@ -1,6 +1,7 @@ // build-fail // compile-flags: -Copt-level=0 // normalize-stderr-test: ".nll/" -> "/" +// ignore-compare-mode-next-solver (hangs) fn main() { rec(Empty); diff --git a/tests/ui/issues/issue-67552.stderr b/tests/ui/issues/issue-67552.stderr index 4746f918bf8dd..f93ed67dab244 100644 --- a/tests/ui/issues/issue-67552.stderr +++ b/tests/ui/issues/issue-67552.stderr @@ -1,11 +1,11 @@ error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>` - --> $DIR/issue-67552.rs:29:9 + --> $DIR/issue-67552.rs:30:9 | LL | rec(identity(&mut it)) | ^^^^^^^^^^^^^^^^^^^^^^ | note: `rec` defined here - --> $DIR/issue-67552.rs:22:1 + --> $DIR/issue-67552.rs:23:1 | LL | / fn rec(mut it: T) LL | | where diff --git a/tests/ui/recursion/issue-95134.rs b/tests/ui/recursion/issue-95134.rs index 2f1cffa2fa907..7ee31d85c2b12 100644 --- a/tests/ui/recursion/issue-95134.rs +++ b/tests/ui/recursion/issue-95134.rs @@ -3,6 +3,7 @@ // compile-flags: -Copt-level=0 // dont-check-failure-status // dont-check-compiler-stderr +// ignore-compare-mode-next-solver (hangs) pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { if n > 15 { From 3247275323b3a0ac96b4f0472726e7eee9303283 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 4 Jul 2023 18:49:13 +0000 Subject: [PATCH 8/8] Normalize opaques during codegen in new solver --- .../src/solve/normalize.rs | 4 +-- .../param-env-region-infer.current.stderr | 2 +- .../param-env-region-infer.next.stderr | 29 +++++++++++++++++++ tests/ui/dyn-star/param-env-region-infer.rs | 6 ++-- tests/ui/impl-trait/reveal-during-codegen.rs | 11 +++++++ 5 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 tests/ui/dyn-star/param-env-region-infer.next.stderr create mode 100644 tests/ui/impl-trait/reveal-during-codegen.rs diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index c0ee1a576e5fb..c388850d831e2 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -167,9 +167,7 @@ impl<'tcx> FallibleTypeFolder> for NormalizationFolder<'_, 'tcx> { // We don't normalize opaque types unless we have // `Reveal::All`, even if we're in the defining scope. let data = match *ty.kind() { - ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::UserFacing => { - alias_ty - } + ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::All => alias_ty, _ => return ty.try_super_fold_with(self), }; diff --git a/tests/ui/dyn-star/param-env-region-infer.current.stderr b/tests/ui/dyn-star/param-env-region-infer.current.stderr index c606a50c8a9cb..902053ecfef62 100644 --- a/tests/ui/dyn-star/param-env-region-infer.current.stderr +++ b/tests/ui/dyn-star/param-env-region-infer.current.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/param-env-region-infer.rs:16:10 + --> $DIR/param-env-region-infer.rs:18:10 | LL | t as _ | ^ cannot infer type diff --git a/tests/ui/dyn-star/param-env-region-infer.next.stderr b/tests/ui/dyn-star/param-env-region-infer.next.stderr new file mode 100644 index 0000000000000..dd724a6590829 --- /dev/null +++ b/tests/ui/dyn-star/param-env-region-infer.next.stderr @@ -0,0 +1,29 @@ +error[E0391]: cycle detected when computing type of `make_dyn_star::{opaque#0}` + --> $DIR/param-env-region-infer.rs:16:60 + | +LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `make_dyn_star`... + --> $DIR/param-env-region-infer.rs:16:1 + | +LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing layout of `make_dyn_star::{opaque#0}`... + = note: ...which requires normalizing `make_dyn_star::{opaque#0}`... + = note: ...which again requires computing type of `make_dyn_star::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/param-env-region-infer.rs:10:1 + | +LL | / #![feature(dyn_star, pointer_like_trait)] +LL | | #![allow(incomplete_features)] +LL | | +LL | | use std::fmt::Debug; +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/dyn-star/param-env-region-infer.rs b/tests/ui/dyn-star/param-env-region-infer.rs index 9c337e4a89bd3..537473abc3a5b 100644 --- a/tests/ui/dyn-star/param-env-region-infer.rs +++ b/tests/ui/dyn-star/param-env-region-infer.rs @@ -1,6 +1,7 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next -//[next] check-pass +// Need `-Zdeduplicate-diagnostics=yes` because the number of cycle errors +// emitted is for some horrible reason platform-specific. +//[next] compile-flags: -Ztrait-solver=next -Zdeduplicate-diagnostics=yes // incremental // checks that we don't ICE if there are region inference variables in the environment @@ -13,6 +14,7 @@ use std::fmt::Debug; use std::marker::PointerLike; fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { + //[next]~^ ERROR cycle detected when computing t as _ //[current]~^ ERROR type annotations needed } diff --git a/tests/ui/impl-trait/reveal-during-codegen.rs b/tests/ui/impl-trait/reveal-during-codegen.rs new file mode 100644 index 0000000000000..11463772eb38c --- /dev/null +++ b/tests/ui/impl-trait/reveal-during-codegen.rs @@ -0,0 +1,11 @@ +// build-pass +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next + +fn test() -> Option { + Some("") +} + +fn main() { + test(); +}