Skip to content

Commit bccf3b7

Browse files
committed
Auto merge of rust-lang#133502 - lcnr:rust4, r=<try>
[DO NOT MERGE] bootstrap with `-Znext-solver=globally` A revival of rust-lang#124812. Current status: `./x.py b --stage 2` passes 🎉 ### commits - rust-lang#133501 - rust-lang#133493 - 9456bfe and b21b116 reimplement candidate preference based on rust-lang#132325, not yet a separate PR - c3ef9cd is a rebased version of rust-lang#125334, unsure whether I actually want to land this PR for now - rust-lang#133517 * rust-lang#133518 * rust-lang#133519 * rust-lang#133520 * rust-lang#133521 * rust-lang#133524 r? `@ghost`
2 parents 66adeaf + 000f7bd commit bccf3b7

File tree

58 files changed

+912
-238
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+912
-238
lines changed

compiler/rustc_borrowck/src/type_check/canonical.rs

+36
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_middle::mir::ConstraintCategory;
77
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast};
88
use rustc_span::Span;
99
use rustc_span::def_id::DefId;
10+
use rustc_trait_selection::solve::NoSolution;
1011
use rustc_trait_selection::traits::ObligationCause;
1112
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
1213
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
@@ -177,6 +178,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
177178
if self.infcx.next_trait_solver() {
178179
let body = self.body;
179180
let param_env = self.infcx.param_env;
181+
// FIXME: Make this into a real type op?
180182
self.fully_perform_op(
181183
location.to_locations(),
182184
ConstraintCategory::Boring,
@@ -213,6 +215,40 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
213215
}
214216
}
215217

218+
#[instrument(skip(self), level = "debug")]
219+
pub(super) fn structurally_resolve(
220+
&mut self,
221+
ty: Ty<'tcx>,
222+
location: impl NormalizeLocation,
223+
) -> Ty<'tcx> {
224+
if self.infcx.next_trait_solver() {
225+
let body = self.body;
226+
let param_env = self.infcx.param_env;
227+
// FIXME: Make this into a real type op?
228+
self.fully_perform_op(
229+
location.to_locations(),
230+
ConstraintCategory::Boring,
231+
CustomTypeOp::new(
232+
|ocx| {
233+
ocx.structurally_normalize(
234+
&ObligationCause::misc(
235+
location.to_locations().span(body),
236+
body.source.def_id().expect_local(),
237+
),
238+
param_env,
239+
ty,
240+
)
241+
.map_err(|_| NoSolution)
242+
},
243+
"normalizing struct tail",
244+
),
245+
)
246+
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar))
247+
} else {
248+
self.normalize(ty, location)
249+
}
250+
}
251+
216252
#[instrument(skip(self), level = "debug")]
217253
pub(super) fn ascribe_user_type(
218254
&mut self,

compiler/rustc_borrowck/src/type_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10751075
proj,
10761076
|this, field, ()| {
10771077
let ty = this.field_ty(tcx, field);
1078-
self.normalize(ty, locations)
1078+
self.structurally_resolve(ty, locations)
10791079
},
10801080
|_, _| unreachable!(),
10811081
);

compiler/rustc_hir_analysis/src/check/check.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,12 @@ fn check_opaque_meets_bounds<'tcx>(
322322
};
323323
let param_env = tcx.param_env(defining_use_anchor);
324324

325-
// FIXME(#132279): This should eventually use the already defined hidden types.
326-
let infcx = tcx.infer_ctxt().build(TypingMode::analysis_in_body(tcx, defining_use_anchor));
325+
// FIXME(#132279): Once `PostBorrowckAnalysis` is supported in the old solver, this branch should be removed.
326+
let infcx = tcx.infer_ctxt().build(if tcx.next_trait_solver_globally() {
327+
TypingMode::post_borrowck_analysis(tcx, defining_use_anchor)
328+
} else {
329+
TypingMode::analysis_in_body(tcx, defining_use_anchor)
330+
});
327331
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
328332

