Skip to content

Commit c092b28

Browse files
committed
Auto merge of rust-lang#127580 - matthiaskrgr:rollup-pjw1xmj, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#126476 (Fix running bootstrap tests with a local Rust toolchain as the stage0) - rust-lang#127094 (E0191 suggestion correction, inserts turbofish) - rust-lang#127554 ( do not run test where it cannot run) - rust-lang#127564 (Temporarily remove me from review rotation.) - rust-lang#127568 (instantiate higher ranked goals in candidate selection again) - rust-lang#127569 (Fix local download of Docker caches from CI) - rust-lang#127570 ( small normalization improvement) r? `@ghost` `@rustbot` modify labels: rollup
2 parents b215beb + 22df186 commit c092b28

35 files changed

+224
-320
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use rustc_errors::MultiSpan;
1111
use rustc_errors::{
1212
codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed,
1313
};
14-
use rustc_hir as hir;
1514
use rustc_hir::def::{DefKind, Res};
1615
use rustc_hir::def_id::{DefId, LocalDefId};
16+
use rustc_hir::{self as hir, Node};
1717
use rustc_middle::bug;
1818
use rustc_middle::query::Key;
1919
use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
@@ -740,7 +740,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
740740
if object_safety_violations {
741741
return;
742742
}
743+
744+
// related to issue #91997, turbofishes added only when in an expr or pat
745+
let mut in_expr_or_pat = false;
743746
if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
747+
let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id));
748+
in_expr_or_pat = match grandparent {
749+
Node::Expr(_) | Node::Pat(_) => true,
750+
_ => false,
751+
};
744752
match bound.trait_ref.path.segments {
745753
// FIXME: `trait_ref.path.span` can point to a full path with multiple
746754
// segments, even though `trait_ref.path.segments` is of length `1`. Work
@@ -896,6 +904,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
896904
// `Trait<'a, Item = Type>` while accounting for the `<'a>` in the
897905
// suggestion.
898906
format!("{}, {}>", &snippet[..snippet.len() - 1], types.join(", "))
907+
} else if in_expr_or_pat {
908+
// The user wrote `Iterator`, so we don't have a type we can suggest, but at
909+
// least we can clue them to the correct syntax `Iterator::<Item = Type>`.
910+
format!("{}::<{}>", snippet, types.join(", "))
899911
} else {
900912
// The user wrote `Iterator`, so we don't have a type we can suggest, but at
901913
// least we can clue them to the correct syntax `Iterator<Item = Type>`.

compiler/rustc_trait_selection/src/traits/normalize.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,13 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
109109
value: &T,
110110
reveal: Reveal,
111111
) -> bool {
112-
// This mirrors `ty::TypeFlags::HAS_ALIASES` except that we take `Reveal` into account.
113-
114-
let mut flags = ty::TypeFlags::HAS_TY_PROJECTION
115-
| ty::TypeFlags::HAS_TY_WEAK
116-
| ty::TypeFlags::HAS_TY_INHERENT
117-
| ty::TypeFlags::HAS_CT_PROJECTION;
112+
let mut flags = ty::TypeFlags::HAS_ALIAS;
118113

114+
// Opaques are treated as rigid with `Reveal::UserFacing`,
115+
// so we can ignore those.
119116
match reveal {
120-
Reveal::UserFacing => {}
121-
Reveal::All => flags |= ty::TypeFlags::HAS_TY_OPAQUE,
117+
Reveal::UserFacing => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE),
118+
Reveal::All => {}
122119
}
123120

124121
value.has_type_flags(flags)

compiler/rustc_trait_selection/src/traits/select/mod.rs

+12-54
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,6 @@ mod _match;
6464
mod candidate_assembly;
6565
mod confirmation;
6666

