Skip to content

Commit 1208edd

Browse files
committed
Auto merge of rust-lang#126726 - matthiaskrgr:rollup-ppe8ve3, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#126620 (Actually taint InferCtxt when a fulfillment error is emitted) - rust-lang#126649 (Fix `feature = "nightly"` in the new trait solver) - rust-lang#126652 (Clarify that anonymous consts still do introduce a new scope) - rust-lang#126703 (reword the hint::blackbox non-guarantees) - rust-lang#126708 (Minimize `can_begin_literal_maybe_minus` usage) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 54fcd5b + c979535 commit 1208edd

File tree

67 files changed

+748
-326
lines changed

Some content is hidden

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

67 files changed

+748
-326
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4905,6 +4905,7 @@ version = "0.0.0"
49054905
dependencies = [
49064906
"bitflags 2.5.0",
49074907
"derivative",
4908+
"indexmap",
49084909
"rustc_ast_ir",
49094910
"rustc_data_structures",
49104911
"rustc_index",

compiler/rustc_ast/src/token.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -558,9 +558,10 @@ impl Token {
558558
/// Returns `true` if the token can appear at the start of a const param.
559559
pub fn can_begin_const_arg(&self) -> bool {
560560
match self.kind {
561-
OpenDelim(Delimiter::Brace) => true,
561+
OpenDelim(Delimiter::Brace) | Literal(..) | BinOp(Minus) => true,
562+
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
562563
Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)),
563-
_ => self.can_begin_literal_maybe_minus(),
564+
_ => false,
564565
}
565566
}
566567

@@ -620,6 +621,21 @@ impl Token {
620621
}
621622
}
622623

624+
pub fn can_begin_string_literal(&self) -> bool {
625+
match self.uninterpolate().kind {
626+
Literal(..) => true,
627+
Interpolated(ref nt) => match &**nt {
628+
NtLiteral(_) => true,
629+
NtExpr(e) => match &e.kind {
630+
ast::ExprKind::Lit(_) => true,
631+
_ => false,
632+
},
633+
_ => false,
634+
},
635+
_ => false,
636+
}
637+
}
638+
623639
/// A convenience function for matching on identifiers during parsing.
624640
/// Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token
625641
/// into the regular identifier or lifetime token it refers to,

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,7 @@ where
119119

120120
let errors = wfcx.select_all_or_error();
121121
if !errors.is_empty() {
122-
let err = infcx.err_ctxt().report_fulfillment_errors(errors);
123-
if tcx.dcx().has_errors().is_some() {
124-
return Err(err);
125-
} else {
126-
// HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs
127-
// causes an delayed bug during normalization, without reporting an error, so we need
128-
// to act as if no error happened, in order to let our callers continue and report an
129-
// error later in check_impl_items_against_trait.
130-
return Ok(());
131-
}
122+
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
132123
}
133124

134125
debug!(?assumed_wf_types);

compiler/rustc_hir_typeck/src/writeback.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
793793
}
794794