329333
let args = match origin {
@@ -417,7 +421,11 @@ fn check_opaque_meets_bounds<'tcx>(
417421
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
418422
ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
419423

420-
if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } = origin {
424+
if infcx.next_trait_solver() {
425+
Ok(())
426+
} else if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } =
427+
origin
428+
{
421429
// HACK: this should also fall through to the hidden type check below, but the original
422430
// implementation had a bug where equivalent lifetimes are not identical. This caused us
423431
// to reject existing stable code that is otherwise completely fine. The real fix is to

compiler/rustc_hir_typeck/src/_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5757
// type in that case)
5858
let mut all_arms_diverge = Diverges::WarnedAlways;
5959

60-
let expected = orig_expected.adjust_for_branches(self);
60+
let expected = orig_expected.adjust_for_branches(self, expr.span);
6161
debug!(?expected);
6262

6363
let mut coercion = {

compiler/rustc_hir_typeck/src/expectation.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,14 @@ impl<'a, 'tcx> Expectation<'tcx> {
3939
// an expected type. Otherwise, we might write parts of the type
4040
// when checking the 'then' block which are incompatible with the
4141
// 'else' branch.
42-
pub(super) fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
42+
pub(super) fn adjust_for_branches(
43+
&self,
44+
fcx: &FnCtxt<'a, 'tcx>,
45+
span: Span,
46+
) -> Expectation<'tcx> {
4347
match *self {
4448
ExpectHasType(ety) => {
45-
let ety = fcx.shallow_resolve(ety);
49+
let ety = fcx.try_structurally_resolve_type(span, ety);
4650
if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
4751
}
4852
ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),

compiler/rustc_hir_typeck/src/expr.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6868

6969
// While we don't allow *arbitrary* coercions here, we *do* allow
7070
// coercions from ! to `expected`.
71-
if ty.is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) {
71+
if self.try_structurally_resolve_type(expr.span, ty).is_never()
72+
&& self.expr_guaranteed_to_constitute_read_for_never(expr)
73+
{
7274
if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
7375
let reported = self.dcx().span_delayed_bug(
7476
expr.span,
@@ -274,7 +276,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
274276
// unless it's a place expression that isn't being read from, in which case
275277
// diverging would be unsound since we may never actually read the `!`.
276278
// e.g. `let _ = *never_ptr;` with `never_ptr: *const !`.
277-
if ty.is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) {
279+
if self.try_structurally_resolve_type(expr.span, ty).is_never()
280+
&& self.expr_guaranteed_to_constitute_read_for_never(expr)
281+
{
278282
self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
279283
}
280284

@@ -1290,7 +1294,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12901294
let cond_diverges = self.diverges.get();
12911295
self.diverges.set(Diverges::Maybe);
12921296

1293-
let expected = orig_expected.adjust_for_branches(self);
1297+
let expected = orig_expected.adjust_for_branches(self, sp);
12941298
let then_ty = self.check_expr_with_expectation(then_expr, expected);
12951299
let then_diverges = self.diverges.get();
12961300
self.diverges.set(Diverges::Maybe);

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
307307
ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _)
308308
if !ty.has_escaping_bound_vars() =>
309309
{
310-
self.normalize(span, ty).ty_adt_def()
310+
self.structurally_resolve_type(span, ty).ty_adt_def()
311311
}
312312
_ => None,
313313
}

compiler/rustc_hir_typeck/src/method/probe.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15741574
// Thus we need to prevent them from trying to match the `&_` autoref
15751575
// candidates that get created for `&self` trait methods.
15761576
ty::Alias(ty::Opaque, alias_ty)
1577-
if self.infcx.can_define_opaque_ty(alias_ty.def_id)
1577+
if !self.next_trait_solver()
1578+
&& self.infcx.can_define_opaque_ty(alias_ty.def_id)
15781579
&& !xform_self_ty.is_ty_var() =>
15791580
{
15801581
return ProbeResult::NoMatch;
@@ -1642,6 +1643,25 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16421643
}
16431644
}
16441645

1646+
// In the new solver, check the well-formedness of the return type.
1647+
// This emulates, in a way, the predicates that fall out of
1648+
// normalizing the return type in the old solver.
1649+
//
1650+
// We alternatively could check the predicates of the method itself hold,
1651+
// but we intentionally do not do this in the old solver b/c of cycles,
1652+
// and doing it in the new solver would be stronger. This should be fixed
1653+
// in the future, since it likely leads to much better method winnowing.
1654+
if let Some(xform_ret_ty) = xform_ret_ty
1655+
&& self.infcx.next_trait_solver()
1656+
{
1657+
ocx.register_obligation(traits::Obligation::new(
1658+
self.tcx,
1659+
cause.clone(),
1660+
self.param_env,
1661+
ty::ClauseKind::WellFormed(xform_ret_ty.into()),
1662+
));
1663+
}
1664+
16451665
// Evaluate those obligations to see if they might possibly hold.
16461666
for error in ocx.select_where_possible() {
16471667
result = ProbeResult::NoMatch;

compiler/rustc_hir_typeck/src/upvar.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1802,7 +1802,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18021802
let mut is_mutbl = bm.1;
18031803

18041804
for pointer_ty in place.deref_tys() {
1805-
match pointer_ty.kind() {
1805+
match self.structurally_resolve_type(self.tcx.hir().span(var_hir_id), pointer_ty).kind()
1806+
{
18061807
// We don't capture derefs of raw ptrs
18071808
ty::RawPtr(_, _) => unreachable!(),
18081809

@@ -1816,7 +1817,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18161817
// Dereferencing a box doesn't change mutability
18171818
ty::Adt(def, ..) if def.is_box() => {}
18181819

1819-
unexpected_ty => bug!("deref of unexpected pointer type {:?}", unexpected_ty),
1820+
unexpected_ty => span_bug!(
1821+
self.tcx.hir().span(var_hir_id),
1822+
"deref of unexpected pointer type {:?}",
1823+
unexpected_ty
1824+
),
18201825
}
18211826
}
18221827

compiler/rustc_infer/src/infer/context.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
77
use rustc_middle::ty::{self, Ty, TyCtxt};
88
use rustc_span::{DUMMY_SP, ErrorGuaranteed};
99

10-
use super::{BoundRegionConversionTime, InferCtxt, SubregionOrigin};
10+
use super::{BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin};
1111

1212
impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
1313
type Interner = TyCtxt<'tcx>;
@@ -87,6 +87,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
8787
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
8888
}
8989

90+
fn next_region_infer(&self) -> ty::Region<'tcx> {
91+
self.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP))
92+
}
93+
9094
fn next_ty_infer(&self) -> Ty<'tcx> {
9195
self.next_ty_var(DUMMY_SP)
9296
}

