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

[DO NOT MERGE] bootstrap with next solver enabled #124812

Closed
wants to merge 18 commits into from
Closed
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
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! # Note
//!
//! This API is completely unstable and subject to change.

#![recursion_limit = "256"]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(deny(warnings)))
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_passes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"

[dependencies]
# tidy-alphabetical-start
itertools = "0.12"
itertools = { git = "https://github.com/rust-itertools/itertools" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"

[dependencies]
# tidy-alphabetical-start
itertools = "0.12"
itertools = { git = "https://github.com/rust-itertools/itertools" }
rustc_ast = { path = "../rustc_ast" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_span = { path = "../rustc_span" }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
# tidy-alphabetical-start
either = "1.5.0"
itertools = "0.12"
itertools = { git = "https://github.com/rust-itertools/itertools" }
polonius-engine = "0.13.0"
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ test = false
[dependencies]
# tidy-alphabetical-start
bitflags = "2.4.1"
itertools = "0.12"
itertools = { git = "https://github.com/rust-itertools/itertools" }
libc = "0.2"
measureme = "11"
object = { version = "0.32.0", default-features = false, features = ["std", "read"] }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ arrayvec = { version = "0.7", default-features = false }
bitflags = "2.4.1"
cc = "1.0.90"
either = "1.5.0"
itertools = "0.12"
itertools = { git = "https://github.com/rust-itertools/itertools" }
jobserver = "0.1.28"
pathdiff = "0.2.0"
regex = "1.4"
Expand Down
31 changes: 19 additions & 12 deletions compiler/rustc_data_structures/src/obligation_forest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,25 @@ pub enum ProcessResult<O, E> {
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
struct ObligationTreeId(usize);

type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
use uwu::*;

mod uwu {
use super::*;
pub type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;

impl<O: ForestObligation> ObligationForest<O> {
pub fn new() -> ObligationForest<O> {
ObligationForest {
nodes: vec![],
done_cache: Default::default(),
active_cache: Default::default(),
reused_node_vec: vec![],
obligation_tree_id_generator: (0..).map(ObligationTreeId),
error_cache: Default::default(),
}
}
}
}

pub struct ObligationForest<O: ForestObligation> {
/// The list of obligations. In between calls to [Self::process_obligations],
Expand Down Expand Up @@ -311,17 +329,6 @@ pub struct Error<O, E> {
}

impl<O: ForestObligation> ObligationForest<O> {
pub fn new() -> ObligationForest<O> {
ObligationForest {
nodes: vec![],
done_cache: Default::default(),
active_cache: Default::default(),
reused_node_vec: vec![],
obligation_tree_id_generator: (0..).map(ObligationTreeId),
error_cache: Default::default(),
}
}

/// Returns the total number of nodes in the forest that have not
/// yet been fully resolved.
pub fn len(&self) -> usize {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ doctest = false

[dependencies]
# tidy-alphabetical-start
itertools = "0.12"
itertools = { git = "https://github.com/rust-itertools/itertools" }
rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
Expand Down
68 changes: 19 additions & 49 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,12 @@ fn check_opaque_meets_bounds<'tcx>(
};
let param_env = tcx.param_env(defining_use_anchor);

let infcx = tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).build();
let infcx = tcx
.infer_ctxt()
.with_opaque_type_mode(ty::OpaqueTypeMode::Reveal(
tcx.opaque_types_defined_by(defining_use_anchor),
))
.build();
let ocx = ObligationCtxt::new(&infcx);

let args = match *origin {
Expand All @@ -359,42 +364,23 @@ fn check_opaque_meets_bounds<'tcx>(
}),
};

let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);

// `ReErased` regions appear in the "parent_args" of closures/coroutines.
// We're ignoring them here and replacing them with fresh region variables.
// See tests in ui/type-alias-impl-trait/closure_{parent_args,wf_outlives}.rs.
//
// FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
// here rather than using ReErased.
let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args);
let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() {
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
_ => re,
});

let misc_cause = traits::ObligationCause::misc(span, def_id);