67-
/// Whether to consider the binder of higher ranked goals for the `leak_check` when
68-
/// evaluating higher-ranked goals. See #119820 for more info.
69-
///
70-
/// While this is a bit hacky, it is necessary to match the behavior of the new solver:
71-
/// We eagerly instantiate binders in the new solver, outside of candidate selection, so
72-
/// the leak check inside of candidates does not consider any bound vars from the higher
73-
/// ranked goal. However, we do exit the binder once we're completely finished with a goal,
74-
/// so the leak-check can be used in evaluate by causing nested higher-ranked goals to fail.
75-
#[derive(Debug, Copy, Clone)]
76-
enum LeakCheckHigherRankedGoal {
77-
No,
78-
Yes,
79-
}
80-
8167
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
8268
pub enum IntercrateAmbiguityCause<'tcx> {
8369
DownstreamCrate { trait_ref: ty::TraitRef<'tcx>, self_ty: Option<Ty<'tcx>> },
@@ -402,10 +388,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
402388
let mut no_candidates_apply = true;
403389

404390
for c in candidate_set.vec.iter() {
405-
if self
406-
.evaluate_candidate(stack, c, LeakCheckHigherRankedGoal::No)?
407-
.may_apply()
408-
{
391+
if self.evaluate_candidate(stack, c)?.may_apply() {
409392
no_candidates_apply = false;
410393
break;
411394
}
@@ -476,7 +459,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
476459
// is needed for specialization. Propagate overflow if it occurs.
477460
let mut candidates = candidates
478461
.into_iter()
479-
.map(|c| match self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::No) {
462+
.map(|c| match self.evaluate_candidate(stack, &c) {
480463
Ok(eval) if eval.may_apply() => {
481464
Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
482465
}
@@ -566,7 +549,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
566549
obligation: &PredicateObligation<'tcx>,
567550
) -> Result<EvaluationResult, OverflowError> {
568551
debug_assert!(!self.infcx.next_trait_solver());
569-
self.evaluation_probe(|this, _outer_universe| {
552+
self.evaluation_probe(|this| {
570553
let goal =
571554
this.infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env));
572555
let mut result = this.evaluate_predicate_recursively(
@@ -589,11 +572,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
589572
/// `op`, but this can be overwritten if necessary.
590573
fn evaluation_probe(
591574
&mut self,
592-
op: impl FnOnce(&mut Self, &mut ty::UniverseIndex) -> Result<EvaluationResult, OverflowError>,
575+
op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>,
593576
) -> Result<EvaluationResult, OverflowError> {
594577
self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
595-
let mut outer_universe = self.infcx.universe();
596-
let result = op(self, &mut outer_universe)?;
578+
let outer_universe = self.infcx.universe();
579+
let result = op(self)?;
597580

598581
match self.infcx.leak_check(outer_universe, Some(snapshot)) {
599582
Ok(()) => {}
@@ -1254,7 +1237,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12541237
}
12551238

12561239
match self.candidate_from_obligation(stack) {
1257-
Ok(Some(c)) => self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::Yes),
1240+
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
12581241
Ok(None) => Ok(EvaluatedToAmbig),
12591242
Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
12601243
Err(..) => Ok(EvaluatedToErr),
@@ -1279,10 +1262,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12791262
/// Further evaluates `candidate` to decide whether all type parameters match and whether nested
12801263
/// obligations are met. Returns whether `candidate` remains viable after this further
12811264
/// scrutiny.
1282-
///
1283-
/// Depending on the value of [LeakCheckHigherRankedGoal], we may ignore the binder of the goal
1284-
/// when eagerly detecting higher ranked region errors via the `leak_check`. See that enum for
1285-
/// more info.
12861265
#[instrument(
12871266
level = "debug",
12881267
skip(self, stack),
@@ -1293,25 +1272,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12931272
&mut self,
12941273
stack: &TraitObligationStack<'o, 'tcx>,
12951274
candidate: &SelectionCandidate<'tcx>,
1296-
leak_check_higher_ranked_goal: LeakCheckHigherRankedGoal,
12971275
) -> Result<EvaluationResult, OverflowError> {
1298-
let mut result = self.evaluation_probe(|this, outer_universe| {
1299-
// We eagerly instantiate higher ranked goals to prevent universe errors
1300-
// from impacting candidate selection. This matches the behavior of the new
1301-
// solver. This slightly weakens type inference.
1302-
//
1303-
// In case there are no unresolved type or const variables this
1304-
// should still not be necessary to select a unique impl as any overlap
1305-
// relying on a universe error from higher ranked goals should have resulted
1306-
// in an overlap error in coherence.
1307-
let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate);
1308-
let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p));
1309-
match leak_check_higher_ranked_goal {
1310-
LeakCheckHigherRankedGoal::No => *outer_universe = self.infcx.universe(),
1311-
LeakCheckHigherRankedGoal::Yes => {}
1312-
}
1313-
1314-
match this.confirm_candidate(&obligation, candidate.clone()) {
1276+
let mut result = self.evaluation_probe(|this| {
1277+
match this.confirm_candidate(stack.obligation, candidate.clone()) {
13151278
Ok(selection) => {
13161279
debug!(?selection);
13171280
this.evaluate_predicates_recursively(
@@ -1731,19 +1694,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17311694
})
17321695
.map_err(|_| ())
17331696
}
1697+
17341698
fn where_clause_may_apply<'o>(
17351699
&mut self,
17361700
stack: &TraitObligationStack<'o, 'tcx>,
17371701
where_clause_trait_ref: ty::PolyTraitRef<'tcx>,
17381702
) -> Result<EvaluationResult, OverflowError> {
1739-
self.evaluation_probe(|this, outer_universe| {
1740-
// Eagerly instantiate higher ranked goals.
1741-
//
1742-
// See the comment in `evaluate_candidate` to see why.
1743-
let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate);
1744-
let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p));
1745-
*outer_universe = self.infcx.universe();
1746-
match this.match_where_clause_trait_ref(&obligation, where_clause_trait_ref) {
1703+
self.evaluation_probe(|this| {
1704+
match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
17471705
Ok(obligations) => this.evaluate_predicates_recursively(stack.list(), obligations),
17481706
Err(()) => Ok(EvaluatedToErr),
17491707
}

compiler/rustc_type_ir/src/flags.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ bitflags::bitflags! {
1414
/// Does this have `ConstKind::Param`?
1515
const HAS_CT_PARAM = 1 << 2;
1616

17-
const HAS_PARAM = TypeFlags::HAS_TY_PARAM.bits()
17+
const HAS_PARAM = TypeFlags::HAS_TY_PARAM.bits()
1818
| TypeFlags::HAS_RE_PARAM.bits()
1919
| TypeFlags::HAS_CT_PARAM.bits();
2020

@@ -27,7 +27,7 @@ bitflags::bitflags! {
2727

2828
/// Does this have inference variables? Used to determine whether
2929
/// inference is required.
30-
const HAS_INFER = TypeFlags::HAS_TY_INFER.bits()
30+
const HAS_INFER = TypeFlags::HAS_TY_INFER.bits()
3131
| TypeFlags::HAS_RE_INFER.bits()
3232
| TypeFlags::HAS_CT_INFER.bits();
3333

@@ -39,7 +39,7 @@ bitflags::bitflags! {
3939
const HAS_CT_PLACEHOLDER = 1 << 8;
4040

4141
/// Does this have placeholders?
42-
const HAS_PLACEHOLDER = TypeFlags::HAS_TY_PLACEHOLDER.bits()
42+
const HAS_PLACEHOLDER = TypeFlags::HAS_TY_PLACEHOLDER.bits()
4343
| TypeFlags::HAS_RE_PLACEHOLDER.bits()
4444
| TypeFlags::HAS_CT_PLACEHOLDER.bits();
4545

@@ -81,7 +81,7 @@ bitflags::bitflags! {
8181
/// Does this have `Alias` or `ConstKind::Unevaluated`?
8282
///
8383
/// Rephrased, could this term be normalized further?
84-
const HAS_ALIASES = TypeFlags::HAS_TY_PROJECTION.bits()
84+
const HAS_ALIAS = TypeFlags::HAS_TY_PROJECTION.bits()
8585
| TypeFlags::HAS_TY_WEAK.bits()
8686
| TypeFlags::HAS_TY_OPAQUE.bits()
8787
| TypeFlags::HAS_TY_INHERENT.bits()

compiler/rustc_type_ir/src/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
230230
}
231231

232232
fn has_aliases(&self) -> bool {
233-
self.has_type_flags(TypeFlags::HAS_ALIASES)
233+
self.has_type_flags(TypeFlags::HAS_ALIAS)
234234
}
235235

236236
fn has_inherent_projections(&self) -> bool {

library/alloc/src/slice/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ fn panic_safe() {
240240

241241
#[test]
242242
#[cfg_attr(miri, ignore)] // Miri is too slow
243+
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
243244
fn test_sort() {
244245
let mut rng = test_rng();
245246

src/bootstrap/bootstrap_test.py

+19
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,25 @@ def build_args(self, configure_args=None, args=None, env=None):
138138
if env is None:
139139
env = {}
140140

141+
# This test ends up invoking build_bootstrap_cmd, which searches for
142+
# the Cargo binary and errors out if it cannot be found. This is not a
143+
# problem in most cases, but there is a scenario where it would cause
144+
# the test to fail.
145+
#
146+
# When a custom local Cargo is configured in config.toml (with the
147+
# build.cargo setting), no Cargo is downloaded to any location known by
148+
# bootstrap, and bootstrap relies on that setting to find it.
149+
#
150+
# In this test though we are not using the config.toml of the caller:
151+
# we are generating a blank one instead. If we don't set build.cargo in
152+
# it, the test will have no way to find Cargo, failing the test.
153+
cargo_bin = os.environ.get("BOOTSTRAP_TEST_CARGO_BIN")
154+
if cargo_bin is not None:
155+
configure_args += ["--set", "build.cargo=" + cargo_bin]
156+
rustc_bin = os.environ.get("BOOTSTRAP_TEST_RUSTC_BIN")
157+
if rustc_bin is not None:
158+
configure_args += ["--set", "build.rustc=" + rustc_bin]
159+
141160
env = env.copy()
142161
env["PATH"] = os.environ["PATH"]
143162

src/bootstrap/src/core/build_steps/test.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2979,6 +2979,8 @@ impl Step for Bootstrap {
29792979
.args(["-m", "unittest", "bootstrap_test.py"])
29802980
.env("BUILD_DIR", &builder.out)
29812981
.env("BUILD_PLATFORM", builder.build.build.triple)
2982+
.env("BOOTSTRAP_TEST_RUSTC_BIN", &builder.initial_rustc)
2983+
.env("BOOTSTRAP_TEST_CARGO_BIN", &builder.initial_cargo)
29822984
.current_dir(builder.src.join("src/bootstrap/"));
29832985
// NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible.
29842986
// Use `python -m unittest` manually if you want to pass arguments.

src/bootstrap/src/core/config/config.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,17 @@ impl Config {
13301330
TomlConfig::default()
13311331
};
13321332

1333+
if cfg!(test) {
1334+
// When configuring bootstrap for tests, make sure to set the rustc and Cargo to the
1335+
// same ones used to call the tests (if custom ones are not defined in the toml). If we
1336+
// don't do that, bootstrap will use its own detection logic to find a suitable rustc
1337+
// and Cargo, which doesn't work when the caller is specìfying a custom local rustc or
1338+
// Cargo in their config.toml.
1339+
let build = toml.build.get_or_insert_with(Default::default);
1340+
build.rustc = build.rustc.take().or(std::env::var_os("RUSTC").map(|p| p.into()));
1341+
build.cargo = build.cargo.take().or(std::env::var_os("CARGO").map(|p| p.into()));
1342+
}
1343+
13331344
if let Some(include) = &toml.profile {
13341345
// Allows creating alias for profile names, allowing
13351346
// profiles to be renamed while maintaining back compatibility
@@ -1448,7 +1459,12 @@ impl Config {
14481459
rustc
14491460
} else {
14501461
config.download_beta_toolchain();
1451-
config.out.join(config.build.triple).join("stage0/bin/rustc")
1462+
config
1463+
.out
1464+
.join(config.build.triple)
1465+
.join("stage0")
1466+
.join("bin")
1467+
.join(exe("rustc", config.build))
14521468
};
14531469

14541470
config.initial_cargo = if let Some(cargo) = cargo {
@@ -1458,7 +1474,12 @@ impl Config {
14581474
cargo
14591475
} else {
14601476
config.download_beta_toolchain();
1461-
config.out.join(config.build.triple).join("stage0/bin/cargo")
1477+
config
1478+
.out
1479+
.join(config.build.triple)
1480+
.join("stage0")
1481+
.join("bin")
1482+
.join(exe("cargo", config.build))
14621483
};
14631484

14641485
// NOTE: it's important this comes *after* we set `initial_rustc` just above.

src/ci/docker/run.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
9393
docker --version
9494

9595
REGISTRY=ghcr.io
96-
REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER}
96+
REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER:-rust-lang-ci}
9797
# Tag used to push the final Docker image, so that it can be pulled by e.g. rustup
9898
IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum}
9999
# Tag used to cache the Docker build
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
trait MyIterator : Iterator {}
2+
3+
fn main() {
4+
let _ = MyIterator::next;
5+
}
6+
//~^^ ERROR the value of the associated type `Item` in `Iterator` must be specified [E0191]
7+
//~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
8+
//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
warning: trait objects without an explicit `dyn` are deprecated
2+
--> $DIR/dynless-turbofish-e0191-issue-91997.rs:4:13
3+
|
4+
LL | let _ = MyIterator::next;
5+
| ^^^^^^^^^^
6+
|
7+
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
8+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
9+
= note: `#[warn(bare_trait_objects)]` on by default
10+
help: if this is an object-safe trait, use `dyn`
11+
|
12+
LL | let _ = <dyn MyIterator>::next;
13+
| ++++ +
14+
15+
error[E0191]: the value of the associated type `Item` in `Iterator` must be specified
16+
--> $DIR/dynless-turbofish-e0191-issue-91997.rs:4:13
17+
|
18+
LL | let _ = MyIterator::next;
19+
| ^^^^^^^^^^ help: specify the associated type: `MyIterator::<Item = Type>`
20+
21+
error: aborting due to 1 previous error; 1 warning emitted
22+
23+
For more information about this error, try `rustc --explain E0191`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0277]: the trait bound `for<'a> &'a &T: Trait` is not satisfied
2+
--> $DIR/candidate-from-env-universe-err-1.rs:27:16
3+
|
4+
LL | hr_bound::<&T>();
5+
| ^^ the trait `for<'a> Trait` is not implemented for `&'a &T`
6+
|
7+
note: required by a bound in `hr_bound`
8+
--> $DIR/candidate-from-env-universe-err-1.rs:14:20
9+
|
10+
LL | fn hr_bound<T>()
11+
| -------- required by a bound in this function
12+
LL | where
13+
LL | for<'a> &'a T: Trait,
14+
| ^^^^^ required by this bound in `hr_bound`
15+
help: consider removing the leading `&`-reference
16+
|
17+
LL - hr_bound::<&T>();
18+
LL + hr_bound::<T>();
19+
|
20+
21+
error: aborting due to 1 previous error
22+
23+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)