Skip to content

Commit 462cc09

Browse files
committed
Auto merge of #141345 - matthiaskrgr:rollup-vux7gok, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #141267 (only resolve top-level guard patterns' guards once) - #141280 (Use Docker cache from the current repository) - #141296 (Async drop fix for 'broken mir, place has deref as later projection') - #141328 (When AsyncDrop impl is empty, sync drop generated in elaborator) - #141332 (Do not eagerly fold consts in `normalize_param_env_or_error` if new solver) - #141333 (Use `DeepRejectCtxt` in `assemble_inherent_candidates_from_param`) - #141334 (eagerly check nested obligations when coercing fndefs) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 356f2d0 + 9fd0ab6 commit 462cc09

25 files changed

+240
-36
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,9 +1190,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11901190
(ty::FnDef(..), ty::FnDef(..)) => {
11911191
// Don't reify if the function types have a LUB, i.e., they
11921192
// are the same function and their parameters have a LUB.
1193-
match self
1194-
.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
1195-
{
1193+
match self.commit_if_ok(|_| {
1194+
// We need to eagerly handle nested obligations due to lazy norm.
1195+
if self.next_trait_solver() {
1196+
let ocx = ObligationCtxt::new(self);
1197+
let value = ocx.lub(cause, self.param_env, prev_ty, new_ty)?;
1198+
if ocx.select_where_possible().is_empty() {
1199+
Ok(InferOk {
1200+
value,
1201+
obligations: ocx.into_pending_obligations(),
1202+
})
1203+
} else {
1204+
Err(TypeError::Mismatch)
1205+
}
1206+
} else {
1207+
self.at(cause, self.param_env).lub(prev_ty, new_ty)
1208+
}
1209+
}) {
11961210
// We have a LUB of prev_ty and new_ty, just return it.
11971211
Ok(ok) => return Ok(self.register_infer_ok_obligations(ok)),
11981212
Err(_) => {

compiler/rustc_hir_typeck/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![allow(rustc::diagnostic_outside_of_impl)]
33
#![allow(rustc::untranslatable_diagnostic)]
44
#![feature(array_windows)]
5+
#![feature(assert_matches)]
56
#![feature(box_patterns)]
67
#![feature(if_let_guard)]
78
#![feature(iter_intersperse)]

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::assert_matches::debug_assert_matches;
12
use std::cell::{Cell, RefCell};
23
use std::cmp::max;
34
use std::ops::Deref;
@@ -16,7 +17,7 @@ use rustc_infer::traits::ObligationCauseCode;
1617
use rustc_middle::middle::stability;
1718
use rustc_middle::query::Providers;
1819
use rustc_middle::ty::elaborate::supertrait_def_ids;
19-
use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
20+
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
2021
use rustc_middle::ty::{
2122
self, AssocItem, AssocItemContainer, GenericArgs, GenericArgsRef, GenericParamDefKind,
2223
ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt, Upcast,
@@ -807,8 +808,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
807808
);
808809
}
809810
}
810-
ty::Param(p) => {
811-
self.assemble_inherent_candidates_from_param(p);
811+
ty::Param(_) => {
812+
self.assemble_inherent_candidates_from_param(raw_self_ty);
812813
}
813814
ty::Bool
814815
| ty::Char
@@ -909,18 +910,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
909910
}
910911

911912
#[instrument(level = "debug", skip(self))]
912-
fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) {
913+
fn assemble_inherent_candidates_from_param(&mut self, param_ty: Ty<'tcx>) {
914+
debug_assert_matches!(param_ty.kind(), ty::Param(_));
915+
916+
let tcx = self.tcx;
913917
let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| {
914918
let bound_predicate = predicate.kind();
915919
match bound_predicate.skip_binder() {
916-
ty::ClauseKind::Trait(trait_predicate) => {
917-
match *trait_predicate.trait_ref.self_ty().kind() {
918-
ty::Param(p) if p == param_ty => {
919-
Some(bound_predicate.rebind(trait_predicate.trait_ref))
920-
}
921-
_ => None,
922-
}
923-
}
920+
ty::ClauseKind::Trait(trait_predicate) => DeepRejectCtxt::relate_rigid_rigid(tcx)
921+
.types_may_unify(param_ty, trait_predicate.trait_ref.self_ty())
922+
.then(|| bound_predicate.rebind(trait_predicate.trait_ref)),
924923
ty::ClauseKind::RegionOutlives(_)
925924
| ty::ClauseKind::TypeOutlives(_)
926925
| ty::ClauseKind::Projection(_)

compiler/rustc_mir_transform/src/elaborate_drop.rs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,29 @@ where
251251
span_bug!(span, "invalid `AsyncDrop` impl_source: {:?}", impl_source);
252252
}
253253
};
254-
let drop_fn_def_id = tcx.associated_item_def_ids(drop_trait)[0];
254+
// impl_item_refs may be empty if drop fn is not implemented in 'impl AsyncDrop for ...'
255+
// (#140974).
256+
// Such code will report error, so just generate sync drop here and return
257+
let Some(drop_fn_def_id) =
258+
tcx.associated_item_def_ids(drop_trait).into_iter().nth(0).copied()
259+
else {
260+
tcx.dcx().span_delayed_bug(
261+
self.elaborator.body().span,
262+
"AsyncDrop type without correct `async fn drop(...)`.",
263+
);
264+
self.elaborator.patch().patch_terminator(
265+
pin_obj_bb,
266+
TerminatorKind::Drop {
267+
place,
268+
target: succ,
269+
unwind: unwind.into_action(),
270+
replace: false,
271+
drop: None,
272+
async_fut: None,
273+
},
274+
);
275+
return pin_obj_bb;
276+
};
255277
let drop_fn = Ty::new_fn_def(tcx, drop_fn_def_id, trait_args);
256278
let sig = drop_fn.fn_sig(tcx);
257279
let sig = tcx.instantiate_bound_regions_with_erased(sig);
@@ -318,15 +340,20 @@ where
318340
bug!();
319341
};
320342
let obj_ptr_ty = Ty::new_mut_ptr(tcx, drop_ty);
321-
let obj_ptr_place = Place::from(self.new_temp(obj_ptr_ty));
322343
let unwrap_ty = adt_def.non_enum_variant().fields[FieldIdx::ZERO].ty(tcx, adt_args);
323-
let addr = Rvalue::RawPtr(
324-
RawPtrKind::Mut,
325-
pin_obj_place.project_deeper(
326-
&[ProjectionElem::Field(FieldIdx::ZERO, unwrap_ty), ProjectionElem::Deref],
327-
tcx,
328-
),
329-
);
344+
let obj_ref_place = Place::from(self.new_temp(unwrap_ty));
345+
call_statements.push(self.assign(
346+
obj_ref_place,
347+
Rvalue::Use(Operand::Copy(tcx.mk_place_field(
348+
pin_obj_place,
349+
FieldIdx::ZERO,
350+
unwrap_ty,
351+
))),
352+
));
353+
354+
let obj_ptr_place = Place::from(self.new_temp(obj_ptr_ty));
355+
356+
let addr = Rvalue::RawPtr(RawPtrKind::Mut, tcx.mk_place_deref(obj_ref_place));
330357
call_statements.push(self.assign(obj_ptr_place, addr));
331358
obj_ptr_place
332359
};

compiler/rustc_resolve/src/late.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3901,7 +3901,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
39013901
// We walk the pattern before declaring the pattern's inner bindings,
39023902
// so that we avoid resolving a literal expression to a binding defined
39033903
// by the pattern.
3904-
visit::walk_pat(self, pat);
3904+
// NB: `Self::visit_pat` must be used rather than `visit::walk_pat` to avoid resolving guard
3905+
// patterns' guard expressions multiple times (#141265).
3906+
self.visit_pat(pat);
39053907
self.resolve_pattern_inner(pat, pat_src, bindings);
39063908
// This has to happen *after* we determine which pat_idents are variants:
39073909
self.check_consistent_bindings(pat);

compiler/rustc_trait_selection/src/traits/engine.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,20 @@ where
188188
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
189189
}
190190

