Skip to content

Commit

Permalink
Auto merge of rust-lang#126726 - matthiaskrgr:rollup-ppe8ve3, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

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
  • Loading branch information
bors committed Jun 20, 2024
2 parents 54fcd5b + c979535 commit 1208edd
Show file tree
Hide file tree
Showing 67 changed files with 748 additions and 326 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4905,6 +4905,7 @@ version = "0.0.0"
dependencies = [
"bitflags 2.5.0",
"derivative",
"indexmap",
"rustc_ast_ir",
"rustc_data_structures",
"rustc_index",
Expand Down
20 changes: 18 additions & 2 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,9 +558,10 @@ impl Token {
/// Returns `true` if the token can appear at the start of a const param.
pub fn can_begin_const_arg(&self) -> bool {
match self.kind {
OpenDelim(Delimiter::Brace) => true,
OpenDelim(Delimiter::Brace) | Literal(..) | BinOp(Minus) => true,
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)),
_ => self.can_begin_literal_maybe_minus(),
_ => false,
}
}

Expand Down Expand Up @@ -620,6 +621,21 @@ impl Token {
}
}

pub fn can_begin_string_literal(&self) -> bool {
match self.uninterpolate().kind {
Literal(..) => true,
Interpolated(ref nt) => match &**nt {
NtLiteral(_) => true,
NtExpr(e) => match &e.kind {
ast::ExprKind::Lit(_) => true,
_ => false,
},
_ => false,
},
_ => false,
}
}

/// A convenience function for matching on identifiers during parsing.
/// Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token
/// into the regular identifier or lifetime token it refers to,
Expand Down
11 changes: 1 addition & 10 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,7 @@ where

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

debug!(?assumed_wf_types);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
}

fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) -> ErrorGuaranteed {
if let Some(guar) = self.fcx.dcx().has_errors() {
if let Some(guar) = self.fcx.tainted_by_errors() {
guar
} else {
self.fcx
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho
.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`
.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
.doctest = make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`
.exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration
.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
.const_anon = use a const-anon item to suppress this lint
.macro_to_change = the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_next_trait_solver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2021"
# tidy-alphabetical-start
bitflags = "2.4.1"
derivative = "2.2.0"
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
rustc_index = { path = "../rustc_index", default-features = false }
rustc_macros = { path = "../rustc_macros", optional = true }
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_next_trait_solver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
//! but were uplifted in the process of making the new trait solver generic.
//! So if you got to this crate from the old solver, it's totally normal.

#![feature(let_chains)]

pub mod canonicalizer;
pub mod infcx;
pub mod resolve;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! traits, `Copy`/`Clone`.

use rustc_ast_ir::{Movability, Mutability};
use rustc_data_structures::fx::FxHashMap;
use rustc_type_ir::data_structures::HashMap;
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
Expand Down Expand Up @@ -304,9 +304,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
let kind_ty = args.kind_ty();
let sig = args.coroutine_closure_sig().skip_binder();

let coroutine_ty = if let Some(closure_kind) = kind_ty.to_opt_closure_kind()
&& !args.tupled_upvars_ty().is_ty_var()
{
// FIXME: let_chains
let kind = kind_ty.to_opt_closure_kind();
let coroutine_ty = if kind.is_some() && !args.tupled_upvars_ty().is_ty_var() {
let closure_kind = kind.unwrap();
if !closure_kind.extends(goal_kind) {
return Err(NoSolution);
}
Expand Down Expand Up @@ -411,10 +412,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
let kind_ty = args.kind_ty();
let sig = args.coroutine_closure_sig().skip_binder();
let mut nested = vec![];
let coroutine_ty = if let Some(closure_kind) = kind_ty.to_opt_closure_kind()
&& !args.tupled_upvars_ty().is_ty_var()
{
if !closure_kind.extends(goal_kind) {

// FIXME: let_chains
let kind = kind_ty.to_opt_closure_kind();
let coroutine_ty = if kind.is_some() && !args.tupled_upvars_ty().is_ty_var() {
if !kind.unwrap().extends(goal_kind) {
return Err(NoSolution);
}

Expand Down Expand Up @@ -683,7 +685,7 @@ where
);
}

let mut replace_projection_with = FxHashMap::default();
let mut replace_projection_with = HashMap::default();
for bound in object_bounds {
if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() {
let proj = proj.with_self_ty(tcx, trait_ref.self_ty());
Expand Down Expand Up @@ -713,7 +715,7 @@ where
struct ReplaceProjectionWith<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> {
ecx: &'a EvalCtxt<'a, Infcx>,
param_env: I::ParamEnv,
mapping: FxHashMap<I::DefId, ty::Binder<I, ty::ProjectionPredicate<I>>>,
mapping: HashMap<I::DefId, ty::Binder<I, ty::ProjectionPredicate<I>>>,
nested: Vec<Goal<I, I::Predicate>>,
}

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

fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
if let ty::Alias(ty::Projection, alias_ty) = ty.kind()
&& let Some(replacement) = self.mapping.get(&alias_ty.def_id)
{
// We may have a case where our object type's projection bound is higher-ranked,
// but the where clauses we instantiated are not. We can solve this by instantiating
// the binder at the usage site.
let proj = self.ecx.instantiate_binder_with_infer(*replacement);
// FIXME: Technically this equate could be fallible...
self.nested.extend(
self.ecx
.eq_and_get_goals(
self.param_env,
alias_ty,
proj.projection_term.expect_ty(self.ecx.interner()),
)
.expect("expected to be able to unify goal projection with dyn's projection"),
);
proj.term.expect_ty()
if let ty::Alias(ty::Projection, alias_ty) = ty.kind() {
if let Some(replacement) = self.mapping.get(&alias_ty.def_id) {
// We may have a case where our object type's projection bound is higher-ranked,
// but the where clauses we instantiated are not. We can solve this by instantiating
// the binder at the usage site.
let proj = self.ecx.instantiate_binder_with_infer(*replacement);
// FIXME: Technically this equate could be fallible...
self.nested.extend(
self.ecx
.eq_and_get_goals(
self.param_env,
alias_ty,
proj.projection_term.expect_ty(self.ecx.interner()),
)
.expect(
"expected to be able to unify goal projection with dyn's projection",
),
);
proj.term.expect_ty()
} else {
ty.super_fold_with(self)
}
} else {
ty.super_fold_with(self)
}
Expand Down
41 changes: 24 additions & 17 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::ops::ControlFlow;

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

#[derive(PartialEq, Eq, Debug, Hash, HashStable_NoContext, Clone, Copy)]
#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)]
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
pub enum GenerateProofTree {
Yes,
No,
Expand Down Expand Up @@ -689,14 +691,15 @@ where
fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
match t.kind() {
ty::Infer(ty::TyVar(vid)) => {
if let ty::TermKind::Ty(term) = self.term.kind()
&& let ty::Infer(ty::TyVar(term_vid)) = term.kind()
&& self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid)
{
ControlFlow::Break(())
} else {
self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
if let ty::TermKind::Ty(term) = self.term.kind() {
if let ty::Infer(ty::TyVar(term_vid)) = term.kind() {
if self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid) {
return ControlFlow::Break(());
}
}
}

self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
}
ty::Placeholder(p) => self.check_nameable(p.universe()),
_ => {
Expand All @@ -712,14 +715,18 @@ where
fn visit_const(&mut self, c: I::Const) -> Self::Result {
match c.kind() {
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
if let ty::TermKind::Const(term) = self.term.kind()
&& let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
&& self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid)
{
ControlFlow::Break(())
} else {
self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
if let ty::TermKind::Const(term) = self.term.kind() {
if let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
{
if self.infcx.root_const_var(vid)
== self.infcx.root_const_var(term_vid)
{
return ControlFlow::Break(());
}
}
}

self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
}
ty::ConstKind::Placeholder(p) => self.check_nameable(p.universe()),
_ => {
Expand Down
17 changes: 11 additions & 6 deletions compiler/rustc_next_trait_solver/src/solve/search_graph.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::mem;

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_index::{Idx, IndexVec};
use rustc_type_ir::data_structures::{HashMap, HashSet};
use rustc_type_ir::inherent::*;
use rustc_type_ir::Interner;
use tracing::debug;
Expand All @@ -17,6 +17,7 @@ pub struct SolverLimit(usize);

rustc_index::newtype_index! {
#[orderable]
#[gate_rustc_only]
pub struct StackDepth {}
}

Expand Down Expand Up @@ -70,7 +71,7 @@ struct StackEntry<I: Interner> {
/// C :- D
/// D :- C
/// ```
cycle_participants: FxHashSet<CanonicalInput<I>>,
cycle_participants: HashSet<CanonicalInput<I>>,
/// Starts out as `None` and gets set when rerunning this
/// goal in case we encounter a cycle.
provisional_result: Option<QueryResult<I>>,
Expand Down Expand Up @@ -126,7 +127,7 @@ pub(super) struct SearchGraph<I: Interner> {
///
/// An element is *deeper* in the stack if its index is *lower*.
stack: IndexVec<StackDepth, StackEntry<I>>,
provisional_cache: FxHashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
provisional_cache: HashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
}

impl<I: Interner> SearchGraph<I> {
Expand Down Expand Up @@ -227,13 +228,17 @@ impl<I: Interner> SearchGraph<I> {
}

fn clear_dependent_provisional_results(
provisional_cache: &mut FxHashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
provisional_cache: &mut HashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
head: StackDepth,
) {
#[allow(rustc::potential_query_instability)]
provisional_cache.retain(|_, entry| {
entry.with_coinductive_stack.take_if(|p| p.head == head);
entry.with_inductive_stack.take_if(|p| p.head == head);
if entry.with_coinductive_stack.as_ref().is_some_and(|p| p.head == head) {
entry.with_coinductive_stack.take();
}
if entry.with_inductive_stack.as_ref().is_some_and(|p| p.head == head) {
entry.with_inductive_stack.take();
}
!entry.is_empty()
});
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Dealing with trait goals, i.e. `T: Trait<'a, U>`.

use rustc_ast_ir::Movability;
use rustc_data_structures::fx::FxIndexSet;
use rustc_type_ir::data_structures::IndexSet;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::visit::TypeVisitableExt as _;
Expand Down Expand Up @@ -821,7 +821,7 @@ where
// We may upcast to auto traits that are either explicitly listed in
// the object type's bounds, or implied by the principal trait ref's
// supertraits.
let a_auto_traits: FxIndexSet<I::DefId> = a_data
let a_auto_traits: IndexSet<I::DefId> = a_data
.auto_traits()
.into_iter()
.chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,7 @@ impl<'a> Parser<'a> {
self.token.is_keyword(kw::Unsafe)
&& self.is_keyword_ahead(1, &[kw::Extern])
&& self.look_ahead(
2 + self.look_ahead(2, |t| t.can_begin_literal_maybe_minus() as usize),
2 + self.look_ahead(2, |t| t.can_begin_string_literal() as usize),
|t| t.kind == token::OpenDelim(Delimiter::Brace),
)
}
Expand Down Expand Up @@ -2448,7 +2448,7 @@ impl<'a> Parser<'a> {
})
// `extern ABI fn`
|| self.check_keyword_case(kw::Extern, case)
&& self.look_ahead(1, |t| t.can_begin_literal_maybe_minus())
&& self.look_ahead(1, |t| t.can_begin_string_literal())
&& (self.look_ahead(2, |t| t.is_keyword_case(kw::Fn, case)) ||
// this branch is only for better diagnostic in later, `pub` is not allowed here
(self.may_recover()
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,8 @@ impl<'a> Parser<'a> {
|| self.look_ahead(dist, |t| {
t.is_path_start() // e.g. `MY_CONST`;
|| t.kind == token::Dot // e.g. `.5` for recovery;
|| t.can_begin_literal_maybe_minus() // e.g. `42`.
|| matches!(t.kind, token::Literal(..) | token::BinOp(token::Minus))
|| t.is_bool_lit()
|| t.is_whole_expr()
|| t.is_lifetime() // recover `'a` instead of `'a'`
|| (self.may_recover() // recover leading `(`
Expand Down
Loading

0 comments on commit 1208edd

Please sign in to comment.