match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
Ok(()) => {}
Err(ty_err) => {
// Some types may be left "stranded" if they can't be reached
// from a lowered rustc_middle bound but they're mentioned in the HIR.
// This will happen, e.g., when a nested opaque is inside of a non-
// existent associated type, like `impl Trait<Missing = impl Trait>`.
// See <tests/ui/impl-trait/stranded-opaque.rs>.
let ty_err = ty_err.to_string(tcx);
let guar = tcx.dcx().span_delayed_bug(
span,
format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"),
);
return Err(guar);
}
}
let predicates: Vec<_> = tcx.item_bounds(def_id).iter_instantiated(tcx, args).collect();
let predicates = ocx.normalize(&misc_cause, param_env, predicates);
ocx.register_obligations(
predicates
.into_iter()
.map(|clause| Obligation::new(tcx, misc_cause.clone(), param_env, clause)),
);

// Additionally require the hidden type to be well-formed with only the generics of the opaque type.
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
// hidden type is well formed even without those bounds.
let hidden_ty =
tcx.fold_regions(tcx.type_of(def_id).instantiate(tcx, args), |re, _| match *re {
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
_ => re,
});
let predicate =
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(hidden_ty.into())));
ocx.register_obligation(Obligation::new(tcx, misc_cause.clone(), param_env, predicate));
Expand All @@ -412,23 +398,7 @@ fn check_opaque_meets_bounds<'tcx>(
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;

if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin {
// HACK: this should also fall through to the hidden type check below, but the original
// implementation had a bug where equivalent lifetimes are not identical. This caused us
// to reject existing stable code that is otherwise completely fine. The real fix is to
// compare the hidden types via our type equivalence/relation infra instead of doing an
// identity check.
let _ = infcx.take_opaque_types();
Ok(())
} else {
// Check that any hidden types found during wf checking match the hidden types that `type_of` sees.
for (mut key, mut ty) in infcx.take_opaque_types() {
ty.hidden_type.ty = infcx.resolve_vars_if_possible(ty.hidden_type.ty);
key = infcx.resolve_vars_if_possible(key);
sanity_check_found_hidden_type(tcx, key, ty.hidden_type)?;
}
Ok(())
}
Ok(())
}

fn sanity_check_found_hidden_type<'tcx>(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"

