mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-06 08:36:52 -04:00
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:
+14
-10
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 { .. } => {
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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!();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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]; };
|
||||
}
|
||||
@@ -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`.
|
||||
|
||||
Reference in New Issue
Block a user