Auto merge of #156190 - JonathanBrouwer:rollup-db0KRf1, r=JonathanBrouwer

Rollup of 7 pull requests

Successful merges:

 - rust-lang/rust#156014 (resolve: Catch "cannot reexport" errors from macros 2.0 better)
 - rust-lang/rust#156058 (Print HRTB binders before fn qualifiers)
 - rust-lang/rust#156172 (Implement a new flag `-Zdisable-fast-paths` in trait solving)
 - rust-lang/rust#156184 (Revert "remove `MethodReceiverExpr` special-casing")
 - rust-lang/rust#155957 (Revert const hacks and use const closures in std)
 - rust-lang/rust#156127 (Update `askama` version to `0.16.0`)
 - rust-lang/rust#156183 (Remove duplicate debug assert)
This commit is contained in:
bors
2026-05-05 19:36:08 +00:00
40 changed files with 369 additions and 193 deletions
+14 -10
View File
@@ -174,9 +174,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "askama"
version = "0.15.4"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08e1676b346cadfec169374f949d7490fd80a24193d37d2afce0c047cf695e57"
checksum = "f1bf825125edd887a019d0a3a837dcc5499a68b0d034cc3eb594070c3e18addc"
dependencies = [
"askama_macros",
"itoa",
@@ -187,12 +187,13 @@ dependencies = [
[[package]]
name = "askama_derive"
version = "0.15.4"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7661ff56517787343f376f75db037426facd7c8d3049cef8911f1e75016f3a37"
checksum = "e1c7065972a130eafa84215f21352ae15b4a7393da48c1f5e103904490736738"
dependencies = [
"askama_parser",
"basic-toml",
"glob",
"memchr",
"proc-macro2",
"quote",
@@ -204,24 +205,24 @@ dependencies = [
[[package]]
name = "askama_macros"
version = "0.15.4"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "713ee4dbfd1eb719c2dab859465b01fa1d21cb566684614a713a6b7a99a4e47b"
checksum = "0e23b1d2c4bd39a41971f6124cef4cc6fd0540913ecb90919b69ab3bbe44ae1a"
dependencies = [
"askama_derive",
]
[[package]]
name = "askama_parser"
version = "0.15.4"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d62d674238a526418b30c0def480d5beadb9d8964e7f38d635b03bf639c704c"
checksum = "7db09fde9143e7ac4513358fb32ee32847125b63b18ea715afd487956da715da"
dependencies = [
"rustc-hash 2.1.1",
"serde",
"serde_derive",
"unicode-ident",
"winnow 0.7.13",
"winnow 1.0.0",
]
[[package]]
@@ -756,7 +757,7 @@ checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681"
dependencies = [
"serde",
"termcolor",
"unicode-width 0.1.14",
"unicode-width 0.2.2",
]
[[package]]
@@ -6625,6 +6626,9 @@ name = "winnow"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8"
dependencies = [
"memchr",
]
[[package]]
name = "winsplit"
-4
View File
@@ -423,10 +423,6 @@ pub trait MacResult {
None
}
fn make_method_receiver_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
self.make_expr()
}
/// Creates zero or more items.
fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
None
+14 -5
View File
@@ -68,6 +68,7 @@ macro_rules! ast_fragments {
/// Can also serve as an input and intermediate result for macro expansion operations.
pub enum AstFragment {
OptExpr(Option<Box<ast::Expr>>),
MethodReceiverExpr(Box<ast::Expr>),
$($Kind($AstTy),)*
}
@@ -75,6 +76,7 @@ macro_rules! ast_fragments {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum AstFragmentKind {
OptExpr,
MethodReceiverExpr,
$($Kind,)*
}
@@ -82,6 +84,7 @@ macro_rules! ast_fragments {
pub fn name(self) -> &'static str {
match self {
AstFragmentKind::OptExpr => "expression",
AstFragmentKind::MethodReceiverExpr => "expression",
$(AstFragmentKind::$Kind => $kind_name,)*
}
}
@@ -90,6 +93,8 @@ macro_rules! ast_fragments {
match self {
AstFragmentKind::OptExpr =>
result.make_expr().map(Some).map(AstFragment::OptExpr),
AstFragmentKind::MethodReceiverExpr =>
result.make_expr().map(AstFragment::MethodReceiverExpr),
$(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)*
}
}
@@ -116,6 +121,13 @@ macro_rules! ast_fragments {
}
}
pub(crate) fn make_method_receiver_expr(self) -> Box<ast::Expr> {
match self {
AstFragment::MethodReceiverExpr(expr) => expr,
_ => panic!("AstFragment::make_method_receiver_expr called on the wrong kind of fragment"),
}
}
$(pub fn $make_ast(self) -> $AstTy {
match self {
AstFragment::$Kind(ast) => ast,
@@ -134,6 +146,7 @@ macro_rules! ast_fragments {
*opt_expr = vis.filter_map_expr(expr)
}
}
AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr),
$($(AstFragment::$Kind(ast) => vis.$visit_ast(ast),)?)*
$($(AstFragment::$Kind(ast) =>
ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast, $($args)*)),)?)*
@@ -144,6 +157,7 @@ macro_rules! ast_fragments {
match self {
AstFragment::OptExpr(Some(expr)) => try_visit!(visitor.visit_expr(expr)),
AstFragment::OptExpr(None) => {}
AstFragment::MethodReceiverExpr(expr) => try_visit!(visitor.visit_method_receiver_expr(expr)),
$($(AstFragment::$Kind(ast) => try_visit!(visitor.$visit_ast(ast)),)?)*
$($(AstFragment::$Kind(ast) => walk_list!(visitor, $visit_ast_elt, &ast[..], $($args)*),)?)*
}
@@ -166,11 +180,6 @@ ast_fragments! {
one fn visit_expr;
fn make_expr;
}
MethodReceiverExpr(Box<ast::Expr>) {
"expression";
one fn visit_method_receiver_expr;
fn make_method_receiver_expr;
}
Pat(Box<ast::Pat>) {
"pattern";
one fn visit_pat;
@@ -22,6 +22,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
self.next_trait_solver
}
fn disable_trait_solver_fast_paths(&self) -> bool {
self.disable_trait_solver_fast_paths()
}
fn typing_mode(&self) -> ty::TypingMode<'tcx> {
self.typing_mode()
}
+5
View File
@@ -640,6 +640,11 @@ impl<'tcx> InferCtxt<'tcx> {
self.next_trait_solver
}
#[inline(always)]
pub fn disable_trait_solver_fast_paths(&self) -> bool {
self.tcx.disable_trait_solver_fast_paths()
}
#[inline(always)]
pub fn typing_mode(&self) -> TypingMode<'tcx> {
self.typing_mode
+4
View File
@@ -2657,6 +2657,10 @@ impl<'tcx> TyCtxt<'tcx> {
self.sess.opts.unstable_opts.next_solver.coherence
}
pub fn disable_trait_solver_fast_paths(self) -> bool {
self.sess.opts.unstable_opts.disable_fast_paths
}
#[allow(rustc::bad_opt_access)]
pub fn use_typing_mode_borrowck(self) -> bool {
self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
@@ -447,6 +447,7 @@ where
ref sub_roots,
stalled_certainty,
}) = stalled_on
&& !self.delegate.disable_trait_solver_fast_paths()
&& !stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
&& !sub_roots
.iter()
@@ -666,7 +667,10 @@ where
// If this loop did not result in any progress, what's our final certainty.
let mut unchanged_certainty = Some(Certainty::Yes);
for (source, goal, stalled_on) in mem::take(&mut self.nested_goals) {
if let Some(certainty) = self.delegate.compute_goal_fast_path(goal, self.origin_span) {
if !self.delegate.disable_trait_solver_fast_paths()
&& let Some(certainty) =
self.delegate.compute_goal_fast_path(goal, self.origin_span)
{
match certainty {
Certainty::Yes => {}
Certainty::Maybe { .. } => {
+2 -1
View File
@@ -54,10 +54,11 @@ fn inherit_const_stability(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
match def_kind {
DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst { .. } => {
match tcx.def_kind(tcx.local_parent(def_id)) {
DefKind::Impl { .. } => true,
DefKind::Trait | DefKind::Impl { .. } => true,
_ => false,
}
}
DefKind::Closure => true,
_ => false,
}
}
+105 -64
View File
@@ -9,7 +9,9 @@ use rustc_attr_parsing::AttributeParser;
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_data_structures::intern::Interned;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diagnostic, MultiSpan, pluralize, struct_span_code_err};
use rustc_errors::{
Applicability, BufferedEarlyLint, Diagnostic, MultiSpan, pluralize, struct_span_code_err,
};
use rustc_hir::Attribute;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::attrs::diagnostic::{CustomDiagnostic, Directive, FormatArgs};
@@ -19,6 +21,7 @@ use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport};
use rustc_middle::span_bug;
use rustc_middle::ty::{TyCtxt, Visibility};
use rustc_session::errors::feature_err;
use rustc_session::lint::LintId;
use rustc_session::lint::builtin::{
AMBIGUOUS_GLOB_REEXPORTS, EXPORTED_PRIVATE_DEPENDENCIES, HIDDEN_GLOB_REEXPORTS,
PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_IMPORTS, UNUSED_IMPORTS,
@@ -273,6 +276,8 @@ impl<'ra> ImportData<'ra> {
vis: self.vis,
nearest_parent_mod: self.parent_scope.module.nearest_parent_mod().expect_local(),
is_single: matches!(self.kind, ImportKind::Single { .. }),
priv_macro_use: matches!(self.kind, ImportKind::MacroUse { warn_private: true }),
span: self.span,
}
}
}
@@ -381,9 +386,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
) -> Visibility {
assert!(import.vis.is_accessible_from(import.nearest_parent_mod, self.tcx));
let decl_vis = if min { decl.min_vis() } else { decl.vis() };
if decl_vis.partial_cmp(import.vis, self.tcx) == Some(Ordering::Less)
let ord = decl_vis.partial_cmp(import.vis, self.tcx);
let extern_crate_hack = pub_use_of_private_extern_crate_hack(import, decl).is_some();
if ord == Some(Ordering::Less)
&& decl_vis.is_accessible_from(import.nearest_parent_mod, self.tcx)
&& pub_use_of_private_extern_crate_hack(import, decl).is_none()
&& !extern_crate_hack
{
// Imported declaration is less visible than the import, but is still visible
// from the current module, use the declaration's visibility.
@@ -391,12 +398,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} else {
// Good case - imported declaration is more visible than the import, or the same,
// use the import's visibility.
//
// Bad case - imported declaration is too private for the current module.
// It doesn't matter what visibility we choose here (except in the `PRIVATE_MACRO_USE`
// and `PUB_USE_OF_PRIVATE_EXTERN_CRATE` cases), because either some error will be
// reported, or the import declaration will be thrown away (unfortunately cannot use
// delayed bug here for this reason).
// and `PUB_USE_OF_PRIVATE_EXTERN_CRATE` cases), because an error will be reported.
// Use import visibility to keep the all declaration visibilities in a module ordered.
if !min
&& matches!(ord, None | Some(Ordering::Less))
&& !extern_crate_hack
&& !import.priv_macro_use
{
let msg = format!("cannot extend visibility from {decl_vis:?} to {:?}", import.vis);
self.dcx().span_delayed_bug(import.span, msg);
}
import.vis
}
}
@@ -784,6 +798,29 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let resolution = resolution.borrow();
let Some(binding) = resolution.best_decl() else { continue };
// Report "cannot reexport" errors for exotic cases involving macros 2.0
// privacy bending or invariant-breaking code under deprecation lints.
for decl in [resolution.non_glob_decl, resolution.glob_decl] {
if let Some(decl) = decl
&& let DeclKind::Import { source_decl, import } = decl.kind
{
// The source entity is too private to be reexported
// with the given import declaration's visibility.
let ord = source_decl.vis().partial_cmp(decl.vis(), self.tcx);
if matches!(ord, None | Some(Ordering::Less)) {
let ident = match import.kind {
ImportKind::Single { source, .. } => source,
_ => key.ident.orig(resolution.orig_ident_span),
};
if let Some(lint) =
self.report_cannot_reexport(import, source_decl, ident, key.ns)
{
self.lint_buffer.add_early_lint(lint);
}
}
}
}
if let DeclKind::Import { import, .. } = binding.kind
&& let Some(amb_binding) = binding.ambiguity.get()
&& binding.res() != Res::Err
@@ -1515,76 +1552,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let mut reexport_error = None;
let mut any_successful_reexport = false;
let mut crate_private_reexport = false;
self.per_ns(|this, ns| {
let Some(binding) = bindings[ns].get().decl().map(|b| b.import_source()) else {
let Some(binding) = bindings[ns].get().decl() else {
return;
};
if import.vis.greater_than(binding.vis(), this.tcx) {
reexport_error = Some((ns, binding));
if let Visibility::Restricted(binding_def_id) = binding.vis()
&& binding_def_id.is_top_level_module()
{
crate_private_reexport = true;
}
// In isolation, a declaration like this is not an error, but if *all* 1-3
// declarations introduced by the import are more private than the import item's
// nominal visibility, then it's an error.
reexport_error = Some((ns, binding.import_source()));
} else {
any_successful_reexport = true;
}
});
// All namespaces must be re-exported with extra visibility for an error to occur.
if !any_successful_reexport {
let (ns, binding) = reexport_error.unwrap();
if let Some(extern_crate_id) =
pub_use_of_private_extern_crate_hack(import.summary(), binding)
{
let extern_crate_sp = self.tcx.source_span(self.local_def_id(extern_crate_id));
self.lint_buffer.buffer_lint(
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
import_id,
import.span,
crate::errors::PrivateExternCrateReexport {
ident,
sugg: extern_crate_sp.shrink_to_lo(),
},
);
} else if ns == TypeNS {
let err = if crate_private_reexport {
self.dcx()
.create_err(CannotBeReexportedCratePublicNS { span: import.span, ident })
} else {
self.dcx().create_err(CannotBeReexportedPrivateNS { span: import.span, ident })
};
err.emit();
} else {
let mut err = if crate_private_reexport {
self.dcx()
.create_err(CannotBeReexportedCratePublic { span: import.span, ident })
} else {
self.dcx().create_err(CannotBeReexportedPrivate { span: import.span, ident })
};
match binding.kind {
DeclKind::Def(Res::Def(DefKind::Macro(_), def_id))
// exclude decl_macro
if self.get_macro_by_def_id(def_id).macro_rules =>
{
err.subdiagnostic( ConsiderAddingMacroExport {
span: binding.span,
});
err.subdiagnostic( ConsiderMarkingAsPubCrate {
vis_span: import.vis_span,
});
}
_ => {
err.subdiagnostic( ConsiderMarkingAsPub {
span: import.span,
ident,
});
}
}
err.emit();
if let Some(lint) = self.report_cannot_reexport(import, binding, ident, ns) {
self.lint_buffer.add_early_lint(lint);
}
}
@@ -1613,6 +1599,61 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None
}
fn report_cannot_reexport(
&self,
import: Import<'ra>,
decl: Decl<'ra>,
ident: Ident,
ns: Namespace,
) -> Option<BufferedEarlyLint> {
let crate_private_reexport = match decl.vis() {
Visibility::Restricted(def_id) if def_id.is_top_level_module() => true,
_ => false,
};
if let Some(extern_crate_id) = pub_use_of_private_extern_crate_hack(import.summary(), decl)
{
let ImportKind::Single { id, .. } = import.kind else { unreachable!() };
let sugg = self.tcx.source_span(self.local_def_id(extern_crate_id)).shrink_to_lo();
let diagnostic = crate::errors::PrivateExternCrateReexport { ident, sugg };
return Some(BufferedEarlyLint {
lint_id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE),
node_id: id,
span: Some(import.span.into()),
diagnostic: diagnostic.into(),
});
} else if ns == TypeNS {
let err = if crate_private_reexport {
self.dcx().create_err(CannotBeReexportedCratePublicNS { span: import.span, ident })
} else {
self.dcx().create_err(CannotBeReexportedPrivateNS { span: import.span, ident })
};
err.emit();
} else {
let mut err = if crate_private_reexport {
self.dcx().create_err(CannotBeReexportedCratePublic { span: import.span, ident })
} else {
self.dcx().create_err(CannotBeReexportedPrivate { span: import.span, ident })
};
match decl.kind {
// exclude decl_macro
DeclKind::Def(Res::Def(DefKind::Macro(_), def_id))
if self.get_macro_by_def_id(def_id).macro_rules =>
{
err.subdiagnostic(ConsiderAddingMacroExport { span: decl.span });
err.subdiagnostic(ConsiderMarkingAsPubCrate { vis_span: import.vis_span });
}
_ => {
err.subdiagnostic(ConsiderMarkingAsPub { span: import.span, ident });
}
}
err.emit();
}
None
}
pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> bool {
// This function is only called for single imports.
let ImportKind::Single { source, target, ref decls, id, .. } = import.kind else {
+2
View File
@@ -2750,6 +2750,8 @@ struct ImportSummary {
vis: Visibility,
nearest_parent_mod: LocalDefId,
is_single: bool,
priv_macro_use: bool,
span: Span,
}
/// Invariant: if `Finalize` is used, expansion and import resolution must be complete.
+2
View File
@@ -2269,6 +2269,8 @@ options! {
themselves (default: no)"),
direct_access_external_data: Option<bool> = (None, parse_opt_bool, [TRACKED],
"Direct or use GOT indirect to reference external data symbols"),
disable_fast_paths: bool = (false, parse_bool, [TRACKED],
"disable various performance optimizations in trait solving"),
dual_proc_macros: bool = (false, parse_bool, [TRACKED],
"load proc macros for both target and host, but only link to the target (default: no)"),
dump_dep_graph: bool = (false, parse_bool, [UNTRACKED],
@@ -106,7 +106,6 @@ impl Sleep {
let mut data = self.data.lock().unwrap();
debug_assert!(data.active_threads > 0);
debug_assert!(data.blocked_threads < data.worker_count);
debug_assert!(data.active_threads > 0);
data.active_threads -= 1;
data.blocked_threads += 1;
@@ -779,29 +779,40 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let (lt1, sig1) = get_lifetimes(sig1);
let (lt2, sig2) = get_lifetimes(sig2);
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
let mut values =
(DiagStyledString::normal("".to_string()), DiagStyledString::normal("".to_string()));
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
// ^^^^^^
let safety = |fn_def, sig: ty::FnSig<'_>| match fn_def {
None => sig.safety().prefix_str(),
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^^^^^^^^^^^
let fn_item_prefix_and_safety = |fn_def, sig: ty::FnSig<'_>| match fn_def {
None => ("", sig.safety().prefix_str()),
Some((did, _)) => {
if self.tcx.codegen_fn_attrs(did).safe_target_features {
"#[target_features] "
("#[target_features] ", "")
} else {
sig.safety().prefix_str()
("", sig.safety().prefix_str())
}
}
};
let safety1 = safety(fn_def1, sig1);
let safety2 = safety(fn_def2, sig2);
let (prefix1, safety1) = fn_item_prefix_and_safety(fn_def1, sig1);
let (prefix2, safety2) = fn_item_prefix_and_safety(fn_def2, sig2);
values.0.push(prefix1, prefix1 != prefix2);
values.1.push(prefix2, prefix1 != prefix2);
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^
let lifetime_diff = lt1 != lt2;
values.0.push(lt1, lifetime_diff);
values.1.push(lt2, lifetime_diff);
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^
values.0.push(safety1, safety1 != safety2);
values.1.push(safety2, safety1 != safety2);
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
// ^^^^^^^^^^
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^^^
if sig1.abi() != ExternAbi::Rust {
values.0.push(format!("extern {} ", sig1.abi()), sig1.abi() != sig2.abi());
}
@@ -809,19 +820,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
values.1.push(format!("extern {} ", sig2.abi()), sig1.abi() != sig2.abi());
}
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
// ^^^^^^^^
let lifetime_diff = lt1 != lt2;
values.0.push(lt1, lifetime_diff);
values.1.push(lt2, lifetime_diff);
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
// ^^^
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^
values.0.push_normal("fn(");
values.1.push_normal("fn(");
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
// ^^^^^
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^
let len1 = sig1.inputs().len();
let len2 = sig2.inputs().len();
if len1 == len2 {
@@ -859,13 +864,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
values.1.push("...", !sig1.c_variadic());
}
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
// ^
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^
values.0.push_normal(")");
values.1.push_normal(")");
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
// ^^^^^^^^
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^
let output1 = sig1.output();
let output2 = sig2.output();
let (x1, x2) = self.cmp(output1, output2);
@@ -186,8 +186,9 @@ where
let goal = obligation.as_goal();
let delegate = <&SolverDelegate<'tcx>>::from(infcx);
if let Some(certainty) =
delegate.compute_goal_fast_path(goal, obligation.cause.span)
if !delegate.disable_trait_solver_fast_paths()
&& let Some(certainty) =
delegate.compute_goal_fast_path(goal, obligation.cause.span)
{
match certainty {
// This fast path doesn't depend on region identity so it doesn't
@@ -325,6 +325,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
/// compile-time benchmarks are very sensitive to even small changes.
#[inline(always)]
fn needs_process_obligation(&self, pending_obligation: &Self::Obligation) -> bool {
if self.selcx.infcx.disable_trait_solver_fast_paths() {
return true;
}
// If we were stalled on some unresolved variables, first check whether
// any of them have been resolved; if not, don't bother doing more work
// yet.
@@ -388,7 +392,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
let infcx = self.selcx.infcx;
if sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env) {
if !infcx.disable_trait_solver_fast_paths()
&& sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env)
{
return ProcessResult::Changed(thin_vec![]);
}
@@ -110,7 +110,9 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
),
NoSolution,
> {
if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) {
if !infcx.disable_trait_solver_fast_paths()
&& let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key)
{
return Ok((result, None, PredicateObligations::new(), Certainty::Proven));
}
@@ -159,7 +161,9 @@ where
"query type op",
span,
|ocx| {
if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &self) {
if !infcx.disable_trait_solver_fast_paths()
&& let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &self)
{
return Ok(result);
}
QueryTypeOp::perform_locally_with_next_solver(ocx, self, span)
@@ -604,7 +604,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
None => self.check_recursion_limit(&obligation, &obligation)?,
}
if sizedness_fast_path(self.tcx(), obligation.predicate, obligation.param_env) {
if !self.infcx.disable_trait_solver_fast_paths()
&& sizedness_fast_path(self.tcx(), obligation.predicate, obligation.param_env)
{
return Ok(EvaluatedToOk);
}
@@ -24,7 +24,7 @@ fn evaluate_obligation<'tcx>(
debug!("evaluate_obligation: goal={:#?}", goal);
let ParamEnvAnd { param_env, value: predicate } = goal;
if sizedness_fast_path(tcx, predicate, param_env) {
if !tcx.disable_trait_solver_fast_paths() && sizedness_fast_path(tcx, predicate, param_env) {
return Ok(EvaluationResult::EvaluatedToOk);
}
+2
View File
@@ -230,6 +230,8 @@ pub trait InferCtxtLike: Sized {
true
}
fn disable_trait_solver_fast_paths(&self) -> bool;
fn typing_mode(&self) -> TypingMode<Self::Interner>;
fn universe(&self) -> ty::UniverseIndex;
+2
View File
@@ -108,6 +108,7 @@
#![feature(const_heap)]
#![feature(const_index)]
#![feature(const_option_ops)]
#![feature(const_result_trait_fn)]
#![feature(const_try)]
#![feature(copied_into_inner)]
#![feature(core_intrinsics)]
@@ -173,6 +174,7 @@
#![feature(allocator_internals)]
#![feature(allow_internal_unstable)]
#![feature(cfg_sanitize)]
#![feature(const_closures)]
#![feature(const_precise_live_drops)]
#![feature(const_trait_impl)]
#![feature(coroutine_trait)]
+1 -5
View File
@@ -898,9 +898,5 @@ const fn layout_array(cap: usize, elem_layout: Layout) -> Result<Layout, TryRese
// which lets us use the much-simpler `repeat_packed`.
debug_assert!(elem_layout.size() == elem_layout.pad_to_align().size());
// FIXME(const-hack) return to using `map` and `map_err` once `const_closures` is implemented
match elem_layout.repeat_packed(cap) {
Ok(layout) => Ok(layout),
Err(_) => Err(CapacityOverflow.into()),
}
elem_layout.repeat_packed(cap).map_err(const |_| CapacityOverflow.into())
}
+2
View File
@@ -23,6 +23,7 @@
#![feature(const_destruct)]
#![feature(const_heap)]
#![feature(const_option_ops)]
#![feature(const_result_trait_fn)]
#![feature(const_try)]
#![feature(copied_into_inner)]
#![feature(core_intrinsics)]
@@ -54,6 +55,7 @@
//
// Language features:
// tidy-alphabetical-start
#![feature(const_closures)]
#![feature(const_trait_impl)]
#![feature(dropck_eyepatch)]
#![feature(min_specialization)]
+5 -7
View File
@@ -226,13 +226,11 @@ pub const trait Iterator {
Self: Sized + [const] Destruct,
Self::Item: [const] Destruct,
{
// FIXME(const-hack): revert this to a const closure
#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
#[rustc_inherit_overflow_checks]
const fn plus_one<T: [const] Destruct>(accum: usize, _elem: T) -> usize {
accum + 1
}
self.fold(0, plus_one)
self.fold(
0,
#[rustc_inherit_overflow_checks]
const |accum, _elem| accum + 1,
)
}
/// Consumes the iterator, returning the last element.
+1
View File
@@ -125,6 +125,7 @@
#![feature(cfg_target_has_atomic)]
#![feature(cfg_target_has_atomic_equal_alignment)]
#![feature(cfg_ub_checks)]
#![feature(const_closures)]
#![feature(const_precise_live_drops)]
#![feature(const_trait_impl)]
#![feature(decl_macro)]
+7 -23
View File
@@ -1,4 +1,4 @@
use crate::marker::{Destruct, PhantomData};
use crate::marker::Destruct;
use crate::ops::ControlFlow;
/// The `?` operator and `try {}` blocks.
@@ -398,25 +398,6 @@ pub(crate) type ChangeOutputType<T: Try<Residual: Residual<V>>, V> =
/// Not currently planned to be exposed publicly, so just `pub(crate)`.
#[repr(transparent)]
pub(crate) struct NeverShortCircuit<T>(pub T);
// FIXME(const-hack): replace with `|a| NeverShortCircuit(f(a))` when const closures added.
pub(crate) struct Wrapped<T, A, F: FnMut(A) -> T> {
f: F,
p: PhantomData<(T, A)>,
}
#[rustc_const_unstable(feature = "const_never_short_circuit", issue = "none")]
impl<T, A, F: [const] FnMut(A) -> T + [const] Destruct> const FnOnce<(A,)> for Wrapped<T, A, F> {
type Output = NeverShortCircuit<T>;
extern "rust-call" fn call_once(mut self, args: (A,)) -> Self::Output {
self.call_mut(args)
}
}
#[rustc_const_unstable(feature = "const_never_short_circuit", issue = "none")]
impl<T, A, F: [const] FnMut(A) -> T> const FnMut<(A,)> for Wrapped<T, A, F> {
extern "rust-call" fn call_mut(&mut self, (args,): (A,)) -> Self::Output {
NeverShortCircuit((self.f)(args))
}
}
impl<T> NeverShortCircuit<T> {
/// Wraps a unary function to produce one that wraps the output into a `NeverShortCircuit`.
@@ -424,11 +405,14 @@ impl<T> NeverShortCircuit<T> {
/// This is useful for implementing infallible functions in terms of the `try_` ones,
/// without accidentally capturing extra generic parameters in a closure.
#[inline]
pub(crate) const fn wrap_mut_1<A, F>(f: F) -> Wrapped<T, A, F>
#[rustc_const_unstable(feature = "const_array", issue = "147606")]
pub(crate) const fn wrap_mut_1<A, F>(
mut f: F,
) -> impl [const] FnMut(A) -> Self + [const] Destruct
where
F: [const] FnMut(A) -> T,
F: [const] FnMut(A) -> T + [const] Destruct,
{
Wrapped { f, p: PhantomData }
const move |a| NeverShortCircuit(f(a))
}
#[inline]
+10 -27
View File
@@ -3,7 +3,6 @@
use super::{from_raw_parts, memchr};
use crate::ascii;
use crate::cmp::{self, BytewiseEq, Ordering};
use crate::convert::Infallible;
use crate::intrinsics::compare_bytes;
use crate::marker::Destruct;
use crate::mem::SizedTypeProperties;
@@ -182,20 +181,12 @@ type AlwaysBreak<B> = ControlFlow<B, crate::convert::Infallible>;
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: [const] PartialOrd> const SlicePartialOrd for A {
default fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> {
// FIXME(const-hack): revert this to a const closure once possible
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
const fn elem_chain<A: [const] PartialOrd>(a: &A, b: &A) -> ControlFlow<Option<Ordering>> {
match PartialOrd::partial_cmp(a, b) {
Some(Ordering::Equal) => ControlFlow::Continue(()),
non_eq => ControlFlow::Break(non_eq),
}
}
let elem_chain = const |a, b| match PartialOrd::partial_cmp(a, b) {
Some(Ordering::Equal) => ControlFlow::Continue(()),
non_eq => ControlFlow::Break(non_eq),
};
// FIXME(const-hack): revert this to a const closure once possible
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
const fn len_chain(a: &usize, b: &usize) -> ControlFlow<Option<Ordering>, Infallible> {
ControlFlow::Break(usize::partial_cmp(a, b))
}
let len_chain = const |a: &_, b: &_| ControlFlow::Break(usize::partial_cmp(a, b));
let AlwaysBreak::Break(b) = chaining_impl(left, right, elem_chain, len_chain);
b
@@ -293,20 +284,12 @@ const trait SliceOrd: Sized {
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: [const] Ord> const SliceOrd for A {
default fn compare(left: &[Self], right: &[Self]) -> Ordering {
// FIXME(const-hack): revert this to a const closure once possible
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
const fn elem_chain<A: [const] Ord>(a: &A, b: &A) -> ControlFlow<Ordering> {
match Ord::cmp(a, b) {
Ordering::Equal => ControlFlow::Continue(()),
non_eq => ControlFlow::Break(non_eq),
}
}
let elem_chain = const |a, b| match Ord::cmp(a, b) {
Ordering::Equal => ControlFlow::Continue(()),
non_eq => ControlFlow::Break(non_eq),
};
// FIXME(const-hack): revert this to a const closure once possible
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
const fn len_chain(a: &usize, b: &usize) -> ControlFlow<Ordering, Infallible> {
ControlFlow::Break(usize::cmp(a, b))
}
let len_chain = const |a: &_, b: &_| ControlFlow::Break(usize::cmp(a, b));
let AlwaysBreak::Break(b) = chaining_impl(left, right, elem_chain, len_chain);
b
@@ -22,6 +22,7 @@ pub static CRATES: &[&str] = &[
"fnv",
"foldhash",
"generic-array",
"glob",
"hashbrown",
"heck",
"ident_case",
+1 -1
View File
@@ -5,7 +5,7 @@ edition = "2024"
[dependencies]
anyhow = "1"
askama = "0.15.4"
askama = "0.16.0"
clap = { version = "4.5", features = ["derive"] }
csv = "1"
diff = "0.1"
+1 -1
View File
@@ -10,7 +10,7 @@ path = "lib.rs"
[dependencies]
# tidy-alphabetical-start
arrayvec = { version = "0.7", default-features = false }
askama = { version = "0.15.4", default-features = false, features = ["alloc", "config", "derive"] }
askama = { version = "0.16.0", default-features = false, features = ["alloc", "config", "derive"] }
base64 = "0.21.7"
indexmap = { version = "2", features = ["serde"] }
itertools = "0.12"
+1 -1
View File
@@ -42,7 +42,7 @@ walkdir = "2.3"
filetime = "0.2.9"
itertools = "0.12"
pulldown-cmark = { version = "0.11", default-features = false, features = ["html"] }
askama = { version = "0.15.4", default-features = false, features = ["alloc", "config", "derive"] }
askama = { version = "0.16.0", default-features = false, features = ["alloc", "config", "derive"] }
[dev-dependencies.toml]
version = "0.9.7"
+1 -1
View File
@@ -8,7 +8,7 @@ description = "Produces a manifest of all the copyrighted materials in the Rust
[dependencies]
anyhow = "1.0.65"
askama = "0.15.4"
askama = "0.16.0"
cargo_metadata = "0.21"
serde = { version = "1.0.147", features = ["derive"] }
serde_json = "1.0.85"
@@ -16,6 +16,7 @@ extern crate rustc_parse_format;
extern crate ra_ap_rustc_parse_format as rustc_parse_format;
extern crate ra_ap_rustc_abi as rustc_abi;
pub extern crate ra_ap_rustc_abi as layout;
pub mod db;
@@ -47,7 +48,6 @@ pub mod import_map;
pub mod visibility;
use intern::{Interned, Symbol};
pub use rustc_abi as layout;
use thin_vec::ThinVec;
pub use crate::signatures::LocalFieldId;
+1
View File
@@ -8,6 +8,7 @@ mod foo {
pub macro m() {
use f as g; //~ ERROR `f` is private, and cannot be re-exported
//~| ERROR `f` is private, and cannot be re-exported
f!();
}
}
+21 -1
View File
@@ -17,6 +17,26 @@ LL | foo::m!();
| --------- in this macro invocation
= note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 1 previous error
error[E0364]: `f` is private, and cannot be re-exported
--> $DIR/privacy-early.rs:10:13
|
LL | use f as g;
| ^^^^^^
...
LL | foo::m!();
| --------- in this macro invocation
|
note: consider marking `f` as `pub` in the imported module
--> $DIR/privacy-early.rs:10:13
|
LL | use f as g;
| ^^^^^^
...
LL | foo::m!();
| --------- in this macro invocation
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
= note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0364`.
@@ -1,5 +1,24 @@
error[E0364]: `S` is private, and cannot be re-exported
--> $DIR/private-from-decl-macro.rs:18:13
|
LL | use crate::m::*;
| ^^^^^^^^^^^
...
LL | crate::m::mac_glob!();
| --------------------- in this macro invocation
|
note: consider marking `S` as `pub` in the imported module
--> $DIR/private-from-decl-macro.rs:18:13
|
LL | use crate::m::*;
| ^^^^^^^^^^^
...
LL | crate::m::mac_glob!();
| --------------------- in this macro invocation
= note: this error originates in the macro `crate::m::mac_glob` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0423]: expected value, found struct `S`
--> $DIR/private-from-decl-macro.rs:27:17
--> $DIR/private-from-decl-macro.rs:28:17
|
LL | pub struct S {}
| --------------- `S` defined here
@@ -22,6 +41,7 @@ LL - let s = S;
LL + let s = s;
|
error: aborting due to 1 previous error
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0423`.
Some errors have detailed explanations: E0364, E0423.
For more information about an error, try `rustc --explain E0364`.
+2 -1
View File
@@ -14,7 +14,8 @@ mod m {
}
pub macro mac_glob() {
use crate::m::*;
#[cfg(fail)]
use crate::m::*; //[fail]~ ERROR `S` is private, and cannot be re-exported
}
}
@@ -0,0 +1,4 @@
#[macro_export]
macro_rules! outer {
($inner:ident) => { $inner![1, 2, 3]; };
}
+15
View File
@@ -0,0 +1,15 @@
//! Regression test for https://github.com/rust-lang/rust/issues/156084.
//! This test can probably be removed again once
//! `semicolon_in_expressions_from_macros` is a hard error.
//@ check-pass
//@ aux-build:semicolon-in-exprs.rs
//@ edition: 2021
extern crate semicolon_in_exprs;
macro_rules! inner {
[$($x:expr),*] => { [$($x),*] };
}
fn main() {
let _v: Vec<i32> = semicolon_in_exprs::outer!(inner).into_iter().collect();
}
@@ -10,7 +10,19 @@ fn foo(x: i32) -> u32 {
0
}
extern "C" fn extern_foo(_: &i32) {}
unsafe extern "C" fn unsafe_extern_foo(_: &i32) {}
fn rust_foo(_: &i32) {}
fn main() {
let b: fn() -> u32 = bar; //~ ERROR mismatched types [E0308]
let f: fn(i32) = foo; //~ ERROR mismatched types [E0308]
// See https://github.com/rust-lang/rust/issues/151393
let _: for<'a> fn(&'a i32) = extern_foo; //~ ERROR mismatched types [E0308]
let _: for<'a> fn(&'a i32) = unsafe_extern_foo; //~ ERROR mismatched types [E0308]
let _: for<'a> extern "C" fn(&'a i32) = rust_foo; //~ ERROR mismatched types [E0308]
let _: for<'a> unsafe extern "C" fn(&'a i32) = rust_foo; //~ ERROR mismatched types [E0308]
}
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch-diagnostics.rs:14:26
--> $DIR/fn-pointer-mismatch-diagnostics.rs:20:26
|
LL | let b: fn() -> u32 = bar;
| ----------- ^^^ expected fn pointer, found fn item
@@ -10,7 +10,7 @@ LL | let b: fn() -> u32 = bar;
found fn item `fn() -> () {bar}`
error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch-diagnostics.rs:15:22
--> $DIR/fn-pointer-mismatch-diagnostics.rs:21:22
|
LL | let f: fn(i32) = foo;
| ------- ^^^ expected fn pointer, found fn item
@@ -20,6 +20,51 @@ LL | let f: fn(i32) = foo;
= note: expected fn pointer `fn(_) -> ()`
found fn item `fn(_) -> u32 {foo}`
error: aborting due to 2 previous errors
error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch-diagnostics.rs:24:34
|
LL | let _: for<'a> fn(&'a i32) = extern_foo;
| ------------------- ^^^^^^^^^^ expected "Rust" fn, found "C" fn
| |
| expected due to this
|
= note: expected fn pointer `for<'a> fn(&'a _)`
found fn item `for<'a> extern "C" fn(&'a _) {extern_foo}`
error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch-diagnostics.rs:25:34
|
LL | let _: for<'a> fn(&'a i32) = unsafe_extern_foo;
| ------------------- ^^^^^^^^^^^^^^^^^ expected safe fn, found unsafe fn
| |
| expected due to this
|
= note: expected fn pointer `for<'a> fn(&'a _)`
found fn item `for<'a> unsafe extern "C" fn(&'a _) {unsafe_extern_foo}`
= note: unsafe functions cannot be coerced into safe function pointers
error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch-diagnostics.rs:26:45
|
LL | let _: for<'a> extern "C" fn(&'a i32) = rust_foo;
| ------------------------------ ^^^^^^^^ expected "C" fn, found "Rust" fn
| |
| expected due to this
|
= note: expected fn pointer `for<'a> extern "C" fn(&'a _)`
found fn item `for<'a> fn(&'a _) {rust_foo}`
error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch-diagnostics.rs:27:52
|
LL | let _: for<'a> unsafe extern "C" fn(&'a i32) = rust_foo;
| ------------------------------------- ^^^^^^^^ expected "C" fn, found "Rust" fn
| |
| expected due to this
|
= note: expected fn pointer `for<'a> unsafe extern "C" fn(&'a _)`
found fn item `for<'a> fn(&'a _) {rust_foo}`
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0308`.