Skip to content
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

Fix feature = "nightly" in the new trait solver #126649

Merged
merged 2 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4913,6 +4913,7 @@ version = "0.0.0"
dependencies = [
"bitflags 2.5.0",
"derivative",
"indexmap",
"rustc_ast_ir",
"rustc_data_structures",
"rustc_index",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_next_trait_solver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2021"
# tidy-alphabetical-start
bitflags = "2.4.1"
derivative = "2.2.0"
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
rustc_index = { path = "../rustc_index", default-features = false }
rustc_macros = { path = "../rustc_macros", optional = true }
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_next_trait_solver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
//! but were uplifted in the process of making the new trait solver generic.
//! So if you got to this crate from the old solver, it's totally normal.

#![feature(let_chains)]

pub mod canonicalizer;
pub mod infcx;
pub mod resolve;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! traits, `Copy`/`Clone`.

use rustc_ast_ir::{Movability, Mutability};
use rustc_data_structures::fx::FxHashMap;
use rustc_type_ir::data_structures::HashMap;
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
Expand Down Expand Up @@ -304,9 +304,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
let kind_ty = args.kind_ty();
let sig = args.coroutine_closure_sig().skip_binder();

let coroutine_ty = if let Some(closure_kind) = kind_ty.to_opt_closure_kind()
&& !args.tupled_upvars_ty().is_ty_var()
{
// FIXME: let_chains
let kind = kind_ty.to_opt_closure_kind();
let coroutine_ty = if kind.is_some() && !args.tupled_upvars_ty().is_ty_var() {
let closure_kind = kind.unwrap();
Comment on lines +307 to +310
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// FIXME: let_chains
let kind = kind_ty.to_opt_closure_kind();
let coroutine_ty = if kind.is_some() && !args.tupled_upvars_ty().is_ty_var() {
let closure_kind = kind.unwrap();
let coroutine_ty = if let Some(kind) = kind_ty.to_opt_closure_kind().filter(|_| !args.tupled_upvars_ty().is_ty_var()) {

Copy link
Member Author

@compiler-errors compiler-errors Jun 19, 2024

Choose a reason for hiding this comment

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

I feel like this is so much harder to read. I'd really rather unwrap, or restructure the whole block to just be nested ifs.

if !closure_kind.extends(goal_kind) {
return Err(NoSolution);
}
Expand Down Expand Up @@ -411,10 +412,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
let kind_ty = args.kind_ty();
let sig = args.coroutine_closure_sig().skip_binder();
let mut nested = vec![];
let coroutine_ty = if let Some(closure_kind) = kind_ty.to_opt_closure_kind()
&& !args.tupled_upvars_ty().is_ty_var()
{
if !closure_kind.extends(goal_kind) {

// FIXME: let_chains
let kind = kind_ty.to_opt_closure_kind();
let coroutine_ty = if kind.is_some() && !args.tupled_upvars_ty().is_ty_var() {
Copy link
Contributor

Choose a reason for hiding this comment

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

same here

if !kind.unwrap().extends(goal_kind) {
return Err(NoSolution);
}

Expand Down Expand Up @@ -683,7 +685,7 @@ where
);
}

let mut replace_projection_with = FxHashMap::default();
let mut replace_projection_with = HashMap::default();
for bound in object_bounds {
if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() {
let proj = proj.with_self_ty(tcx, trait_ref.self_ty());
Expand Down Expand Up @@ -713,7 +715,7 @@ where
struct ReplaceProjectionWith<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> {
ecx: &'a EvalCtxt<'a, Infcx>,
param_env: I::ParamEnv,
mapping: FxHashMap<I::DefId, ty::Binder<I, ty::ProjectionPredicate<I>>>,
mapping: HashMap<I::DefId, ty::Binder<I, ty::ProjectionPredicate<I>>>,
nested: Vec<Goal<I, I::Predicate>>,
}

Expand All @@ -725,24 +727,28 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
}

fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
if let ty::Alias(ty::Projection, alias_ty) = ty.kind()
&& let Some(replacement) = self.mapping.get(&alias_ty.def_id)
{
// We may have a case where our object type's projection bound is higher-ranked,
// but the where clauses we instantiated are not. We can solve this by instantiating
// the binder at the usage site.
let proj = self.ecx.instantiate_binder_with_infer(*replacement);
// FIXME: Technically this equate could be fallible...
self.nested.extend(
self.ecx
.eq_and_get_goals(
self.param_env,
alias_ty,
proj.projection_term.expect_ty(self.ecx.interner()),
)
.expect("expected to be able to unify goal projection with dyn's projection"),
);
proj.term.expect_ty()
if let ty::Alias(ty::Projection, alias_ty) = ty.kind() {
if let Some(replacement) = self.mapping.get(&alias_ty.def_id) {
// We may have a case where our object type's projection bound is higher-ranked,
// but the where clauses we instantiated are not. We can solve this by instantiating
// the binder at the usage site.
let proj = self.ecx.instantiate_binder_with_infer(*replacement);
// FIXME: Technically this equate could be fallible...
self.nested.extend(
self.ecx
.eq_and_get_goals(
self.param_env,
alias_ty,
proj.projection_term.expect_ty(self.ecx.interner()),
)
.expect(
"expected to be able to unify goal projection with dyn's projection",
),
);
proj.term.expect_ty()
} else {
ty.super_fold_with(self)
}
} else {
ty.super_fold_with(self)
}
Expand Down
41 changes: 24 additions & 17 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::ops::ControlFlow;

use rustc_data_structures::stack::ensure_sufficient_stack;
#[cfg(feature = "nightly")]
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
use rustc_type_ir::data_structures::ensure_sufficient_stack;
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_type_ir::inherent::*;
use rustc_type_ir::relate::Relate;
Expand Down Expand Up @@ -88,7 +89,7 @@ where
#[derive(derivative::Derivative)]
#[derivative(Clone(bound = ""), Debug(bound = ""), Default(bound = ""))]
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
#[derive(TyDecodable, TyEncodable, HashStable_NoContext)]
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
// FIXME: This can be made crate-private once `EvalCtxt` also lives in this crate.
pub struct NestedGoals<I: Interner> {
/// These normalizes-to goals are treated specially during the evaluation
Expand Down Expand Up @@ -116,7 +117,8 @@ impl<I: Interner> NestedGoals<I> {
}
}

#[derive(PartialEq, Eq, Debug, Hash, HashStable_NoContext, Clone, Copy)]
#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)]
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
pub enum GenerateProofTree {
Yes,
No,
Expand Down Expand Up @@ -689,14 +691,15 @@ where
fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
match t.kind() {
ty::Infer(ty::TyVar(vid)) => {
if let ty::TermKind::Ty(term) = self.term.kind()
&& let ty::Infer(ty::TyVar(term_vid)) = term.kind()
&& self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid)
{
ControlFlow::Break(())
} else {
self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
if let ty::TermKind::Ty(term) = self.term.kind() {
if let ty::Infer(ty::TyVar(term_vid)) = term.kind() {
if self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid) {
return ControlFlow::Break(());
}
}
}

self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
}
ty::Placeholder(p) => self.check_nameable(p.universe()),
_ => {
Expand All @@ -712,14 +715,18 @@ where
fn visit_const(&mut self, c: I::Const) -> Self::Result {
match c.kind() {
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
if let ty::TermKind::Const(term) = self.term.kind()
&& let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
&& self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid)
{
ControlFlow::Break(())
} else {
self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
if let ty::TermKind::Const(term) = self.term.kind() {
if let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
{
if self.infcx.root_const_var(vid)
== self.infcx.root_const_var(term_vid)
{
return ControlFlow::Break(());
}
}
}

self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
}
ty::ConstKind::Placeholder(p) => self.check_nameable(p.universe()),
_ => {
Expand Down
17 changes: 11 additions & 6 deletions compiler/rustc_next_trait_solver/src/solve/search_graph.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::mem;

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_index::{Idx, IndexVec};
use rustc_type_ir::data_structures::{HashMap, HashSet};
use rustc_type_ir::inherent::*;
use rustc_type_ir::Interner;
use tracing::debug;
Expand All @@ -17,6 +17,7 @@ pub struct SolverLimit(usize);

rustc_index::newtype_index! {
#[orderable]
#[gate_rustc_only]
pub struct StackDepth {}
}

Expand Down Expand Up @@ -70,7 +71,7 @@ struct StackEntry<I: Interner> {
/// C :- D
/// D :- C
/// ```
cycle_participants: FxHashSet<CanonicalInput<I>>,
cycle_participants: HashSet<CanonicalInput<I>>,
/// Starts out as `None` and gets set when rerunning this
/// goal in case we encounter a cycle.
provisional_result: Option<QueryResult<I>>,
Expand Down Expand Up @@ -126,7 +127,7 @@ pub(super) struct SearchGraph<I: Interner> {
///
/// An element is *deeper* in the stack if its index is *lower*.
stack: IndexVec<StackDepth, StackEntry<I>>,
provisional_cache: FxHashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
provisional_cache: HashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
}

impl<I: Interner> SearchGraph<I> {
Expand Down Expand Up @@ -227,13 +228,17 @@ impl<I: Interner> SearchGraph<I> {
}

fn clear_dependent_provisional_results(
provisional_cache: &mut FxHashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
provisional_cache: &mut HashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
head: StackDepth,
) {
#[allow(rustc::potential_query_instability)]
provisional_cache.retain(|_, entry| {
entry.with_coinductive_stack.take_if(|p| p.head == head);
entry.with_inductive_stack.take_if(|p| p.head == head);
if entry.with_coinductive_stack.as_ref().is_some_and(|p| p.head == head) {
entry.with_coinductive_stack.take();
}
if entry.with_inductive_stack.as_ref().is_some_and(|p| p.head == head) {
entry.with_inductive_stack.take();
}
!entry.is_empty()
});
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Dealing with trait goals, i.e. `T: Trait<'a, U>`.

use rustc_ast_ir::Movability;
use rustc_data_structures::fx::FxIndexSet;
use rustc_type_ir::data_structures::IndexSet;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::visit::TypeVisitableExt as _;
Expand Down Expand Up @@ -821,7 +821,7 @@ where
// We may upcast to auto traits that are either explicitly listed in
// the object type's bounds, or implied by the principal trait ref's
// supertraits.
let a_auto_traits: FxIndexSet<I::DefId> = a_data
let a_auto_traits: IndexSet<I::DefId> = a_data
.auto_traits()
.into_iter()
.chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_type_ir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ edition = "2021"
# tidy-alphabetical-start
bitflags = "2.4.1"
derivative = "2.2.0"
rustc_ast_ir = { path = "../rustc_ast_ir" }
indexmap = "2.0.0"
rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
rustc_index = { path = "../rustc_index", default-features = false }
rustc_macros = { path = "../rustc_macros", optional = true }
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_type_ir/src/binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ use std::ops::{ControlFlow, Deref};

#[cfg(feature = "nightly")]
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
#[cfg(feature = "nightly")]
use rustc_serialize::Decodable;
use tracing::debug;

use crate::data_structures::SsoHashSet;
use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
use crate::inherent::*;
use crate::lift::Lift;
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
use crate::{self as ty, Interner, SsoHashSet};
use crate::{self as ty, Interner};

/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
/// compiler's representation for things like `for<'a> Fn(&'a isize)`
Expand Down Expand Up @@ -55,6 +57,7 @@ where
}
}

#[cfg(feature = "nightly")]
macro_rules! impl_binder_encode_decode {
($($t:ty),+ $(,)?) => {
$(
Expand Down Expand Up @@ -82,6 +85,7 @@ macro_rules! impl_binder_encode_decode {
}
}

#[cfg(feature = "nightly")]
impl_binder_encode_decode! {
ty::FnSig<I>,
ty::TraitPredicate<I>,
Expand Down
29 changes: 29 additions & 0 deletions compiler/rustc_type_ir/src/data_structures.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#[cfg(feature = "nightly")]
mod impl_ {
pub use rustc_data_structures::fx::FxHashMap as HashMap;
pub use rustc_data_structures::fx::FxHashSet as HashSet;
pub use rustc_data_structures::fx::FxIndexMap as IndexMap;
pub use rustc_data_structures::fx::FxIndexSet as IndexSet;
pub use rustc_data_structures::sso::SsoHashMap;
pub use rustc_data_structures::sso::SsoHashSet;
pub use rustc_data_structures::stack::ensure_sufficient_stack;
pub use rustc_data_structures::sync::Lrc;
}

#[cfg(not(feature = "nightly"))]
mod impl_ {
pub use indexmap::IndexMap;
pub use indexmap::IndexSet;
pub use std::collections::HashMap;
pub use std::collections::HashMap as SsoHashMap;
pub use std::collections::HashSet;
pub use std::collections::HashSet as SsoHashSet;
pub use std::sync::Arc as Lrc;

#[inline]
pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
f()
}
}

pub use impl_::*;
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl<T> ExpectedFound<T> {
Debug(bound = "")
)]
#[derive(TypeVisitable_Generic)]
#[rustc_pass_by_value]
#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
pub enum TypeError<I: Interner> {
Mismatch,
ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_type_ir/src/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ use rustc_index::{Idx, IndexVec};
use std::mem;
use tracing::debug;

use crate::data_structures::Lrc;
use crate::inherent::*;
use crate::visit::{TypeVisitable, TypeVisitableExt as _};
use crate::{self as ty, Interner, Lrc};
use crate::{self as ty, Interner};

#[cfg(feature = "nightly")]
type Never = !;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_type_ir/src/generic_arg.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(feature = "nightly")]
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};

use crate::Interner;
Expand Down
Loading
Loading