795795
fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) -> ErrorGuaranteed {
796-
if let Some(guar) = self.fcx.dcx().has_errors() {
796+
if let Some(guar) = self.fcx.tainted_by_errors() {
797797
guar
798798
} else {
799799
self.fcx

compiler/rustc_lint/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho
550550
.with_trait = an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
551551
.bounds = `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
552552
.doctest = make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`
553-
.exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration
553+
.exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint
554554
.const_anon = use a const-anon item to suppress this lint
555555
.macro_to_change = the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed
556556

compiler/rustc_next_trait_solver/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ edition = "2021"
77
# tidy-alphabetical-start
88
bitflags = "2.4.1"
99
derivative = "2.2.0"
10-
rustc_ast_ir = { path = "../rustc_ast_ir" }
10+
rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
1111
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
1212
rustc_index = { path = "../rustc_index", default-features = false }
1313
rustc_macros = { path = "../rustc_macros", optional = true }

compiler/rustc_next_trait_solver/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
//! but were uplifted in the process of making the new trait solver generic.
55
//! So if you got to this crate from the old solver, it's totally normal.
66
7-
#![feature(let_chains)]
8-
97
pub mod canonicalizer;
108
pub mod infcx;
119
pub mod resolve;

compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs

+34-28
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! traits, `Copy`/`Clone`.
33
44
use rustc_ast_ir::{Movability, Mutability};
5-
use rustc_data_structures::fx::FxHashMap;
5+
use rustc_type_ir::data_structures::HashMap;
66
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
77
use rustc_type_ir::inherent::*;
88
use rustc_type_ir::lang_items::TraitSolverLangItem;
@@ -304,9 +304,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
304304
let kind_ty = args.kind_ty();
305305
let sig = args.coroutine_closure_sig().skip_binder();
306306

307-
let coroutine_ty = if let Some(closure_kind) = kind_ty.to_opt_closure_kind()
308-
&& !args.tupled_upvars_ty().is_ty_var()
309-
{
307+
// FIXME: let_chains
308+
let kind = kind_ty.to_opt_closure_kind();
309+
let coroutine_ty = if kind.is_some() && !args.tupled_upvars_ty().is_ty_var() {
310+
let closure_kind = kind.unwrap();
310311
if !closure_kind.extends(goal_kind) {
311312
return Err(NoSolution);
312313
}
@@ -411,10 +412,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
411412
let kind_ty = args.kind_ty();
412413
let sig = args.coroutine_closure_sig().skip_binder();
413414
let mut nested = vec![];
414-
let coroutine_ty = if let Some(closure_kind) = kind_ty.to_opt_closure_kind()
415-
&& !args.tupled_upvars_ty().is_ty_var()
416-
{
417-
if !closure_kind.extends(goal_kind) {
415+
416+
// FIXME: let_chains
417+
let kind = kind_ty.to_opt_closure_kind();
418+
let coroutine_ty = if kind.is_some() && !args.tupled_upvars_ty().is_ty_var() {
419+
if !kind.unwrap().extends(goal_kind) {
418420
return Err(NoSolution);
419421
}
420422

@@ -683,7 +685,7 @@ where
683685
);
684686
}
685687

686-
let mut replace_projection_with = FxHashMap::default();
688+
let mut replace_projection_with = HashMap::default();
687689
for bound in object_bounds {
688690
if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() {
689691
let proj = proj.with_self_ty(tcx, trait_ref.self_ty());
@@ -713,7 +715,7 @@ where
713715
struct ReplaceProjectionWith<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> {
714716
ecx: &'a EvalCtxt<'a, Infcx>,
715717
param_env: I::ParamEnv,
716-
mapping: FxHashMap<I::DefId, ty::Binder<I, ty::ProjectionPredicate<I>>>,
718+
mapping: HashMap<I::DefId, ty::Binder<I, ty::ProjectionPredicate<I>>>,
717719
nested: Vec<Goal<I, I::Predicate>>,
718720
}
719721

@@ -725,24 +727,28 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
725727
}
726728

727729
fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
728-
if let ty::Alias(ty::Projection, alias_ty) = ty.kind()
729-
&& let Some(replacement) = self.mapping.get(&alias_ty.def_id)
730-
{
731-
// We may have a case where our object type's projection bound is higher-ranked,
732-
// but the where clauses we instantiated are not. We can solve this by instantiating
733-
// the binder at the usage site.
734-
let proj = self.ecx.instantiate_binder_with_infer(*replacement);
735-
// FIXME: Technically this equate could be fallible...
736-
self.nested.extend(
737-
self.ecx
738-
.eq_and_get_goals(
739-
self.param_env,
740-
alias_ty,
741-
proj.projection_term.expect_ty(self.ecx.interner()),
742-
)
743-
.expect("expected to be able to unify goal projection with dyn's projection"),
744-
);
745-
proj.term.expect_ty()
730+
if let ty::Alias(ty::Projection, alias_ty) = ty.kind() {
731+
if let Some(replacement) = self.mapping.get(&alias_ty.def_id) {
732+
// We may have a case where our object type's projection bound is higher-ranked,
733+
// but the where clauses we instantiated are not. We can solve this by instantiating
734+
// the binder at the usage site.
735+
let proj = self.ecx.instantiate_binder_with_infer(*replacement);
736+
// FIXME: Technically this equate could be fallible...
737+
self.nested.extend(
738+
self.ecx
739+
.eq_and_get_goals(
740+
self.param_env,
741+
alias_ty,
742+
proj.projection_term.expect_ty(self.ecx.interner()),
743+
)
744+
.expect(
745+
"expected to be able to unify goal projection with dyn's projection",
746+
),
747+
);
748+
proj.term.expect_ty()
749+
} else {
750+
ty.super_fold_with(self)
751+
}
746752
} else {
747753
ty.super_fold_with(self)
748754
}

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

+24-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::ops::ControlFlow;
22

3-
use rustc_data_structures::stack::ensure_sufficient_stack;
3+
#[cfg(feature = "nightly")]
44
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
5+
use rustc_type_ir::data_structures::ensure_sufficient_stack;
56
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
67
use rustc_type_ir::inherent::*;
78
use rustc_type_ir::relate::Relate;
@@ -88,7 +89,7 @@ where
8889
#[derive(derivative::Derivative)]
8990
#[derivative(Clone(bound = ""), Debug(bound = ""), Default(bound = ""))]
9091
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
91-
#[derive(TyDecodable, TyEncodable, HashStable_NoContext)]
92+
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
9293
// FIXME: This can be made crate-private once `EvalCtxt` also lives in this crate.
9394
pub struct NestedGoals<I: Interner> {
9495
/// These normalizes-to goals are treated specially during the evaluation
@@ -116,7 +117,8 @@ impl<I: Interner> NestedGoals<I> {
116117
}
117118
}
118119

119-
#[derive(PartialEq, Eq, Debug, Hash, HashStable_NoContext, Clone, Copy)]
120+
#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)]
121+
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
120122
pub enum GenerateProofTree {
121123
Yes,
122124
No,
@@ -689,14 +691,15 @@ where
689691
fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
690692
match t.kind() {
691693
ty::Infer(ty::TyVar(vid)) => {
692-
if let ty::TermKind::Ty(term) = self.term.kind()
693-
&& let ty::Infer(ty::TyVar(term_vid)) = term.kind()
694-
&& self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid)
695-
{
696-
ControlFlow::Break(())
697-
} else {
698-
self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
694+
if let ty::TermKind::Ty(term) = self.term.kind() {
695+
if let ty::Infer(ty::TyVar(term_vid)) = term.kind() {
696+
if self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid) {
697+
return ControlFlow::Break(());
698+
}
699+
}
699700
}
701+
702+
self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
700703
}
701704
ty::Placeholder(p) => self.check_nameable(p.universe()),
702705
_ => {
@@ -712,14 +715,18 @@ where
712715
fn visit_const(&mut self, c: I::Const) -> Self::Result {
713716
match c.kind() {
714717
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
715-
if let ty::TermKind::Const(term) = self.term.kind()
716-
&& let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
717-
&& self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid)
718-
{
719-
ControlFlow::Break(())
720-
} else {
721-
self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
718+
if let ty::TermKind::Const(term) = self.term.kind() {
719+
if let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
720+
{
721+
if self.infcx.root_const_var(vid)
722+
== self.infcx.root_const_var(term_vid)
723+
{
724+
return ControlFlow::Break(());
725+
}
726+
}
722727
}
728+
729+
self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
723730
}
724731
ty::ConstKind::Placeholder(p) => self.check_nameable(p.universe()),
725732
_ => {

compiler/rustc_next_trait_solver/src/solve/search_graph.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::mem;
22

3-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
43
use rustc_index::{Idx, IndexVec};
4+
use rustc_type_ir::data_structures::{HashMap, HashSet};
55
use rustc_type_ir::inherent::*;
66
use rustc_type_ir::Interner;
77
use tracing::debug;
@@ -17,6 +17,7 @@ pub struct SolverLimit(usize);
1717

1818
rustc_index::newtype_index! {
1919
#[orderable]
20+
#[gate_rustc_only]
2021
pub struct StackDepth {}
2122
}
2223

@@ -70,7 +71,7 @@ struct StackEntry<I: Interner> {
7071
/// C :- D
7172
/// D :- C
7273
/// ```
73-
cycle_participants: FxHashSet<CanonicalInput<I>>,
74+
cycle_participants: HashSet<CanonicalInput<I>>,
7475
/// Starts out as `None` and gets set when rerunning this
7576
/// goal in case we encounter a cycle.
7677
provisional_result: Option<QueryResult<I>>,
@@ -126,7 +127,7 @@ pub(super) struct SearchGraph<I: Interner> {
126127
///
127128
/// An element is *deeper* in the stack if its index is *lower*.
128129
stack: IndexVec<StackDepth, StackEntry<I>>,
129-
provisional_cache: FxHashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
130+
provisional_cache: HashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
130131
}
131132

132133
impl<I: Interner> SearchGraph<I> {
@@ -227,13 +228,17 @@ impl<I: Interner> SearchGraph<I> {
227228
}
228229

229230
fn clear_dependent_provisional_results(
230-
provisional_cache: &mut FxHashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
231+
provisional_cache: &mut HashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
231232
head: StackDepth,
232233
) {
233234
#[allow(rustc::potential_query_instability)]
234235
provisional_cache.retain(|_, entry| {
235-
entry.with_coinductive_stack.take_if(|p| p.head == head);
236-
entry.with_inductive_stack.take_if(|p| p.head == head);
236+
if entry.with_coinductive_stack.as_ref().is_some_and(|p| p.head == head) {
237+
entry.with_coinductive_stack.take();
238+
}
239+
if entry.with_inductive_stack.as_ref().is_some_and(|p| p.head == head) {
240+
entry.with_inductive_stack.take();
241+
}
237242
!entry.is_empty()
238243
});
239244
}

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Dealing with trait goals, i.e. `T: Trait<'a, U>`.
22
33
use rustc_ast_ir::Movability;
4-
use rustc_data_structures::fx::FxIndexSet;
4+
use rustc_type_ir::data_structures::IndexSet;
55
use rustc_type_ir::inherent::*;
66
use rustc_type_ir::lang_items::TraitSolverLangItem;
77
use rustc_type_ir::visit::TypeVisitableExt as _;
@@ -821,7 +821,7 @@ where
821821
// We may upcast to auto traits that are either explicitly listed in
822822
// the object type's bounds, or implied by the principal trait ref's
823823
// supertraits.
824-
let a_auto_traits: FxIndexSet<I::DefId> = a_data
824+
let a_auto_traits: IndexSet<I::DefId> = a_data
825825
.auto_traits()
826826
.into_iter()
827827
.chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {

compiler/rustc_parse/src/parser/item.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,7 @@ impl<'a> Parser<'a> {
12591259
self.token.is_keyword(kw::Unsafe)
12601260
&& self.is_keyword_ahead(1, &[kw::Extern])
12611261
&& self.look_ahead(
1262-
2 + self.look_ahead(2, |t| t.can_begin_literal_maybe_minus() as usize),
1262+
2 + self.look_ahead(2, |t| t.can_begin_string_literal() as usize),
12631263
|t| t.kind == token::OpenDelim(Delimiter::Brace),
12641264
)
12651265
}
@@ -2448,7 +2448,7 @@ impl<'a> Parser<'a> {
24482448
})
24492449
// `extern ABI fn`
24502450
|| self.check_keyword_case(kw::Extern, case)
2451-
&& self.look_ahead(1, |t| t.can_begin_literal_maybe_minus())
2451+
&& self.look_ahead(1, |t| t.can_begin_string_literal())
24522452
&& (self.look_ahead(2, |t| t.is_keyword_case(kw::Fn, case)) ||
24532453
// this branch is only for better diagnostic in later, `pub` is not allowed here
24542454
(self.may_recover()

compiler/rustc_parse/src/parser/pat.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,8 @@ impl<'a> Parser<'a> {
939939
|| self.look_ahead(dist, |t| {
940940
t.is_path_start() // e.g. `MY_CONST`;
941941
|| t.kind == token::Dot // e.g. `.5` for recovery;
942-
|| t.can_begin_literal_maybe_minus() // e.g. `42`.
942+
|| matches!(t.kind, token::Literal(..) | token::BinOp(token::Minus))
943+
|| t.is_bool_lit()
943944
|| t.is_whole_expr()
944945
|| t.is_lifetime() // recover `'a` instead of `'a'`
945946
|| (self.may_recover() // recover leading `(`

0 commit comments

Comments
 (0)