compiler/rustc_infer/src/infer/mod.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -990,11 +990,17 @@ impl<'tcx> InferCtxt<'tcx> {
990990

991991
#[inline(always)]
992992
pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
993+
debug_assert!(!self.next_trait_solver());
993994
match self.typing_mode() {
994995
TypingMode::Analysis { defining_opaque_types } => {
995996
id.into().as_local().is_some_and(|def_id| defining_opaque_types.contains(&def_id))
996997
}
997-
TypingMode::Coherence | TypingMode::PostAnalysis => false,
998+
// FIXME(#132279): This function is quite weird in post-analysis
999+
// and post-borrowck analysis mode. We may need to modify its uses
1000+
// to support PostBorrowckAnalysis in the old solver as well.
1001+
TypingMode::Coherence
1002+
| TypingMode::PostBorrowckAnalysis { .. }
1003+
| TypingMode::PostAnalysis => false,
9981004
}
9991005
}
10001006

@@ -1276,15 +1282,16 @@ impl<'tcx> InferCtxt<'tcx> {
12761282
/// using canonicalization or carrying this inference context around.
12771283
pub fn typing_env(&self, param_env: ty::ParamEnv<'tcx>) -> ty::TypingEnv<'tcx> {
12781284
let typing_mode = match self.typing_mode() {
1279-
ty::TypingMode::Coherence => ty::TypingMode::Coherence,
12801285
// FIXME(#132279): This erases the `defining_opaque_types` as it isn't possible
12811286
// to handle them without proper canonicalization. This means we may cause cycle
12821287
// errors and fail to reveal opaques while inside of bodies. We should rename this
12831288
// function and require explicit comments on all use-sites in the future.
12841289
ty::TypingMode::Analysis { defining_opaque_types: _ } => {
12851290
TypingMode::non_body_analysis()
12861291
}
1287-
ty::TypingMode::PostAnalysis => ty::TypingMode::PostAnalysis,
1292+
mode @ (ty::TypingMode::Coherence
1293+
| ty::TypingMode::PostBorrowckAnalysis { .. }
1294+
| ty::TypingMode::PostAnalysis) => mode,
12881295
};
12891296
ty::TypingEnv { typing_mode, param_env }
12901297
}

compiler/rustc_infer/src/infer/opaque_types/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ impl<'tcx> InferCtxt<'tcx> {
9898
span: Span,
9999
param_env: ty::ParamEnv<'tcx>,
100100
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, TypeError<'tcx>> {
101+
debug_assert!(!self.next_trait_solver());
101102
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
102103
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
103104
let def_id = def_id.expect_local();
@@ -546,7 +547,9 @@ impl<'tcx> InferCtxt<'tcx> {
546547
);
547548
}
548549
}
549-
ty::TypingMode::PostAnalysis => bug!("insert hidden type post-analysis"),
550+
mode @ (ty::TypingMode::PostBorrowckAnalysis { .. } | ty::TypingMode::PostAnalysis) => {
551+
bug!("insert hidden type in {mode:?}")
552+
}
550553
}
551554