191+
/// Computes the least-upper-bound, or mutual supertype, of two values.
192+
pub fn lub<T: ToTrace<'tcx>>(
193+
&self,
194+
cause: &ObligationCause<'tcx>,
195+
param_env: ty::ParamEnv<'tcx>,
196+
expected: T,
197+
actual: T,
198+
) -> Result<T, TypeError<'tcx>> {
199+
self.infcx
200+
.at(cause, param_env)
201+
.lub(expected, actual)
202+
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
203+
}
204+
191205
#[must_use]
192206
pub fn select_where_possible(&self) -> Vec<E> {
193207
self.engine.borrow_mut().select_where_possible(self.infcx)

compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ pub fn normalize_param_env_or_error<'tcx>(
340340
let mut predicates: Vec<_> = util::elaborate(
341341
tcx,
342342
unnormalized_env.caller_bounds().into_iter().map(|predicate| {
343-
if tcx.features().generic_const_exprs() {
343+
if tcx.features().generic_const_exprs() || tcx.next_trait_solver_globally() {
344344
return predicate;
345345
}
346346

@@ -405,8 +405,6 @@ pub fn normalize_param_env_or_error<'tcx>(
405405
// compatibility. Eventually when lazy norm is implemented this can just be removed.
406406
// We do not normalize types here as there is no backwards compatibility requirement
407407
// for us to do so.
408-
//
409-
// FIXME(-Znext-solver): remove this hack since we have deferred projection equality
410408
predicate.fold_with(&mut ConstNormalizer(tcx))
411409
}),
412410
)

src/ci/docker/run.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,8 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
9797
docker --version
9898

9999
REGISTRY=ghcr.io
100-
# Hardcode username to reuse cache between auto and pr jobs
101-
# FIXME: should be changed after move from rust-lang-ci
102-
REGISTRY_USERNAME=rust-lang-ci
100+
# Default to `rust-lang` to allow reusing the cache for local builds
101+
REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER:-rust-lang}
103102
# Tag used to push the final Docker image, so that it can be pulled by e.g. rustup
104103
IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum}
105104
# Tag used to cache the Docker build

