Skip to content

Commit 3111015

Browse files
committed
Auto merge of rust-lang#124811 - matthiaskrgr:rollup-4zpov13, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - rust-lang#124520 (Document that `create_dir_all` calls `mkdir`/`CreateDirW` multiple times) - rust-lang#124724 (Prefer lower vtable candidates in select in new solver) - rust-lang#124771 (Don't consider candidates with no failing where clauses when refining obligation causes in new solver) - rust-lang#124808 (Use `super_fold` in `RegionsToStatic` visitor) r? `@ghost` `@rustbot` modify labels: rollup
2 parents fc47cf3 + ad73b16 commit 3111015

File tree

12 files changed

+137
-15
lines changed

12 files changed

+137
-15
lines changed

compiler/rustc_next_trait_solver/src/canonicalizer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ impl<I: Interner> TypeFolder<I> for RegionsToStatic<I> {
455455
I::Binder<T>: TypeSuperFoldable<I>,
456456
{
457457
self.binder.shift_in(1);
458-
let t = t.fold_with(self);
458+
let t = t.super_fold_with(self);
459459
self.binder.shift_out(1);
460460
t
461461
}

compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ impl<'tcx> inspect::ProofTreeVisitor<'tcx> for Select {
5858
)));
5959
}
6060

61+
// Don't winnow until `Certainty::Yes` -- we don't need to winnow until
62+
// codegen, and only on the good path.
63+
if matches!(goal.result().unwrap(), Certainty::Maybe(..)) {
64+
return ControlFlow::Break(Ok(None));
65+
}
66+
6167
// We need to winnow. See comments on `candidate_should_be_dropped_in_favor_of`.
6268
let mut i = 0;
6369
while i < candidates.len() {
@@ -86,7 +92,7 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
8692
other: &inspect::InspectCandidate<'_, 'tcx>,
8793
) -> bool {
8894
// Don't winnow until `Certainty::Yes` -- we don't need to winnow until
89-
// codegen, technically.
95+
// codegen, and only on the good path.
9096
if matches!(other.result().unwrap(), Certainty::Maybe(..)) {
9197
return false;
9298
}
@@ -105,12 +111,14 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
105111
bug!("should not have assembled a CoherenceUnknowable candidate")
106112
}
107113

114+
// In the old trait solver, we arbitrarily choose lower vtable candidates
115+
// over higher ones.
116+
(
117+
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { vtable_base: a }),
118+
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { vtable_base: b }),
119+
) => a >= b,
108120
// Prefer dyn candidates over non-dyn candidates. This is necessary to
109121
// handle the unsoundness between `impl<T: ?Sized> Any for T` and `dyn Any: Any`.
110-
(
111-
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }),
112-
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }),
113-
) => false,
114122
(
115123
CandidateSource::Impl(_) | CandidateSource::ParamEnv(_) | CandidateSource::AliasBound,
116124
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }),

compiler/rustc_trait_selection/src/solve/fulfill.rs

+42-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::ty::{self, TyCtxt};
1414
use rustc_span::symbol::sym;
1515

1616
use super::eval_ctxt::GenerateProofTree;
17-
use super::inspect::{ProofTreeInferCtxtExt, ProofTreeVisitor};
17+
use super::inspect::{InspectCandidate, InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor};
1818
use super::{Certainty, InferCtxtEvalExt};
1919

2020
/// A trait engine using the new trait solver.
@@ -304,6 +304,46 @@ impl<'tcx> BestObligation<'tcx> {
304304
self.obligation = old_obligation;
305305
res
306306
}
307+
308+
/// Filter out the candidates that aren't either error or ambiguous (depending
309+
/// on what we are looking for), and also throw out candidates that have no
310+
/// failing WC (or higher-ranked obligations, for which there should only be
311+
/// one candidate anyways -- but I digress). This most likely means that the
312+
/// goal just didn't unify at all, e.g. a param candidate with an alias in it.
313+
fn non_trivial_candidates<'a>(
314+
&self,
315+
goal: &'a InspectGoal<'a, 'tcx>,
316+
) -> Vec<InspectCandidate<'a, 'tcx>> {
317+
let mut candidates = goal
318+
.candidates()
319+
.into_iter()
320+
.filter(|candidate| match self.consider_ambiguities {
321+
true => matches!(candidate.result(), Ok(Certainty::Maybe(_))),
322+
false => matches!(candidate.result(), Err(_)),
323+
})
324+
.collect::<Vec<_>>();
325+
326+
// If we have >1 candidate, one may still be due to "boring" reasons, like
327+
// an alias-relate that failed to hold when deeply evaluated. We really
328+
// don't care about reasons like this.
329+
if candidates.len() > 1 {
330+
candidates.retain(|candidate| {
331+
goal.infcx().probe(|_| {
332+
candidate.instantiate_nested_goals(self.span()).iter().any(|nested_goal| {
333+
matches!(
334+
nested_goal.source(),
335+
GoalSource::ImplWhereBound | GoalSource::InstantiateHigherRanked
336+
) && match self.consider_ambiguities {
337+
true => matches!(nested_goal.result(), Ok(Certainty::Maybe(_))),
338+
false => matches!(nested_goal.result(), Err(_)),
339+
}
340+
})
341+
})
342+
});
343+
}
344+
345+
candidates
346+
}
307347
}
308348