552555
Ok(())

compiler/rustc_middle/src/ty/context.rs

+8
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,14 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
632632
fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::DefiningOpaqueTypes {
633633
self.opaque_types_defined_by(defining_anchor)
634634
}
635+
636+
fn fold_regions<T: TypeFoldable<TyCtxt<'tcx>>>(
637+
self,
638+
value: T,
639+
f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
640+
) -> T {
641+
self.fold_regions(value, f)
642+
}
635643
}
636644

637645
macro_rules! bidirectional_lang_item_map {

compiler/rustc_middle/src/ty/fold.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,11 @@ where
5555

5656
impl<'tcx> TyCtxt<'tcx> {
5757
/// Folds the escaping and free regions in `value` using `f`.
58-
pub fn fold_regions<T>(
58+
pub fn fold_regions<T: TypeFoldable<TyCtxt<'tcx>>>(
5959
self,
6060
value: T,
6161
mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
62-
) -> T
63-
where
64-
T: TypeFoldable<TyCtxt<'tcx>>,
65-
{
62+
) -> T {
6663
value.fold_with(&mut RegionFolder::new(self, &mut f))
6764
}
6865
}

compiler/rustc_middle/src/ty/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ pub use adt::*;
2323
pub use assoc::*;
2424
pub use generic_args::{GenericArgKind, TermKind, *};
2525
pub use generics::*;
26+
// Can't use a glob import here as it would cause
27+
// ambiguity when importing the actual types implementing
28+
// the inherent traits from this module.
29+
#[allow(rustc::non_glob_import_of_type_ir_inherent)]
30+
use inherent::SliceLike;
2631
pub use intrinsic::IntrinsicDef;
2732
use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx};
2833
use rustc_ast::expand::StrippedCfgItem;
@@ -970,7 +975,7 @@ pub struct ParamEnv<'tcx> {
970975
}
971976

972977
impl<'tcx> rustc_type_ir::inherent::ParamEnv<TyCtxt<'tcx>> for ParamEnv<'tcx> {
973-
fn caller_bounds(self) -> impl IntoIterator<Item = ty::Clause<'tcx>> {
978+
fn caller_bounds(self) -> impl SliceLike<Item = ty::Clause<'tcx>> {
974979
self.caller_bounds()
975980
}
976981
}

0 commit comments

Comments
 (0)