tests/crashes/140975.rs renamed to tests/ui/async-await/async-drop/deref-later-projection.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
//@ known-bug: #140975
2-
//@ compile-flags: --crate-type lib -Zvalidate-mir
3-
//@ edition: 2021
1+
// Ex-ICE: #140975
2+
//@ compile-flags: -Zvalidate-mir
3+
//@ build-pass
4+
//@ edition:2021
5+
#![crate_type = "lib"]
46
#![feature(async_drop)]
7+
#![allow(incomplete_features)]
8+
59
use std::{future::AsyncDrop, pin::Pin};
610

711
struct HasAsyncDrop ;

tests/crashes/140974.rs renamed to tests/ui/async-await/async-drop/elaborate-index-out-of-bounds.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
//@ known-bug: #140974
2-
//@edition:2021
1+
//@ edition: 2024
2+
// Ex-ICE: #140974
3+
#![crate_type = "lib"]
4+
#![allow(incomplete_features)]
35
#![feature(async_drop)]
46
use core::future::AsyncDrop;
57

@@ -10,5 +12,6 @@ impl Drop for HasIncompleteAsyncDrop {
1012
fn drop(&mut self) {}
1113
}
1214
impl AsyncDrop for HasIncompleteAsyncDrop {
15+
//~^ ERROR: not all trait items implemented, missing: `drop` [E0046]
1316
// not implemented yet..
1417
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0046]: not all trait items implemented, missing: `drop`
2+
--> $DIR/elaborate-index-out-of-bounds.rs:14:1
3+
|
4+
LL | impl AsyncDrop for HasIncompleteAsyncDrop {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `drop` in implementation
6+
|
7+
= help: implement the missing item: `async fn drop(self: Pin<&mut Self>) { todo!() }`
8+
9+
error: aborting due to 1 previous error
10+
11+
For more information about this error, try `rustc --explain E0046`.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/141265>.
2+
//! Make sure expressions in top-level guard patterns are only resolved once.
3+
4+
fn main() {
5+
for
6+
else if b 0 {}
7+
//~^ ERROR expected identifier, found keyword `else`
8+
//~| ERROR missing `in` in `for` loop
9+
//~| ERROR cannot find value `b` in this scope
10+
//~| ERROR guard patterns are experimental
11+
//~| ERROR `{integer}` is not an iterator
12+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
error: expected identifier, found keyword `else`
2+
--> $DIR/only-resolve-top-level-guard-expr-once-ice-141265.rs:6:5
3+
|
4+
LL | else if b 0 {}
5+
| ^^^^ expected identifier, found keyword
6+
7+
error: missing `in` in `for` loop
8+
--> $DIR/only-resolve-top-level-guard-expr-once-ice-141265.rs:6:14
9+
|
10+
LL | else if b 0 {}
11+
| ^
12+
|
13+
help: try adding `in` here
14+
|
15+
LL | else if b in 0 {}
16+
| ++
17+
18+
error[E0425]: cannot find value `b` in this scope
19+
--> $DIR/only-resolve-top-level-guard-expr-once-ice-141265.rs:6:13
20+
|
21+
LL | else if b 0 {}
22+
| ^ not found in this scope
23+
24+
error[E0658]: guard patterns are experimental
25+
--> $DIR/only-resolve-top-level-guard-expr-once-ice-141265.rs:6:13
26+
|
27+
LL | else if b 0 {}
28+
| ^
29+
|
30+
= note: see issue #129967 <https://github.com/rust-lang/rust/issues/129967> for more information
31+
= help: add `#![feature(guard_patterns)]` to the crate attributes to enable
32+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
33+
= help: consider using match arm guards
34+
35+
error[E0277]: `{integer}` is not an iterator
36+
--> $DIR/only-resolve-top-level-guard-expr-once-ice-141265.rs:6:15
37+
|
38+
LL | else if b 0 {}
39+
| ^ `{integer}` is not an iterator
40+
|
41+
= help: the trait `Iterator` is not implemented for `{integer}`
42+
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
43+
= note: required for `{integer}` to implement `IntoIterator`
44+
45+
error: aborting due to 5 previous errors
46+
47+
Some errors have detailed explanations: E0277, E0425, E0658.
48+
For more information about an error, try `rustc --explain E0277`.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//@ compile-flags: -Znext-solver
2+
//@ check-pass
3+
4+
// Make sure that we consider nested obligations when checking whether
5+
// we should coerce fn definitions to function pointers.
6+
7+
fn foo<const N: usize>() {}
8+
fn bar<T>() {}
9+
fn main() {
10+
let _ = if true { foo::<{ 0 + 0 }> } else { foo::<1> };
11+
let _ = if true {
12+
bar::<for<'a> fn(<Vec<&'a ()> as IntoIterator>::Item)>
13+
} else {
14+
bar::<fn(i32)>
15+
};
16+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//@ check-pass
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
5+
6+
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/214>.
7+
// See comment below.
8+
9+
trait A {
10+
fn hello(&self) {}
11+
}
12+
13+
trait B {
14+
fn hello(&self) {}
15+
}
16+
17+
impl<T> A for T {}
18+
impl<T> B for T {}
19+
20+
fn test<F, R>(q: F::Item)
21+
where
22+
F: Iterator<Item = R>,
23+
// We want to prefer `A` for `R.hello()`
24+
F::Item: A,
25+
{
26+
q.hello();
27+
}
28+
29+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ check-pass
2+
//@ compile-flags: -Znext-solver
3+
4+
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/214>.
5+
6+
fn execute<K, F, R>(q: F::Item) -> R
7+
where
8+
F: Iterator<Item = R>,
9+
// Both of the below bounds should be considered for `.into()`, and then be combined
10+
// into a single `R: Into<?0>` bound which can be inferred to `?0 = R`.
11+
F::Item: Into<K>,
12+
R: Into<String>,
13+
{
14+
q.into()
15+
}
16+
17+
fn main() {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ check-pass
2+
//@ compile-flags: -Znext-solver
3+
4+
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/213>.
5+
6+
use std::ops::Deref;
7+
8+
trait Trait: Deref<Target = [u8; { 1 + 1 }]> {}
9+
10+
fn main() {}

0 commit comments

Comments
 (0)