309349
impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
@@ -314,11 +354,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
314354
}
315355

316356
fn visit_goal(&mut self, goal: &super::inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
317-
// FIXME: Throw out candidates that have no failing WC and >0 failing misc goal.
318-
// This most likely means that the goal just didn't unify at all, e.g. a param
319-
// candidate with an alias in it.
320-
let candidates = goal.candidates();
321-
357+
let candidates = self.non_trivial_candidates(goal);
322358
let [candidate] = candidates.as_slice() else {
323359
return ControlFlow::Break(self.obligation.clone());
324360
};

library/std/src/fs.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -2258,7 +2258,7 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
22582258
/// # Platform-specific behavior
22592259
///
22602260
/// This function currently corresponds to the `mkdir` function on Unix
2261-
/// and the `CreateDirectory` function on Windows.
2261+
/// and the `CreateDirectoryW` function on Windows.
22622262
/// Note that, this [may change in the future][changes].
22632263
///
22642264
/// [changes]: io#platform-specific-behavior
@@ -2298,10 +2298,14 @@ pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
22982298
/// Recursively create a directory and all of its parent components if they
22992299
/// are missing.
23002300
///
2301+
/// If this function returns an error, some of the parent components might have
2302+
/// been created already.
2303+
///
23012304
/// # Platform-specific behavior
23022305
///
2303-
/// This function currently corresponds to the `mkdir` function on Unix
2304-
/// and the `CreateDirectory` function on Windows.
2306+
/// This function currently corresponds to multiple calls to the `mkdir`
2307+
/// function on Unix and the `CreateDirectoryW` function on Windows.
2308+
///
23052309
/// Note that, this [may change in the future][changes].
23062310
///
23072311
/// [changes]: io#platform-specific-behavior
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ compile-flags: -Znext-solver=coherence
2+
3+
#[derive(Debug)]
4+
struct X<const FN: fn() = { || {} }>;
5+
//~^ ERROR using function pointers as const generic parameters is forbidden
6+
//~| ERROR using function pointers as const generic parameters is forbidden
7+
8+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error: using function pointers as const generic parameters is forbidden
2+
--> $DIR/const-region-infer-to-static-in-binder.rs:4:20
3+
|
4+
LL | struct X<const FN: fn() = { || {} }>;
5+
| ^^^^
6+
|
7+
= note: the only supported types are integers, `bool` and `char`
8+
9+
error: using function pointers as const generic parameters is forbidden
10+
--> $DIR/const-region-infer-to-static-in-binder.rs:4:20
11+
|
12+
LL | struct X<const FN: fn() = { || {} }>;
13+
| ^^^^
14+
|
15+
= note: the only supported types are integers, `bool` and `char`
16+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
17+
18+
error: aborting due to 2 previous errors
19+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
trait Foo {}
2+
trait Bar {}
3+
4+
impl<T> Foo for T where T: Bar {}
5+
fn needs_foo(_: impl Foo) {}
6+
7+
trait Mirror {
8+
type Mirror;
9+
}
10+
impl<T> Mirror for T {
11+
type Mirror = T;
12+
}
13+
14+
// Make sure the `Alias: Foo` bound doesn't "shadow" the impl, since the
15+
// impl is really the only candidate we care about here for the purpose
16+
// of error reporting.
17+
fn hello<T>() where <T as Mirror>::Mirror: Foo {
18+
needs_foo(());
19+
//~^ ERROR the trait bound `(): Foo` is not satisfied
20+
}
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0277]: the trait bound `(): Foo` is not satisfied
2+
--> $DIR/where-clause-doesnt-apply.rs:18:15
3+
|
4+
LL | needs_foo(());
5+
| --------- ^^ the trait `Bar` is not implemented for `()`, which is required by `(): Foo`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
note: required for `()` to implement `Foo`
10+
--> $DIR/where-clause-doesnt-apply.rs:4:9
11+
|
12+
LL | impl<T> Foo for T where T: Bar {}
13+
| ^^^ ^ --- unsatisfied trait bound introduced here
14+
note: required by a bound in `needs_foo`
15+
--> $DIR/where-clause-doesnt-apply.rs:5:22
16+
|
17+
LL | fn needs_foo(_: impl Foo) {}
18+
| ^^^ required by this bound in `needs_foo`
19+
20+
error: aborting due to 1 previous error
21+
22+
For more information about this error, try `rustc --explain E0277`.

tests/ui/traits/normalize-supertrait.rs

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
// comparing the supertrait `Derived<()>` to the expected trait.
55

66
//@ build-pass
7+
//@ revisions: current next
8+
//@ ignore-compare-mode-next-solver (explicit revisions)
9+
//@[next] compile-flags: -Znext-solver
710

811
trait Proj {
912
type S;

0 commit comments

Comments
 (0)