[dependencies]
# tidy-alphabetical-start
itertools = "0.12"
itertools = { git = "https://github.com/rust-itertools/itertools" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_attr = { path = "../rustc_attr" }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl<'tcx> InferCtxt<'tcx> {
pub fn fork_with_intercrate(&self, intercrate: bool) -> Self {
Self {
tcx: self.tcx,
defining_opaque_types: self.defining_opaque_types,
opaque_type_mode: self.opaque_type_mode,
considering_regions: self.considering_regions,
skip_leak_check: self.skip_leak_check,
inner: self.inner.clone(),
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl<'tcx> InferCtxt<'tcx> {
},
);

param_env.defining_opaque_types = self.defining_opaque_types;
param_env.opaque_type_mode = self.opaque_type_mode;

Canonicalizer::canonicalize_with_base(
param_env,
Expand Down Expand Up @@ -544,7 +544,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
max_universe: ty::UniverseIndex::ROOT,
variables: List::empty(),
value: (),
defining_opaque_types: infcx.map(|i| i.defining_opaque_types).unwrap_or_default(),
opaque_type_mode: infcx.map(|i| i.opaque_type_mode).unwrap_or_default(),
};
Canonicalizer::canonicalize_with_base(
base,
Expand Down Expand Up @@ -614,14 +614,12 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
.max()
.unwrap_or(ty::UniverseIndex::ROOT);

assert!(
!infcx.is_some_and(|infcx| infcx.defining_opaque_types != base.defining_opaque_types)
);
assert!(!infcx.is_some_and(|infcx| infcx.opaque_type_mode != base.opaque_type_mode));
Canonical {
max_universe,
variables: canonical_variables,
value: (base.value, out_value),
defining_opaque_types: base.defining_opaque_types,
opaque_type_mode: base.opaque_type_mode,
}
}

Expand Down
65 changes: 44 additions & 21 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pub use relate::combine::CombineFields;
pub use relate::combine::ObligationEmittingRelation;
pub use relate::StructurallyRelateAliases;
pub use rustc_macros::{TypeFoldable, TypeVisitable};
use rustc_middle::traits::Reveal;
use rustc_middle::traits::TreatOpaque;
pub use rustc_middle::ty::IntVarValue;
pub use BoundRegionConversionTime::*;
pub use RegionVariableOrigin::*;
Expand Down Expand Up @@ -246,7 +248,7 @@ pub struct InferCtxt<'tcx> {
pub tcx: TyCtxt<'tcx>,

/// The `DefIds` of the opaque types that may have their hidden types constrained.
defining_opaque_types: &'tcx ty::List<LocalDefId>,
opaque_type_mode: ty::OpaqueTypeMode<TyCtxt<'tcx>>,

/// Whether this inference context should care about region obligations in
/// the root universe. Most notably, this is used during hir typeck as region
Expand Down Expand Up @@ -373,8 +375,8 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
}

fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
self.defining_opaque_types
fn opaque_type_mode(&self) -> ty::OpaqueTypeMode<TyCtxt<'tcx>> {
self.opaque_type_mode
}

fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> Ty<'tcx> {
Expand Down Expand Up @@ -621,7 +623,7 @@ impl fmt::Display for FixupError {
/// Used to configure inference contexts before their creation.
pub struct InferCtxtBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
defining_opaque_types: &'tcx ty::List<LocalDefId>,
opaque_type_mode: ty::OpaqueTypeMode<TyCtxt<'tcx>>,
considering_regions: bool,
skip_leak_check: bool,
/// Whether we are in coherence mode.
Expand All @@ -636,7 +638,7 @@ impl<'tcx> TyCtxt<'tcx> {
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
InferCtxtBuilder {
tcx: self,
defining_opaque_types: ty::List::empty(),
opaque_type_mode: Default::default(),
considering_regions: true,
skip_leak_check: false,
intercrate: false,
Expand All @@ -646,22 +648,23 @@ impl<'tcx> TyCtxt<'tcx> {
}

impl<'tcx> InferCtxtBuilder<'tcx> {
pub fn with_opaque_type_mode(
mut self,
opaque_type_mode: ty::OpaqueTypeMode<TyCtxt<'tcx>>,
) -> Self {
self.opaque_type_mode = opaque_type_mode;
self
}

/// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
/// you need to call this function. Otherwise the opaque type will be treated opaquely.
///
/// It is only meant to be called in two places, for typeck
/// (via `Inherited::build`) and for the inference context used
/// in mir borrowck.
pub fn with_opaque_type_inference(mut self, defining_anchor: LocalDefId) -> Self {
self.defining_opaque_types = self.tcx.opaque_types_defined_by(defining_anchor);
self
}

pub fn with_defining_opaque_types(
mut self,
defining_opaque_types: &'tcx ty::List<LocalDefId>,
) -> Self {
self.defining_opaque_types = defining_opaque_types;
let types = self.tcx.opaque_types_defined_by(defining_anchor);
self.opaque_type_mode = ty::OpaqueTypeMode::Define(types);
self
}

Expand Down Expand Up @@ -700,23 +703,23 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
let infcx = self.with_defining_opaque_types(canonical.defining_opaque_types).build();
let infcx = self.with_opaque_type_mode(canonical.opaque_type_mode).build();
let (value, args) = infcx.instantiate_canonical(span, canonical);
(infcx, value, args)
}

pub fn build(&mut self) -> InferCtxt<'tcx> {
let InferCtxtBuilder {
tcx,
defining_opaque_types,
opaque_type_mode: defining_opaque_types,
considering_regions,
skip_leak_check,
intercrate,
next_trait_solver,
} = *self;
InferCtxt {
tcx,
defining_opaque_types,
opaque_type_mode: defining_opaque_types,
considering_regions,
skip_leak_check,
inner: RefCell::new(InferCtxtInner::new()),
Expand Down Expand Up @@ -1240,10 +1243,30 @@ impl<'tcx> InferCtxt<'tcx> {
self.inner.borrow().opaque_type_storage.opaque_types.clone()
}

#[inline(always)]
pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
let Some(id) = id.into().as_local() else { return false };
self.defining_opaque_types.contains(&id)
pub fn treat_opaque_ty(&self, reveal: Reveal, def_id: DefId) -> TreatOpaque {
if self.intercrate {
return TreatOpaque::Ambiguous;
}

match reveal {
Reveal::All => return TreatOpaque::Reveal,
Reveal::UserFacing => {}
}

match self.opaque_type_mode {
ty::OpaqueTypeMode::Define(list) => {
if def_id.as_local().is_some_and(|def_id| list.contains(&def_id)) {
return TreatOpaque::Define;
}
}
ty::OpaqueTypeMode::Reveal(list) => {
if def_id.as_local().is_some_and(|def_id| list.contains(&def_id)) {
return TreatOpaque::Reveal;
}
}
}

TreatOpaque::Rigid
}

pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
Expand Down
Loading
Loading