diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs
index 4d70afd4e0b..55f4845d216 100644
--- a/compiler/rustc_abi/src/extern_abi.rs
+++ b/compiler/rustc_abi/src/extern_abi.rs
@@ -60,7 +60,6 @@ pub enum ExternAbi {
System {
unwind: bool,
},
- RustIntrinsic,
RustCall,
/// *Not* a stable ABI, just directly use the Rust types to describe the ABI for LLVM. Even
/// normally ABI-compatible Rust types can become ABI-incompatible with this ABI!
@@ -128,7 +127,6 @@ abi_impls! {
RiscvInterruptS =><= "riscv-interrupt-s",
RustCall =><= "rust-call",
RustCold =><= "rust-cold",
- RustIntrinsic =><= "rust-intrinsic",
Stdcall { unwind: false } =><= "stdcall",
Stdcall { unwind: true } =><= "stdcall-unwind",
System { unwind: false } =><= "system",
@@ -199,7 +197,7 @@ impl ExternAbi {
/// - are subject to change between compiler versions
pub fn is_rustic_abi(self) -> bool {
use ExternAbi::*;
- matches!(self, Rust | RustCall | RustIntrinsic | RustCold)
+ matches!(self, Rust | RustCall | RustCold)
}
pub fn supports_varargs(self) -> bool {
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 97e6879c33e..3fb88c9599d 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -563,6 +563,7 @@ impl Pat {
/// This is intended for use by diagnostics.
pub fn to_ty(&self) -> Option
> {
let kind = match &self.kind {
+ PatKind::Missing => unreachable!(),
// In a type expression `_` is an inference variable.
PatKind::Wild => TyKind::Infer,
// An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`.
@@ -625,7 +626,8 @@ impl Pat {
| PatKind::Guard(s, _) => s.walk(it),
// These patterns do not contain subpatterns, skip.
- PatKind::Wild
+ PatKind::Missing
+ | PatKind::Wild
| PatKind::Rest
| PatKind::Never
| PatKind::Expr(_)
@@ -676,6 +678,7 @@ impl Pat {
/// Return a name suitable for diagnostics.
pub fn descr(&self) -> Option {
match &self.kind {
+ PatKind::Missing => unreachable!(),
PatKind::Wild => Some("_".to_string()),
PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
@@ -769,6 +772,9 @@ pub enum RangeSyntax {
// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum PatKind {
+ /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
+ Missing,
+
/// Represents a wildcard pattern (`_`).
Wild,
@@ -1169,6 +1175,7 @@ pub enum MacStmtStyle {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Local {
pub id: NodeId,
+ pub super_: Option,
pub pat: P,
pub ty: Option>,
pub kind: LocalKind,
@@ -3926,7 +3933,7 @@ mod size_asserts {
static_assert_size!(Item, 144);
static_assert_size!(ItemKind, 80);
static_assert_size!(LitKind, 24);
- static_assert_size!(Local, 80);
+ static_assert_size!(Local, 96);
static_assert_size!(MetaItemLit, 40);
static_assert_size!(Param, 40);
static_assert_size!(Pat, 72);
diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs
index f01c781f46c..13a7c5a1805 100644
--- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs
+++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs
@@ -92,6 +92,12 @@ pub struct AutoDiffAttrs {
pub input_activity: Vec,
}
+impl AutoDiffAttrs {
+ pub fn has_primal_ret(&self) -> bool {
+ matches!(self.ret_activity, DiffActivity::Active | DiffActivity::Dual)
+ }
+}
+
impl DiffMode {
pub fn is_rev(&self) -> bool {
matches!(self, DiffMode::Reverse)
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index f7d13acdfc4..b083e878905 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -704,7 +704,8 @@ fn walk_parenthesized_parameter_data(vis: &mut T, args: &mut Pare
}
fn walk_local(vis: &mut T, local: &mut P) {
- let Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local.deref_mut();
+ let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens } = local.deref_mut();
+ visit_opt(super_, |sp| vis.visit_span(sp));
vis.visit_id(id);
visit_attrs(vis, attrs);
vis.visit_pat(pat);
@@ -1587,7 +1588,7 @@ pub fn walk_pat(vis: &mut T, pat: &mut P) {
vis.visit_id(id);
match kind {
PatKind::Err(_guar) => {}
- PatKind::Wild | PatKind::Rest | PatKind::Never => {}
+ PatKind::Missing | PatKind::Wild | PatKind::Rest | PatKind::Never => {}
PatKind::Ident(_binding_mode, ident, sub) => {
vis.visit_ident(ident);
visit_opt(sub, |sub| vis.visit_pat(sub));
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 1ef92ff8898..79193fcec63 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -323,7 +323,7 @@ pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::R
}
pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::Result {
- let Local { id: _, pat, ty, kind, span: _, colon_sp: _, attrs, tokens: _ } = local;
+ let Local { id: _, super_: _, pat, ty, kind, span: _, colon_sp: _, attrs, tokens: _ } = local;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_pat(pat));
visit_opt!(visitor, visit_ty, ty);
@@ -750,7 +750,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Res
try_visit!(visitor.visit_pat(subpattern));
try_visit!(visitor.visit_expr(guard_condition));
}
- PatKind::Wild | PatKind::Rest | PatKind::Never => {}
+ PatKind::Missing | PatKind::Wild | PatKind::Rest | PatKind::Never => {}
PatKind::Err(_guar) => {}
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
walk_list!(visitor, visit_pat, elems);
diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs
index 1d9ca6bb9c8..c3222b79e55 100644
--- a/compiler/rustc_ast_lowering/src/block.rs
+++ b/compiler/rustc_ast_lowering/src/block.rs
@@ -95,6 +95,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_local(&mut self, l: &Local) -> &'hir hir::LetStmt<'hir> {
// Let statements are allowed to have impl trait in bindings.
+ let super_ = l.super_;
let ty = l.ty.as_ref().map(|t| {
self.lower_ty(t, self.impl_trait_in_bindings_ctxt(ImplTraitPosition::Variable))
});
@@ -109,7 +110,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let span = self.lower_span(l.span);
let source = hir::LocalSource::Normal;
self.lower_attrs(hir_id, &l.attrs, l.span);
- self.arena.alloc(hir::LetStmt { hir_id, ty, pat, init, els, span, source })
+ self.arena.alloc(hir::LetStmt { hir_id, super_, ty, pat, init, els, span, source })
}
fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index d5d6dcd8d63..6aa6a18ee9a 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1496,18 +1496,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Option] {
self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
- PatKind::Ident(_, ident, _) => {
- if ident.name != kw::Empty {
- Some(self.lower_ident(ident))
- } else {
- None
- }
- }
+ PatKind::Missing => None,
+ PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
_ => {
self.dcx().span_delayed_bug(
param.pat.span,
- "non-ident/wild param pat must trigger an error",
+ "non-missing/ident/wild param pat must trigger an error",
);
None
}
@@ -2223,6 +2218,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.attrs.insert(hir_id.local_id, a);
}
let local = hir::LetStmt {
+ super_: None,
hir_id,
init,
pat,
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 07cc64a1358..f94d788a9b0 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -26,6 +26,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let pat_hir_id = self.lower_node_id(pattern.id);
let node = loop {
match &pattern.kind {
+ PatKind::Missing => break hir::PatKind::Missing,
PatKind::Wild => break hir::PatKind::Wild,
PatKind::Never => break hir::PatKind::Never,
PatKind::Ident(binding_mode, ident, sub) => {
diff --git a/compiler/rustc_ast_lowering/src/stability.rs b/compiler/rustc_ast_lowering/src/stability.rs
index a2004bbb39f..eb052ba1c6d 100644
--- a/compiler/rustc_ast_lowering/src/stability.rs
+++ b/compiler/rustc_ast_lowering/src/stability.rs
@@ -79,10 +79,6 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> {
| ExternAbi::SysV64 { .. }
| ExternAbi::System { .. }
| ExternAbi::EfiApi => Ok(()),
- // implementation details
- ExternAbi::RustIntrinsic => {
- Err(UnstableAbi { abi, feature: sym::intrinsics, explain: GateReason::ImplDetail })
- }
ExternAbi::Unadjusted => {
Err(UnstableAbi { abi, feature: sym::abi_unadjusted, explain: GateReason::ImplDetail })
}
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 9916de8b7b1..dc77e7b2834 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -244,7 +244,7 @@ impl<'a> AstValidator<'a> {
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option, bool)) {
for Param { pat, .. } in &decl.inputs {
match pat.kind {
- PatKind::Ident(BindingMode::NONE, _, None) | PatKind::Wild => {}
+ PatKind::Missing | PatKind::Ident(BindingMode::NONE, _, None) | PatKind::Wild => {}
PatKind::Ident(BindingMode::MUT, ident, None) => {
report_err(pat.span, Some(ident), true)
}
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 3dbfc191f8f..90caad1c845 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1336,6 +1336,9 @@ impl<'a> State<'a> {
self.print_outer_attributes(&loc.attrs);
self.space_if_not_bol();
self.ibox(INDENT_UNIT);
+ if loc.super_.is_some() {
+ self.word_nbsp("super");
+ }
self.word_nbsp("let");
self.ibox(INDENT_UNIT);
@@ -1622,9 +1625,9 @@ impl<'a> State<'a> {
fn print_pat(&mut self, pat: &ast::Pat) {
self.maybe_print_comment(pat.span.lo());
self.ann.pre(self, AnnNode::Pat(pat));
- /* Pat isn't normalized, but the beauty of it
- is that it doesn't matter */
+ /* Pat isn't normalized, but the beauty of it is that it doesn't matter */
match &pat.kind {
+ PatKind::Missing => unreachable!(),
PatKind::Wild => self.word("_"),
PatKind::Never => self.word("!"),
PatKind::Ident(BindingMode(by_ref, mutbl), ident, sub) => {
@@ -1946,12 +1949,7 @@ impl<'a> State<'a> {
if let Some(eself) = input.to_self() {
self.print_explicit_self(&eself);
} else {
- let invalid = if let PatKind::Ident(_, ident, _) = input.pat.kind {
- ident.name == kw::Empty
- } else {
- false
- };
- if !invalid {
+ if !matches!(input.pat.kind, PatKind::Missing) {
self.print_pat(&input.pat);
self.word(":");
self.space();
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index a80d74d9e37..5756a5e7c7c 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex,
use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::{DUMMY_SP, Span};
-use tracing::{debug, instrument, trace};
+use tracing::{Level, debug, enabled, instrument, trace};
use crate::BorrowckInferCtxt;
use crate::constraints::graph::{self, NormalConstraintGraph, RegionGraph};
@@ -327,11 +327,13 @@ fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: &ConstraintSccs) {
let mut var_to_origin_sorted = var_to_origin.clone().into_iter().collect::>();
var_to_origin_sorted.sort_by_key(|vto| vto.0);
- let mut reg_vars_to_origins_str = "region variables to origins:\n".to_string();
- for (reg_var, origin) in var_to_origin_sorted.into_iter() {
- reg_vars_to_origins_str.push_str(&format!("{reg_var:?}: {origin:?}\n"));
+ if enabled!(Level::DEBUG) {
+ let mut reg_vars_to_origins_str = "region variables to origins:\n".to_string();
+ for (reg_var, origin) in var_to_origin_sorted.into_iter() {
+ reg_vars_to_origins_str.push_str(&format!("{reg_var:?}: {origin:?}\n"));
+ }
+ debug!("{}", reg_vars_to_origins_str);
}
- debug!("{}", reg_vars_to_origins_str);
let num_components = sccs.num_sccs();
let mut components = vec![FxIndexSet::default(); num_components];
@@ -342,16 +344,18 @@ fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: &ConstraintSccs) {
components[scc_idx.as_usize()].insert((reg_var, *origin));
}
- let mut components_str = "strongly connected components:".to_string();
- for (scc_idx, reg_vars_origins) in components.iter().enumerate() {
- let regions_info = reg_vars_origins.clone().into_iter().collect::>();
- components_str.push_str(&format!(
- "{:?}: {:?},\n)",
- ConstraintSccIndex::from_usize(scc_idx),
- regions_info,
- ))
+ if enabled!(Level::DEBUG) {
+ let mut components_str = "strongly connected components:".to_string();
+ for (scc_idx, reg_vars_origins) in components.iter().enumerate() {
+ let regions_info = reg_vars_origins.clone().into_iter().collect::>();
+ components_str.push_str(&format!(
+ "{:?}: {:?},\n)",
+ ConstraintSccIndex::from_usize(scc_idx),
+ regions_info,
+ ))
+ }
+ debug!("{}", components_str);
}
- debug!("{}", components_str);
// calculate the best representative for each component
let components_representatives = components
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 75f3a3c1972..d3f47ad7263 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -1,5 +1,4 @@
-//! Codegen of intrinsics. This includes `extern "rust-intrinsic"`,
-//! functions marked with the `#[rustc_intrinsic]` attribute
+//! Codegen of intrinsics. This includes functions marked with the `#[rustc_intrinsic]` attribute
//! and LLVM intrinsics that have symbol names starting with `llvm.`.
macro_rules! intrinsic_args {
diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
index 7d264ba4d00..5e7ef27143b 100644
--- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
+++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
@@ -201,7 +201,23 @@ fn compute_enzyme_fn_ty<'ll>(
}
if attrs.width == 1 {
- todo!("Handle sret for scalar ad");
+ // Enzyme returns a struct of style:
+ // `{ original_ret(if requested), float, float, ... }`
+ let mut struct_elements = vec![];
+ if attrs.has_primal_ret() {
+ struct_elements.push(inner_ret_ty);
+ }
+ // Next, we push the list of active floats, since they will be lowered to `enzyme_out`,
+ // and therefore part of the return struct.
+ let param_tys = cx.func_params_types(fn_ty);
+ for (act, param_ty) in attrs.input_activity.iter().zip(param_tys) {
+ if matches!(act, DiffActivity::Active) {
+ // Now find the float type at position i based on the fn_ty,
+ // to know what (f16/f32/f64/...) to add to the struct.
+ struct_elements.push(param_ty);
+ }
+ }
+ ret_ty = cx.type_struct(&struct_elements, false);
} else {
// First we check if we also have to deal with the primal return.
match attrs.mode {
@@ -388,7 +404,11 @@ fn generate_enzyme_call<'ll>(
// now store the result of the enzyme call into the sret pointer.
let sret_ptr = outer_args[0];
let call_ty = cx.val_ty(call);
- assert_eq!(cx.type_kind(call_ty), TypeKind::Array);
+ if attrs.width == 1 {
+ assert_eq!(cx.type_kind(call_ty), TypeKind::Struct);
+ } else {
+ assert_eq!(cx.type_kind(call_ty), TypeKind::Array);
+ }
llvm::LLVMBuildStore(&builder.llbuilder, call, sret_ptr);
}
builder.ret_void();
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 5e62ce285dd..55b1e728b70 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -53,13 +53,6 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
None => return,
};
- // The order of entries in this global file table needs to be deterministic,
- // and ideally should also be independent of the details of stable-hashing,
- // because coverage tests snapshots (`.cov-map`) can observe the order and
- // would need to be re-blessed if it changes. As long as those requirements
- // are satisfied, the order can be arbitrary.
- let mut global_file_table = GlobalFileTable::new();
-
let mut covfun_records = instances_used
.iter()
.copied()
@@ -67,17 +60,13 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
// order that doesn't depend on the stable-hash-based order in which
// instances were visited during codegen.
.sorted_by_cached_key(|&instance| tcx.symbol_name(instance).name)
- .filter_map(|instance| prepare_covfun_record(tcx, &mut global_file_table, instance, true))
+ .filter_map(|instance| prepare_covfun_record(tcx, instance, true))
.collect::>();
// In a single designated CGU, also prepare covfun records for functions
// in this crate that were instrumented for coverage, but are unused.
if cx.codegen_unit.is_code_coverage_dead_code_cgu() {
- unused::prepare_covfun_records_for_unused_functions(
- cx,
- &mut global_file_table,
- &mut covfun_records,
- );
+ unused::prepare_covfun_records_for_unused_functions(cx, &mut covfun_records);
}
// If there are no covfun records for this CGU, don't generate a covmap record.
@@ -89,68 +78,88 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
return;
}
- // Encode all filenames referenced by coverage mappings in this CGU.
- let filenames_buffer = global_file_table.make_filenames_buffer(tcx);
- // The `llvm-cov` tool uses this hash to associate each covfun record with
- // its corresponding filenames table, since the final binary will typically
- // contain multiple covmap records from different compilation units.
- let filenames_hash = llvm_cov::hash_bytes(&filenames_buffer);
+ // Prepare the global file table for this CGU, containing all paths needed
+ // by one or more covfun records.
+ let global_file_table =
+ GlobalFileTable::build(tcx, covfun_records.iter().flat_map(|c| c.all_source_files()));
for covfun in &covfun_records {
- covfun::generate_covfun_record(cx, filenames_hash, covfun)
+ covfun::generate_covfun_record(cx, &global_file_table, covfun)
}
// Generate the coverage map header, which contains the filenames used by
// this CGU's coverage mappings, and store it in a well-known global.
// (This is skipped if we returned early due to having no covfun records.)
- generate_covmap_record(cx, covmap_version, &filenames_buffer);
+ generate_covmap_record(cx, covmap_version, &global_file_table.filenames_buffer);
}
-/// Maps "global" (per-CGU) file ID numbers to their underlying source files.
+/// Maps "global" (per-CGU) file ID numbers to their underlying source file paths.
+#[derive(Debug)]
struct GlobalFileTable {
/// This "raw" table doesn't include the working dir, so a file's
/// global ID is its index in this set **plus one**.
- raw_file_table: FxIndexMap>,
+ raw_file_table: FxIndexMap,
+
+ /// The file table in encoded form (possibly compressed), which can be
+ /// included directly in this CGU's `__llvm_covmap` record.
+ filenames_buffer: Vec,
+
+ /// Truncated hash of the bytes in `filenames_buffer`.
+ ///
+ /// The `llvm-cov` tool uses this hash to associate each covfun record with
+ /// its corresponding filenames table, since the final binary will typically
+ /// contain multiple covmap records from different compilation units.
+ filenames_hash: u64,
}
impl GlobalFileTable {
- fn new() -> Self {
- Self { raw_file_table: FxIndexMap::default() }
- }
+ /// Builds a "global file table" for this CGU, mapping numeric IDs to
+ /// path strings.
+ fn build<'a>(tcx: TyCtxt<'_>, all_files: impl Iterator- ) -> Self {
+ let mut raw_file_table = FxIndexMap::default();
- fn global_file_id_for_file(&mut self, file: &Arc
) -> GlobalFileId {
- // Ensure the given file has a table entry, and get its index.
- let entry = self.raw_file_table.entry(file.stable_id);
- let raw_id = entry.index();
- entry.or_insert_with(|| Arc::clone(file));
+ for file in all_files {
+ raw_file_table.entry(file.stable_id).or_insert_with(|| {
+ file.name
+ .for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
+ .to_string_lossy()
+ .into_owned()
+ });
+ }
- // The raw file table doesn't include an entry for the working dir
- // (which has ID 0), so add 1 to get the correct ID.
- GlobalFileId::from_usize(raw_id + 1)
- }
+ // FIXME(Zalathar): Consider sorting the file table here, but maybe
+ // only after adding filename support to coverage-dump, so that the
+ // table order isn't directly visible in `.coverage-map` snapshots.
- fn make_filenames_buffer(&self, tcx: TyCtxt<'_>) -> Vec {
- let mut table = Vec::with_capacity(self.raw_file_table.len() + 1);
+ let mut table = Vec::with_capacity(raw_file_table.len() + 1);
- // LLVM Coverage Mapping Format version 6 (zero-based encoded as 5)
- // requires setting the first filename to the compilation directory.
- // Since rustc generates coverage maps with relative paths, the
- // compilation directory can be combined with the relative paths
- // to get absolute paths, if needed.
- table.push(
- tcx.sess
- .opts
- .working_dir
- .for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
- .to_string_lossy(),
- );
+ // Since version 6 of the LLVM coverage mapping format, the first entry
+ // in the global file table is treated as a base directory, used to
+ // resolve any other entries that are stored as relative paths.
+ let base_dir = tcx
+ .sess
+ .opts
+ .working_dir
+ .for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
+ .to_string_lossy();
+ table.push(base_dir.as_ref());
// Add the regular entries after the base directory.
- table.extend(self.raw_file_table.values().map(|file| {
- file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy()
- }));
+ table.extend(raw_file_table.values().map(|name| name.as_str()));
- llvm_cov::write_filenames_to_buffer(&table)
+ // Encode the file table into a buffer, and get the hash of its encoded
+ // bytes, so that we can embed that hash in `__llvm_covfun` records.
+ let filenames_buffer = llvm_cov::write_filenames_to_buffer(&table);
+ let filenames_hash = llvm_cov::hash_bytes(&filenames_buffer);
+
+ Self { raw_file_table, filenames_buffer, filenames_hash }
+ }
+
+ fn get_existing_id(&self, file: &SourceFile) -> Option {
+ let raw_id = self.raw_file_table.get_index_of(&file.stable_id)?;
+ // The raw file table doesn't include an entry for the base dir
+ // (which has ID 0), so add 1 to get the correct ID.
+ Some(GlobalFileId::from_usize(raw_id + 1))
}
}
@@ -166,26 +175,31 @@ rustc_index::newtype_index! {
struct LocalFileId {}
}
-/// Holds a mapping from "local" (per-function) file IDs to "global" (per-CGU)
-/// file IDs.
+/// Holds a mapping from "local" (per-function) file IDs to their corresponding
+/// source files.
#[derive(Debug, Default)]
struct VirtualFileMapping {
- local_to_global: IndexVec,
- global_to_local: FxIndexMap,
+ local_file_table: IndexVec>,
}
impl VirtualFileMapping {
- fn local_id_for_global(&mut self, global_file_id: GlobalFileId) -> LocalFileId {
- *self
- .global_to_local
- .entry(global_file_id)
- .or_insert_with(|| self.local_to_global.push(global_file_id))
+ fn push_file(&mut self, source_file: &Arc) -> LocalFileId {
+ self.local_file_table.push(Arc::clone(source_file))
}
- fn to_vec(&self) -> Vec {
- // This clone could be avoided by transmuting `&[GlobalFileId]` to `&[u32]`,
- // but it isn't hot or expensive enough to justify the extra unsafety.
- self.local_to_global.iter().map(|&global| GlobalFileId::as_u32(global)).collect()
+ /// Resolves all of the filenames in this local file mapping to a list of
+ /// global file IDs in its CGU, for inclusion in this function's
+ /// `__llvm_covfun` record.
+ ///
+ /// The global file IDs are returned as `u32` to make FFI easier.
+ fn resolve_all(&self, global_file_table: &GlobalFileTable) -> Option> {
+ self.local_file_table
+ .iter()
+ .map(|file| try {
+ let id = global_file_table.get_existing_id(file)?;
+ GlobalFileId::as_u32(id)
+ })
+ .collect::>>()
}
}
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
index 93419c2caad..7bdbc685952 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
@@ -5,6 +5,7 @@
//! [^win]: On Windows the section name is `.lcovfun`.
use std::ffi::CString;
+use std::sync::Arc;
use rustc_abi::Align;
use rustc_codegen_ssa::traits::{
@@ -15,7 +16,7 @@ use rustc_middle::mir::coverage::{
MappingKind, Op,
};
use rustc_middle::ty::{Instance, TyCtxt};
-use rustc_span::Span;
+use rustc_span::{SourceFile, Span};
use rustc_target::spec::HasTargetSpec;
use tracing::debug;
@@ -37,9 +38,16 @@ pub(crate) struct CovfunRecord<'tcx> {
regions: ffi::Regions,
}
+impl<'tcx> CovfunRecord<'tcx> {
+ /// Iterator that yields all source files referred to by this function's
+ /// coverage mappings. Used to build the global file table for the CGU.
+ pub(crate) fn all_source_files(&self) -> impl Iterator- {
+ self.virtual_file_mapping.local_file_table.iter().map(Arc::as_ref)
+ }
+}
+
pub(crate) fn prepare_covfun_record<'tcx>(
tcx: TyCtxt<'tcx>,
- global_file_table: &mut GlobalFileTable,
instance: Instance<'tcx>,
is_used: bool,
) -> Option
> {
@@ -57,7 +65,7 @@ pub(crate) fn prepare_covfun_record<'tcx>(
regions: ffi::Regions::default(),
};
- fill_region_tables(tcx, global_file_table, fn_cov_info, ids_info, &mut covfun);
+ fill_region_tables(tcx, fn_cov_info, ids_info, &mut covfun);
if covfun.regions.has_no_regions() {
debug!(?covfun, "function has no mappings to embed; skipping");
@@ -92,7 +100,6 @@ fn prepare_expressions(ids_info: &CoverageIdsInfo) -> Vec(
tcx: TyCtxt<'tcx>,
- global_file_table: &mut GlobalFileTable,
fn_cov_info: &'tcx FunctionCoverageInfo,
ids_info: &'tcx CoverageIdsInfo,
covfun: &mut CovfunRecord<'tcx>,
@@ -106,11 +113,7 @@ fn fill_region_tables<'tcx>(
};
let source_file = source_map.lookup_source_file(first_span.lo());
- // Look up the global file ID for that file.
- let global_file_id = global_file_table.global_file_id_for_file(&source_file);
-
- // Associate that global file ID with a local file ID for this function.
- let local_file_id = covfun.virtual_file_mapping.local_id_for_global(global_file_id);
+ let local_file_id = covfun.virtual_file_mapping.push_file(&source_file);
// In rare cases, _all_ of a function's spans are discarded, and coverage
// codegen needs to handle that gracefully to avoid #133606.
@@ -179,7 +182,7 @@ fn fill_region_tables<'tcx>(
/// as a global variable in the `__llvm_covfun` section.
pub(crate) fn generate_covfun_record<'tcx>(
cx: &CodegenCx<'_, 'tcx>,
- filenames_hash: u64,
+ global_file_table: &GlobalFileTable,
covfun: &CovfunRecord<'tcx>,
) {
let &CovfunRecord {
@@ -191,12 +194,19 @@ pub(crate) fn generate_covfun_record<'tcx>(
ref regions,
} = covfun;
+ let Some(local_file_table) = virtual_file_mapping.resolve_all(global_file_table) else {
+ debug_assert!(
+ false,
+ "all local files should be present in the global file table: \
+ global_file_table = {global_file_table:?}, \
+ virtual_file_mapping = {virtual_file_mapping:?}"
+ );
+ return;
+ };
+
// Encode the function's coverage mappings into a buffer.
- let coverage_mapping_buffer = llvm_cov::write_function_mappings_to_buffer(
- &virtual_file_mapping.to_vec(),
- expressions,
- regions,
- );
+ let coverage_mapping_buffer =
+ llvm_cov::write_function_mappings_to_buffer(&local_file_table, expressions, regions);
// A covfun record consists of four target-endian integers, followed by the
// encoded mapping data in bytes. Note that the length field is 32 bits.
@@ -209,7 +219,7 @@ pub(crate) fn generate_covfun_record<'tcx>(
cx.const_u64(func_name_hash),
cx.const_u32(coverage_mapping_buffer.len() as u32),
cx.const_u64(source_hash),
- cx.const_u64(filenames_hash),
+ cx.const_u64(global_file_table.filenames_hash),
cx.const_bytes(&coverage_mapping_buffer),
],
// This struct needs to be packed, so that the 32-bit length field
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs
index ab030f5b615..68f60f169b5 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs
@@ -7,7 +7,6 @@ use rustc_middle::ty::{self, TyCtxt};
use rustc_span::def_id::DefIdSet;
use crate::common::CodegenCx;
-use crate::coverageinfo::mapgen::GlobalFileTable;
use crate::coverageinfo::mapgen::covfun::{CovfunRecord, prepare_covfun_record};
use crate::llvm;
@@ -21,7 +20,6 @@ use crate::llvm;
/// its embedded coverage data.
pub(crate) fn prepare_covfun_records_for_unused_functions<'tcx>(
cx: &CodegenCx<'_, 'tcx>,
- global_file_table: &mut GlobalFileTable,
covfun_records: &mut Vec>,
) {
assert!(cx.codegen_unit.is_code_coverage_dead_code_cgu());
@@ -33,7 +31,7 @@ pub(crate) fn prepare_covfun_records_for_unused_functions<'tcx>(
// Try to create a covfun record for each unused function.
let mut name_globals = Vec::with_capacity(unused_instances.len());
covfun_records.extend(unused_instances.into_iter().filter_map(|unused| try {
- let record = prepare_covfun_record(cx.tcx, global_file_table, unused.instance, false)?;
+ let record = prepare_covfun_record(cx.tcx, unused.instance, false)?;
// If successful, also store its symbol name in a global constant.
name_globals.push(cx.const_str(unused.symbol_name.name).0);
record
diff --git a/compiler/rustc_error_codes/src/error_codes/E0622.md b/compiler/rustc_error_codes/src/error_codes/E0622.md
index 4cb605b636d..e6ff949d3e9 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0622.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0622.md
@@ -6,8 +6,9 @@ Erroneous code example:
#![feature(intrinsics)]
#![allow(internal_features)]
-extern "rust-intrinsic" {
- pub static atomic_singlethreadfence_seqcst: fn();
+extern "C" {
+ #[rustc_intrinsic]
+ pub static atomic_singlethreadfence_seqcst: unsafe fn();
// error: intrinsic must be a function
}
@@ -22,9 +23,8 @@ error, just declare a function. Example:
#![feature(intrinsics)]
#![allow(internal_features)]
-extern "rust-intrinsic" {
- pub fn atomic_singlethreadfence_seqcst(); // ok!
-}
+#[rustc_intrinsic]
+pub unsafe fn atomic_singlethreadfence_seqcst(); // ok!
fn main() { unsafe { atomic_singlethreadfence_seqcst(); } }
```
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index f68172c1f67..6d616cf84bb 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -230,6 +230,7 @@ impl<'a> ExtCtxt<'a> {
self.pat_ident(sp, ident)
};
let local = P(ast::Local {
+ super_: None,
pat,
ty,
id: ast::DUMMY_NODE_ID,
@@ -245,6 +246,7 @@ impl<'a> ExtCtxt<'a> {
/// Generates `let _: Type;`, which is usually used for type assertions.
pub fn stmt_let_type_only(&self, span: Span, ty: P) -> ast::Stmt {
let local = P(ast::Local {
+ super_: None,
pat: self.pat_wild(span),
ty: Some(ty),
id: ast::DUMMY_NODE_ID,
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 710e129b609..7edb05c7307 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -211,7 +211,7 @@ declare_features! (
(internal, custom_mir, "1.65.0", None),
/// Outputs useful `assert!` messages
(unstable, generic_assert, "1.63.0", None),
- /// Allows using the `rust-intrinsic`'s "ABI".
+ /// Allows using the #[rustc_intrinsic] attribute.
(internal, intrinsics, "1.0.0", None),
/// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
(internal, lang_items, "1.0.0", None),
@@ -630,7 +630,7 @@ declare_features! (
/// Allows string patterns to dereference values to match them.
(unstable, string_deref_patterns, "1.67.0", Some(87121)),
/// Allows `super let` statements.
- (incomplete, super_let, "CURRENT_RUSTC_VERSION", Some(139076)),
+ (unstable, super_let, "CURRENT_RUSTC_VERSION", Some(139076)),
/// Allows subtrait items to shadow supertrait items.
(unstable, supertrait_item_shadowing, "1.86.0", Some(89151)),
/// Allows using `#[thread_local]` on `static` items.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 1a6c15b66a4..c61477951c9 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1555,6 +1555,7 @@ impl<'hir> Pat<'hir> {
use PatKind::*;
match self.kind {
+ Missing => unreachable!(),
Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true,
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
@@ -1582,7 +1583,7 @@ impl<'hir> Pat<'hir> {
use PatKind::*;
match self.kind {
- Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
+ Missing | Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
@@ -1720,6 +1721,9 @@ pub enum TyPatKind<'hir> {
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum PatKind<'hir> {
+ /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
+ Missing,
+
/// Represents a wildcard pattern (i.e., `_`).
Wild,
@@ -1817,6 +1821,8 @@ pub enum StmtKind<'hir> {
/// Represents a `let` statement (i.e., `let : = ;`).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct LetStmt<'hir> {
+ /// Span of `super` in `super let`.
+ pub super_: Option,
pub pat: &'hir Pat<'hir>,
/// Type annotation, if any (otherwise the type will be inferred).
pub ty: Option<&'hir Ty<'hir>>,
@@ -4850,7 +4856,7 @@ mod size_asserts {
static_assert_size!(ImplItemKind<'_>, 40);
static_assert_size!(Item<'_>, 88);
static_assert_size!(ItemKind<'_>, 64);
- static_assert_size!(LetStmt<'_>, 64);
+ static_assert_size!(LetStmt<'_>, 72);
static_assert_size!(Param<'_>, 32);
static_assert_size!(Pat<'_>, 72);
static_assert_size!(Path<'_>, 40);
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 506358341b5..ea3f396761b 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -744,7 +744,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V:
visit_opt!(visitor, visit_pat_expr, lower_bound);
visit_opt!(visitor, visit_pat_expr, upper_bound);
}
- PatKind::Never | PatKind::Wild | PatKind::Err(_) => (),
+ PatKind::Missing | PatKind::Never | PatKind::Wild | PatKind::Err(_) => (),
PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => {
walk_list!(visitor, visit_pat, prepatterns);
visit_opt!(visitor, visit_pat, slice_pattern);
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index a0798656763..e3ed20e1b31 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -741,10 +741,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
for &assoc_item in assoc_items.in_definition_order() {
match assoc_item.kind {
- ty::AssocKind::Fn => {
- let abi = tcx.fn_sig(assoc_item.def_id).skip_binder().abi();
- forbid_intrinsic_abi(tcx, assoc_item.ident(tcx).span, abi);
- }
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
let trait_args = GenericArgs::identity_for_item(tcx, def_id);
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
@@ -788,65 +784,59 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
};
check_abi(tcx, it.span, abi);
- match abi {
- ExternAbi::RustIntrinsic => {
- for item in items {
- intrinsic::check_intrinsic_type(
- tcx,
- item.id.owner_id.def_id,
- item.span,
- item.ident.name,
- abi,
- );
- }
+ for item in items {
+ let def_id = item.id.owner_id.def_id;
+
+ if tcx.has_attr(def_id, sym::rustc_intrinsic) {
+ intrinsic::check_intrinsic_type(
+ tcx,
+ item.id.owner_id.def_id,
+ item.span,
+ item.ident.name,
+ abi,
+ );
}
- _ => {
- for item in items {
- let def_id = item.id.owner_id.def_id;
- let generics = tcx.generics_of(def_id);
- let own_counts = generics.own_counts();
- if generics.own_params.len() - own_counts.lifetimes != 0 {
- let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts)
- {
- (_, 0) => ("type", "types", Some("u32")),
- // We don't specify an example value, because we can't generate
- // a valid value for any type.
- (0, _) => ("const", "consts", None),
- _ => ("type or const", "types or consts", None),
- };
- struct_span_code_err!(
- tcx.dcx(),
- item.span,
- E0044,
- "foreign items may not have {kinds} parameters",
- )
- .with_span_label(item.span, format!("can't have {kinds} parameters"))
- .with_help(
- // FIXME: once we start storing spans for type arguments, turn this
- // into a suggestion.
- format!(
- "replace the {} parameters with concrete {}{}",
- kinds,
- kinds_pl,
- egs.map(|egs| format!(" like `{egs}`")).unwrap_or_default(),
- ),
- )
- .emit();
- }
+ let generics = tcx.generics_of(def_id);
+ let own_counts = generics.own_counts();
+ if generics.own_params.len() - own_counts.lifetimes != 0 {
+ let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
+ (_, 0) => ("type", "types", Some("u32")),
+ // We don't specify an example value, because we can't generate
+ // a valid value for any type.
+ (0, _) => ("const", "consts", None),
+ _ => ("type or const", "types or consts", None),
+ };
+ struct_span_code_err!(
+ tcx.dcx(),
+ item.span,
+ E0044,
+ "foreign items may not have {kinds} parameters",
+ )
+ .with_span_label(item.span, format!("can't have {kinds} parameters"))
+ .with_help(
+ // FIXME: once we start storing spans for type arguments, turn this
+ // into a suggestion.
+ format!(
+ "replace the {} parameters with concrete {}{}",
+ kinds,
+ kinds_pl,
+ egs.map(|egs| format!(" like `{egs}`")).unwrap_or_default(),
+ ),
+ )
+ .emit();
+ }
- let item = tcx.hir_foreign_item(item.id);
- match &item.kind {
- hir::ForeignItemKind::Fn(sig, _, _) => {
- require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span);
- }
- hir::ForeignItemKind::Static(..) => {
- check_static_inhabited(tcx, def_id);
- check_static_linkage(tcx, def_id);
- }
- _ => {}
- }
+ let item = tcx.hir_foreign_item(item.id);
+ match &item.kind {
+ hir::ForeignItemKind::Fn(sig, _, _) => {
+ require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span);
}
+ hir::ForeignItemKind::Static(..) => {
+ check_static_inhabited(tcx, def_id);
+ check_static_linkage(tcx, def_id);
+ }
+ _ => {}
}
}
}
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 42d785c8dd0..0bf9e127989 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -1,4 +1,4 @@
-//! Type-checking for the rust-intrinsic intrinsics that the compiler exposes.
+//! Type-checking for the `#[rustc_intrinsic]` intrinsics that the compiler exposes.
use rustc_abi::ExternAbi;
use rustc_errors::codes::*;
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 7c5d7b33a34..30921b6f055 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -137,15 +137,6 @@ fn get_owner_return_paths(
})
}
-/// Forbid defining intrinsics in Rust code,
-/// as they must always be defined by the compiler.
-// FIXME: Move this to a more appropriate place.
-pub fn forbid_intrinsic_abi(tcx: TyCtxt<'_>, sp: Span, abi: ExternAbi) {
- if let ExternAbi::RustIntrinsic = abi {
- tcx.dcx().span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
- }
-}
-
pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
// Only restricted on wasm target for now
if !tcx.sess.target.is_like_wasm {
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index 6b504c0d672..7cb31a64e13 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -8,6 +8,7 @@
use std::mem;
+use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{self, Visitor};
@@ -44,6 +45,8 @@ struct ScopeResolutionVisitor<'tcx> {
scope_tree: ScopeTree,
cx: Context,
+
+ extended_super_lets: FxHashMap>,
}
/// Records the lifetime of a local variable as `cx.var_parent`
@@ -214,18 +217,29 @@ fn resolve_stmt<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, stmt: &'tcx hi
let stmt_id = stmt.hir_id.local_id;
debug!("resolve_stmt(stmt.id={:?})", stmt_id);
- // Every statement will clean up the temporaries created during
- // execution of that statement. Therefore each statement has an
- // associated destruction scope that represents the scope of the
- // statement plus its destructors, and thus the scope for which
- // regions referenced by the destructors need to survive.
+ if let hir::StmtKind::Let(LetStmt { super_: Some(_), .. }) = stmt.kind {
+ // `super let` statement does not start a new scope, such that
+ //
+ // { super let x = identity(&temp()); &x }.method();
+ //
+ // behaves exactly as
+ //
+ // (&identity(&temp()).method();
+ intravisit::walk_stmt(visitor, stmt);
+ } else {
+ // Every statement will clean up the temporaries created during
+ // execution of that statement. Therefore each statement has an
+ // associated destruction scope that represents the scope of the
+ // statement plus its destructors, and thus the scope for which
+ // regions referenced by the destructors need to survive.
- let prev_parent = visitor.cx.parent;
- visitor.enter_node_scope_with_dtor(stmt_id, true);
+ let prev_parent = visitor.cx.parent;
+ visitor.enter_node_scope_with_dtor(stmt_id, true);
- intravisit::walk_stmt(visitor, stmt);
+ intravisit::walk_stmt(visitor, stmt);
- visitor.cx.parent = prev_parent;
+ visitor.cx.parent = prev_parent;
+ }
}
fn resolve_expr<'tcx>(
@@ -478,14 +492,19 @@ fn resolve_expr<'tcx>(
visitor.cx = prev_cx;
}
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+enum LetKind {
+ Regular,
+ Super,
+}
+
fn resolve_local<'tcx>(
visitor: &mut ScopeResolutionVisitor<'tcx>,
pat: Option<&'tcx hir::Pat<'tcx>>,
init: Option<&'tcx hir::Expr<'tcx>>,
+ let_kind: LetKind,
) {
- debug!("resolve_local(pat={:?}, init={:?})", pat, init);
-
- let blk_scope = visitor.cx.var_parent;
+ debug!("resolve_local(pat={:?}, init={:?}, let_kind={:?})", pat, init, let_kind);
// As an exception to the normal rules governing temporary
// lifetimes, initializers in a let have a temporary lifetime
@@ -543,14 +562,50 @@ fn resolve_local<'tcx>(
// A, but the inner rvalues `a()` and `b()` have an extended lifetime
// due to rule C.
+ if let_kind == LetKind::Super {
+ if let Some(scope) = visitor.extended_super_lets.remove(&pat.unwrap().hir_id.local_id) {
+ // This expression was lifetime-extended by a parent let binding. E.g.
+ //
+ // let a = {
+ // super let b = temp();
+ // &b
+ // };
+ //
+ // (Which needs to behave exactly as: let a = &temp();)
+ //
+ // Processing of `let a` will have already decided to extend the lifetime of this
+ // `super let` to its own var_scope. We use that scope.
+ visitor.cx.var_parent = scope;
+ } else {
+ // This `super let` is not subject to lifetime extension from a parent let binding. E.g.
+ //
+ // identity({ super let x = temp(); &x }).method();
+ //
+ // (Which needs to behave exactly as: identity(&temp()).method();)
+ //
+ // Iterate up to the enclosing destruction scope to find the same scope that will also
+ // be used for the result of the block itself.
+ while let Some(s) = visitor.cx.var_parent {
+ let parent = visitor.scope_tree.parent_map.get(&s).cloned();
+ if let Some(Scope { data: ScopeData::Destruction, .. }) = parent {
+ break;
+ }
+ visitor.cx.var_parent = parent;
+ }
+ }
+ }
+
if let Some(expr) = init {
- record_rvalue_scope_if_borrow_expr(visitor, expr, blk_scope);
+ record_rvalue_scope_if_borrow_expr(visitor, expr, visitor.cx.var_parent);
if let Some(pat) = pat {
if is_binding_pat(pat) {
visitor.scope_tree.record_rvalue_candidate(
expr.hir_id,
- RvalueCandidate { target: expr.hir_id.local_id, lifetime: blk_scope },
+ RvalueCandidate {
+ target: expr.hir_id.local_id,
+ lifetime: visitor.cx.var_parent,
+ },
);
}
}
@@ -562,6 +617,7 @@ fn resolve_local<'tcx>(
if let Some(expr) = init {
visitor.visit_expr(expr);
}
+
if let Some(pat) = pat {
visitor.visit_pat(pat);
}
@@ -623,6 +679,7 @@ fn resolve_local<'tcx>(
PatKind::Ref(_, _)
| PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..)
+ | PatKind::Missing
| PatKind::Wild
| PatKind::Never
| PatKind::Expr(_)
@@ -639,6 +696,7 @@ fn resolve_local<'tcx>(
/// | [ ..., E&, ... ]
/// | ( ..., E&, ... )
/// | {...; E&}
+ /// | { super let ... = E&; ... }
/// | if _ { ...; E& } else { ...; E& }
/// | match _ { ..., _ => E&, ... }
/// | box E&
@@ -675,6 +733,13 @@ fn resolve_local<'tcx>(
if let Some(subexpr) = block.expr {
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
}
+ for stmt in block.stmts {
+ if let hir::StmtKind::Let(local) = stmt.kind
+ && let Some(_) = local.super_
+ {
+ visitor.extended_super_lets.insert(local.pat.hir_id.local_id, blk_id);
+ }
+ }
}
hir::ExprKind::If(_, then_block, else_block) => {
record_rvalue_scope_if_borrow_expr(visitor, then_block, blk_id);
@@ -800,7 +865,7 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
local_id: body.value.hir_id.local_id,
data: ScopeData::Destruction,
});
- resolve_local(this, None, Some(body.value));
+ resolve_local(this, None, Some(body.value), LetKind::Regular);
}
})
}
@@ -818,7 +883,11 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
resolve_expr(self, ex, false);
}
fn visit_local(&mut self, l: &'tcx LetStmt<'tcx>) {
- resolve_local(self, Some(l.pat), l.init)
+ let let_kind = match l.super_ {
+ Some(_) => LetKind::Super,
+ None => LetKind::Regular,
+ };
+ resolve_local(self, Some(l.pat), l.init, let_kind);
}
fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) {
let body = self.tcx.hir_body(c.body);
@@ -847,6 +916,7 @@ pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
cx: Context { parent: None, var_parent: None },
pessimistic_yield: false,
fixup_scopes: vec![],
+ extended_super_lets: Default::default(),
};
visitor.scope_tree.root_body = Some(body.value.hir_id);
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 625f51dd29e..e9cd22435d9 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -42,7 +42,6 @@ use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::ObligationCtxt;
use tracing::{debug, instrument};
-use crate::check::intrinsic::intrinsic_operation_unsafety;
use crate::errors;
use crate::hir_ty_lowering::errors::assoc_kind_str;
use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason};
@@ -1704,18 +1703,13 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
abi: ExternAbi,
safety: hir::Safety,
) -> ty::PolyFnSig<'tcx> {
- let safety = if abi == ExternAbi::RustIntrinsic {
- intrinsic_operation_unsafety(tcx, def_id)
- } else {
- safety
- };
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let fty =
ItemCtxt::new(tcx, def_id).lowerer().lower_fn_ty(hir_id, safety, abi, decl, None, None);
// Feature gate SIMD types in FFI, since I am not sure that the
// ABIs are handled at all correctly. -huonw
- if abi != ExternAbi::RustIntrinsic && !tcx.features().simd_ffi() {
+ if !tcx.features().simd_ffi() {
let check = |hir_ty: &hir::Ty<'_>, ty: Ty<'_>| {
if ty.is_simd() {
let snip = tcx
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 776b23bea8e..320225a7a66 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -172,33 +172,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
};
if let Node::TraitItem(item) = node {
- let parent = tcx.local_parent(item.hir_id().owner.def_id);
- let Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
- unreachable!();
- };
-
- let (trait_generics, trait_bounds) = match parent_trait.kind {
- hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => (generics, supertraits),
- hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
- _ => unreachable!(),
- };
-
- // Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
- // they are not added as super trait bounds to the trait itself. See comment on
- // `requires_default_supertraits` for more details.
- if !icx.lowerer().requires_default_supertraits(trait_bounds, trait_generics) {
- let mut bounds = Vec::new();
- let self_ty_where_predicates = (parent, item.generics.predicates);
- icx.lowerer().add_default_traits_with_filter(
- &mut bounds,
- tcx.types.self_param,
- &[],
- Some(self_ty_where_predicates),
- item.span,
- |tr| tr != hir::LangItem::Sized,
- );
- predicates.extend(bounds);
- }
+ let mut bounds = Vec::new();
+ icx.lowerer().add_default_trait_item_bounds(item, &mut bounds);
+ predicates.extend(bounds);
}
let generics = tcx.generics_of(def_id);
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index c3bb860538e..55087d1f400 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -43,12 +43,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
/// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds
- /// or associative items.
+ /// or associated items.
///
/// To keep backward compatibility with existing code, `experimental_default_bounds` bounds
/// should be added everywhere, including super bounds. However this causes a huge performance
/// costs. For optimization purposes instead of adding default supertraits, bounds
- /// are added to the associative items:
+ /// are added to the associated items:
///
/// ```ignore(illustrative)
/// // Default bounds are generated in the following way:
@@ -81,7 +81,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
///
/// Therefore, `experimental_default_bounds` are still being added to supertraits if
/// the `SelfTyParam` or `AssocItemConstraint` were found in a trait header.
- pub(crate) fn requires_default_supertraits(
+ fn requires_default_supertraits(
&self,
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
hir_generics: &'tcx hir::Generics<'tcx>,
@@ -120,6 +120,43 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
found
}
+ /// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
+ /// they are not added as super trait bounds to the trait itself. See
+ /// `requires_default_supertraits` for more information.
+ pub(crate) fn add_default_trait_item_bounds(
+ &self,
+ trait_item: &hir::TraitItem<'tcx>,
+ bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
+ ) {
+ let tcx = self.tcx();
+ if !tcx.sess.opts.unstable_opts.experimental_default_bounds {
+ return;
+ }
+
+ let parent = tcx.local_parent(trait_item.hir_id().owner.def_id);
+ let hir::Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
+ unreachable!();
+ };
+
+ let (trait_generics, trait_bounds) = match parent_trait.kind {
+ hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => (generics, supertraits),
+ hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
+ _ => unreachable!(),
+ };
+
+ if !self.requires_default_supertraits(trait_bounds, trait_generics) {
+ let self_ty_where_predicates = (parent, trait_item.generics.predicates);
+ self.add_default_traits_with_filter(
+ bounds,
+ tcx.types.self_param,
+ &[],
+ Some(self_ty_where_predicates),
+ trait_item.span,
+ |tr| tr != hir::LangItem::Sized,
+ );
+ }
+ }
+
/// Lazily sets `experimental_default_bounds` to true on trait super bounds.
/// See `requires_default_supertraits` for more information.
pub(crate) fn add_default_super_traits(
@@ -130,6 +167,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
hir_generics: &'tcx hir::Generics<'tcx>,
span: Span,
) {
+ if !self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
+ return;
+ }
+
assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias));
if self.requires_default_supertraits(hir_bounds, hir_generics) {
let self_ty_where_predicates = (trait_def_id, hir_generics.predicates);
@@ -263,11 +304,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
seen_unbound = true;
}
let emit_relax_err = || {
- let unbound_traits =
- match self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
- true => "`?Sized` and `experimental_default_bounds`",
- false => "`?Sized`",
- };
+ let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds {
+ true => "`?Sized` and `experimental_default_bounds`",
+ false => "`?Sized`",
+ };
// There was a `?Trait` bound, but it was neither `?Sized` nor `experimental_default_bounds`.
tcx.dcx().span_err(
unbound.span,
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 8c0c17f7a7d..865209b6a96 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -960,12 +960,16 @@ impl<'a> State<'a> {
fn print_local(
&mut self,
+ super_: bool,
init: Option<&hir::Expr<'_>>,
els: Option<&hir::Block<'_>>,
decl: impl Fn(&mut Self),
) {
self.space_if_not_bol();
self.ibox(INDENT_UNIT);
+ if super_ {
+ self.word_nbsp("super");
+ }
self.word_nbsp("let");
self.ibox(INDENT_UNIT);
@@ -995,7 +999,9 @@ impl<'a> State<'a> {
self.maybe_print_comment(st.span.lo());
match st.kind {
hir::StmtKind::Let(loc) => {
- self.print_local(loc.init, loc.els, |this| this.print_local_decl(loc));
+ self.print_local(loc.super_.is_some(), loc.init, loc.els, |this| {
+ this.print_local_decl(loc)
+ });
}
hir::StmtKind::Item(item) => self.ann.nested(self, Nested::Item(item)),
hir::StmtKind::Expr(expr) => {
@@ -1488,7 +1494,7 @@ impl<'a> State<'a> {
// Print `let _t = $init;`:
let temp = Ident::from_str("_t");
- self.print_local(Some(init), None, |this| this.print_ident(temp));
+ self.print_local(false, Some(init), None, |this| this.print_ident(temp));
self.word(";");
// Print `_t`:
@@ -1868,6 +1874,7 @@ impl<'a> State<'a> {
// Pat isn't normalized, but the beauty of it
// is that it doesn't matter
match pat.kind {
+ PatKind::Missing => unreachable!(),
PatKind::Wild => self.word("_"),
PatKind::Never => self.word("!"),
PatKind::Binding(BindingMode(by_ref, mutbl), _, ident, sub) => {
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index dabae7b1d09..2189fdf0f34 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -5,7 +5,7 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
-use rustc_hir_analysis::check::{check_function_signature, forbid_intrinsic_abi};
+use rustc_hir_analysis::check::check_function_signature;
use rustc_infer::infer::RegionVariableOrigin;
use rustc_infer::traits::WellFormedLoc;
use rustc_middle::ty::{self, Binder, Ty, TyCtxt};
@@ -50,8 +50,6 @@ pub(super) fn check_fn<'a, 'tcx>(
let span = body.value.span;
- forbid_intrinsic_abi(tcx, span, fn_sig.abi);
-
GatherLocalsVisitor::new(fcx).visit_body(body);
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 467ca26e7ea..b8968b58769 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -970,7 +970,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result);
// Normalize only after registering in `user_provided_sigs`.
- self.normalize(self.tcx.hir_span(hir_id), result)
+ self.normalize(self.tcx.def_span(expr_def_id), result)
}
/// Invoked when we are translating the coroutine that results
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index f42ca3af2b3..f1571cf4c83 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -37,7 +37,6 @@
use std::ops::Deref;
-use rustc_abi::ExternAbi;
use rustc_attr_parsing::InlineAttr;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, struct_span_code_err};
@@ -1240,10 +1239,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
};
if let (Some(a_sig), Some(b_sig)) = (a_sig, b_sig) {
- // Intrinsics are not coercible to function pointers.
- if a_sig.abi() == ExternAbi::RustIntrinsic || b_sig.abi() == ExternAbi::RustIntrinsic {
- return Err(TypeError::IntrinsicCast);
- }
// The signature must match.
let (a_sig, b_sig) = self.normalize(new.span, (a_sig, b_sig));
let sig = self
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 45ab8e03db5..952a2e231e4 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -482,7 +482,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// All of these constitute a read, or match on something that isn't `!`,
// which would require a `NeverToAny` coercion.
- hir::PatKind::Binding(_, _, _, _)
+ hir::PatKind::Missing
+ | hir::PatKind::Binding(_, _, _, _)
| hir::PatKind::Struct(_, _, _)
| hir::PatKind::TupleStruct(_, _, _)
| hir::PatKind::Tuple(_, _)
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 64176dacb73..27df8f0e98a 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -611,6 +611,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
for pat in pats {
self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| {
match &pat.kind {
+ PatKind::Missing => unreachable!(),
PatKind::Binding(.., opt_sub_pat) => {
// If the opt_sub_pat is None, then the binding does not count as
// a wildcard for the purpose of borrowing discr.
@@ -1832,6 +1833,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
| PatKind::Expr(..)
| PatKind::Range(..)
| PatKind::Never
+ | PatKind::Missing
| PatKind::Wild
| PatKind::Err(_) => {
// always ok
diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs
index 48fd5f1f982..5d87e800096 100644
--- a/compiler/rustc_hir_typeck/src/gather_locals.rs
+++ b/compiler/rustc_hir_typeck/src/gather_locals.rs
@@ -43,7 +43,7 @@ pub(super) struct Declaration<'a> {
impl<'a> From<&'a hir::LetStmt<'a>> for Declaration<'a> {
fn from(local: &'a hir::LetStmt<'a>) -> Self {
- let hir::LetStmt { hir_id, pat, ty, span, init, els, source: _ } = *local;
+ let hir::LetStmt { hir_id, super_: _, pat, ty, span, init, els, source: _ } = *local;
Declaration { hir_id, pat, ty, span, init, origin: DeclOrigin::LocalDecl { els } }
}
}
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 46389668de7..1d86ff14471 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -117,7 +117,7 @@ fn typeck_with_inspect<'tcx>(
let id = tcx.local_def_id_to_hir_id(def_id);
let node = tcx.hir_node(id);
- let span = tcx.hir_span(id);
+ let span = tcx.def_span(def_id);
// Figure out what primary body this item has.
let body_id = node.body_id().unwrap_or_else(|| {
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 9766ceda569..8641348bffb 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -341,7 +341,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let ty = match pat.kind {
- PatKind::Wild | PatKind::Err(_) => expected,
+ PatKind::Missing | PatKind::Wild | PatKind::Err(_) => expected,
// We allow any type here; we ensure that the type is uninhabited during match checking.
PatKind::Never => expected,
PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
@@ -505,9 +505,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
},
// Ref patterns are complicated, we handle them in `check_pat_ref`.
- PatKind::Ref(..) => AdjustMode::Pass,
+ PatKind::Ref(..)
+ // No need to do anything on a missing pattern.
+ | PatKind::Missing
// A `_` pattern works with any expected type, so there's no need to do anything.
- PatKind::Wild
+ | PatKind::Wild
// A malformed pattern doesn't have an expected type, so let's just accept any type.
| PatKind::Err(_)
// Bindings also work with whatever the expected type is,
@@ -1032,7 +1034,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| PatKind::Tuple(..)
| PatKind::Slice(..) => "binding",
- PatKind::Wild
+ PatKind::Missing
+ | PatKind::Wild
| PatKind::Never
| PatKind::Binding(..)
| PatKind::Box(..)
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index dae0efcbbc4..38c2bf54432 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -779,21 +779,19 @@ impl EarlyLintPass for AnonymousParameters {
}
if let ast::AssocItemKind::Fn(box Fn { ref sig, .. }) = it.kind {
for arg in sig.decl.inputs.iter() {
- if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind {
- if ident.name == kw::Empty {
- let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span);
+ if let ast::PatKind::Missing = arg.pat.kind {
+ let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span);
- let (ty_snip, appl) = if let Ok(ref snip) = ty_snip {
- (snip.as_str(), Applicability::MachineApplicable)
- } else {
- ("", Applicability::HasPlaceholders)
- };
- cx.emit_span_lint(
- ANONYMOUS_PARAMETERS,
- arg.pat.span,
- BuiltinAnonymousParams { suggestion: (arg.pat.span, appl), ty_snip },
- );
- }
+ let (ty_snip, appl) = if let Ok(ref snip) = ty_snip {
+ (snip.as_str(), Applicability::MachineApplicable)
+ } else {
+ ("", Applicability::HasPlaceholders)
+ };
+ cx.emit_span_lint(
+ ANONYMOUS_PARAMETERS,
+ arg.pat.span,
+ BuiltinAnonymousParams { suggestion: (arg.pat.span, appl), ty_snip },
+ );
}
}
}
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 7b43aac90c7..806bca78f78 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -1201,7 +1201,8 @@ impl EarlyLintPass for UnusedParens {
// Do not lint on `(..)` as that will result in the other arms being useless.
Paren(_)
// The other cases do not contain sub-patterns.
- | Wild | Never | Rest | Expr(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) | Err(_) => {},
+ | Missing | Wild | Never | Rest | Expr(..) | MacCall(..) | Range(..) | Ident(.., None)
+ | Path(..) | Err(_) => {},
// These are list-like patterns; parens can always be removed.
TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
self.check_unused_parens_pat(cx, p, false, false, keep_space);
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 130a425e9c7..cfb0de8475c 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -207,7 +207,7 @@ impl<'tcx> Collector<'tcx> {
let sess = self.tcx.sess;
- if matches!(abi, ExternAbi::Rust | ExternAbi::RustIntrinsic) {
+ if matches!(abi, ExternAbi::Rust) {
return;
}
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 8d373cb3b30..c168142fb1e 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -747,6 +747,9 @@ pub struct Ascription<'tcx> {
#[derive(Clone, Debug, HashStable, TypeVisitable)]
pub enum PatKind<'tcx> {
+ /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
+ Missing,
+
/// A wildcard pattern: `_`.
Wild,
@@ -812,23 +815,17 @@ pub enum PatKind<'tcx> {
},
/// Pattern obtained by converting a constant (inline or named) to its pattern
- /// representation using `const_to_pat`.
+ /// representation using `const_to_pat`. This is used for unsafety checking.
ExpandedConstant {
- /// [DefId] of the constant, we need this so that we have a
- /// reference that can be used by unsafety checking to visit nested
- /// unevaluated constants and for diagnostics. If the `DefId` doesn't
- /// correspond to a local crate, it points at the `const` item.
+ /// [DefId] of the constant item.
def_id: DefId,
- /// If `false`, then `def_id` points at a `const` item, otherwise it
- /// corresponds to a local inline const.
- is_inline: bool,
- /// If the inline constant is used in a range pattern, this subpattern
- /// represents the range (if both ends are inline constants, there will
- /// be multiple InlineConstant wrappers).
+ /// The pattern that the constant lowered to.
///
- /// Otherwise, the actual pattern that the constant lowered to. As with
- /// other constants, inline constants are matched structurally where
- /// possible.
+ /// HACK: we need to keep the `DefId` of inline constants around for unsafety checking;
+ /// therefore when a range pattern contains inline constants, we re-wrap the range pattern
+ /// with the `ExpandedConstant` nodes that correspond to the range endpoints. Hence
+ /// `subpattern` may actually be a range pattern, and `def_id` be the constant for one of
+ /// its endpoints.
subpattern: Box>,
},
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 7d62ab7970d..f3da2a5cc8e 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -250,7 +250,8 @@ pub(crate) fn for_each_immediate_subpat<'a, 'tcx>(
mut callback: impl FnMut(&'a Pat<'tcx>),
) {
match &pat.kind {
- PatKind::Wild
+ PatKind::Missing
+ | PatKind::Wild
| PatKind::Binding { subpattern: None, .. }
| PatKind::Constant { value: _ }
| PatKind::Range(_)
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 55ebd15248c..07f2a602f2b 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -71,7 +71,7 @@ pub enum InstanceKind<'tcx> {
/// - coroutines
Item(DefId),
- /// An intrinsic `fn` item (with `"rust-intrinsic"` ABI).
+ /// An intrinsic `fn` item (with`#[rustc_instrinsic]`).
///
/// Alongside `Virtual`, this is the only `InstanceKind` that does not have its own callable MIR.
/// Instead, codegen and const eval "magically" evaluate calls to intrinsics purely in the
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index ebb6a8c08a5..7ebfebea44e 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1265,9 +1265,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option, abi: ExternAbi)
| CCmseNonSecureCall
| CCmseNonSecureEntry
| Unadjusted => false,
- Rust | RustCall | RustCold | RustIntrinsic => {
- tcx.sess.panic_strategy() == PanicStrategy::Unwind
- }
+ Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
}
}
diff --git a/compiler/rustc_middle/src/ty/significant_drop_order.rs b/compiler/rustc_middle/src/ty/significant_drop_order.rs
index 4881d611c12..ce4208f2c44 100644
--- a/compiler/rustc_middle/src/ty/significant_drop_order.rs
+++ b/compiler/rustc_middle/src/ty/significant_drop_order.rs
@@ -143,25 +143,11 @@ pub fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option {
| ty::UnsafeBinder(_) => None,
ty::Adt(adt_def, _) => {
- let did = adt_def.did();
- let try_local_did_span = |did: DefId| {
- if let Some(local) = did.as_local() {
- tcx.source_span(local)
- } else {
- tcx.def_span(did)
- }
- };
- let dtor = if let Some(dtor) = tcx.adt_destructor(did) {
- dtor.did
- } else if let Some(dtor) = tcx.adt_async_destructor(did) {
- return Some(tcx.source_span(dtor.impl_did));
+ if let Some(dtor) = tcx.adt_destructor(adt_def.did()) {
+ Some(tcx.def_span(tcx.parent(dtor.did)))
} else {
- return Some(try_local_did_span(did));
- };
- let def_key = tcx.def_key(dtor);
- let Some(parent_index) = def_key.parent else { return Some(try_local_did_span(dtor)) };
- let parent_did = DefId { index: parent_index, krate: dtor.krate };
- Some(try_local_did_span(parent_did))
+ Some(tcx.def_span(adt_def.did()))
+ }
}
ty::Coroutine(did, _)
| ty::CoroutineWitness(did, _)
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index e4863896fc8..857b462b9eb 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -2,7 +2,7 @@
use std::{fmt, iter};
-use rustc_abi::{ExternAbi, Float, Integer, IntegerType, Size};
+use rustc_abi::{Float, Integer, IntegerType, Size};
use rustc_apfloat::Float as _;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -1719,10 +1719,7 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
/// the compiler to make some assumptions about its shape; if the user doesn't use a feature gate, they may
/// cause an ICE that we otherwise may want to prevent.
pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option {
- if tcx.features().intrinsics()
- && (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
- || tcx.has_attr(def_id, sym::rustc_intrinsic))
- {
+ if tcx.features().intrinsics() && tcx.has_attr(def_id, sym::rustc_intrinsic) {
let must_be_overridden = match tcx.hir_node_by_def_id(def_id) {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { has_body, .. }, .. }) => {
!has_body
diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs
index 19669021eef..5918498f239 100644
--- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs
@@ -145,7 +145,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
let arm = &self.thir[*arm];
let value = match arm.pattern.kind {
PatKind::Constant { value } => value,
- PatKind::ExpandedConstant { ref subpattern, def_id: _, is_inline: false }
+ PatKind::ExpandedConstant { ref subpattern, def_id: _ }
if let PatKind::Constant { value } = subpattern.kind =>
{
value
diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
index 29d400a957b..9670c1716f5 100644
--- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
@@ -118,7 +118,7 @@ impl<'tcx> MatchPairTree<'tcx> {
let place = place_builder.try_to_place(cx);
let mut subpairs = Vec::new();
let test_case = match pattern.kind {
- PatKind::Wild | PatKind::Error(_) => None,
+ PatKind::Missing | PatKind::Wild | PatKind::Error(_) => None,
PatKind::Or { ref pats } => Some(TestCase::Or {
pats: pats.iter().map(|pat| FlatPat::new(place_builder.clone(), pat, cx)).collect(),
@@ -201,39 +201,10 @@ impl<'tcx> MatchPairTree<'tcx> {
None
}
- PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => {
+ PatKind::ExpandedConstant { subpattern: ref pattern, .. } => {
MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
None
}
- PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => {
- MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
-
- // Apply a type ascription for the inline constant to the value at `match_pair.place`
- if let Some(source) = place {
- let span = pattern.span;
- let parent_id = cx.tcx.typeck_root_def_id(cx.def_id.to_def_id());
- let args = ty::InlineConstArgs::new(
- cx.tcx,
- ty::InlineConstArgsParts {
- parent_args: ty::GenericArgs::identity_for_item(cx.tcx, parent_id),
- ty: cx.infcx.next_ty_var(span),
- },
- )
- .args;
- let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::new(
- ty::UserTypeKind::TypeOf(def_id, ty::UserArgs { args, user_self_ty: None }),
- ));
- let annotation = ty::CanonicalUserTypeAnnotation {
- inferred_ty: pattern.ty,
- span,
- user_ty: Box::new(user_ty),
- };
- let variance = ty::Contravariant;
- extra_data.ascriptions.push(super::Ascription { annotation, source, variance });
- }
-
- None
- }
PatKind::Array { ref prefix, ref slice, ref suffix } => {
cx.prefix_slice_suffix(
diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs
index 3acf2a6a2a6..977d4f3e931 100644
--- a/compiler/rustc_mir_build/src/builder/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs
@@ -920,6 +920,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
PatKind::Constant { .. }
| PatKind::Range { .. }
+ | PatKind::Missing
| PatKind::Wild
| PatKind::Never
| PatKind::Error(_) => {}
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 6fb9974fc8e..b6a856a6eb4 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -315,6 +315,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
fn visit_pat(&mut self, pat: &'a Pat<'tcx>) {
if self.in_union_destructure {
match pat.kind {
+ PatKind::Missing => unreachable!(),
// binding to a variable allows getting stuff out of variable
PatKind::Binding { .. }
// match is conditional on having this value
@@ -403,9 +404,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
visit::walk_pat(self, pat);
self.inside_adt = old_inside_adt;
}
- PatKind::ExpandedConstant { def_id, is_inline, .. } => {
+ PatKind::ExpandedConstant { def_id, .. } => {
if let Some(def) = def_id.as_local()
- && *is_inline
+ && matches!(self.tcx.def_kind(def_id), DefKind::InlineConst)
{
self.visit_inner_body(def);
}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 9f5e2c06b22..78583a402fe 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -676,7 +676,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
unpeeled_pat = subpattern;
}
- if let PatKind::ExpandedConstant { def_id, is_inline: false, .. } = unpeeled_pat.kind
+ if let PatKind::ExpandedConstant { def_id, .. } = unpeeled_pat.kind
&& let DefKind::Const = self.tcx.def_kind(def_id)
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
// We filter out paths with multiple path::segments.
@@ -1296,7 +1296,8 @@ fn report_non_exhaustive_match<'p, 'tcx>(
for &arm in arms {
let arm = &thir.arms[arm];
- if let PatKind::ExpandedConstant { def_id, is_inline: false, .. } = arm.pattern.kind
+ if let PatKind::ExpandedConstant { def_id, .. } = arm.pattern.kind
+ && !matches!(cx.tcx.def_kind(def_id), DefKind::InlineConst)
&& let Ok(snippet) = cx.tcx.sess.source_map().span_to_snippet(arm.pattern.span)
// We filter out paths with multiple path::segments.
&& snippet.chars().all(|c| c.is_alphanumeric() || c == '_')
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 372453688d2..a40001bf745 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -182,7 +182,10 @@ impl<'tcx> ConstToPat<'tcx> {
}
}
- inlined_const_as_pat
+ // Wrap the pattern in a marker node to indicate that it is the result of lowering a
+ // constant. This is used for diagnostics, and for unsafety checking of inline const blocks.
+ let kind = PatKind::ExpandedConstant { subpattern: inlined_const_as_pat, def_id: uv.def };
+ Box::new(Pat { kind, ty, span: self.span })
}
fn field_pats(
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index d20e051548b..73d60cf4442 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -13,14 +13,15 @@ use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
use rustc_hir::{self as hir, LangItem, RangeEnd};
use rustc_index::Idx;
+use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir::interpret::LitToConstInput;
use rustc_middle::thir::{
Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary,
};
use rustc_middle::ty::layout::IntegerExt;
-use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypingMode};
use rustc_middle::{bug, span_bug};
-use rustc_span::def_id::LocalDefId;
+use rustc_span::def_id::DefId;
use rustc_span::{ErrorGuaranteed, Span};
use tracing::{debug, instrument};
@@ -124,7 +125,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
expr: Option<&'tcx hir::PatExpr<'tcx>>,
// Out-parameters collecting extra data to be reapplied by the caller
ascriptions: &mut Vec>,
- inline_consts: &mut Vec,
+ expanded_consts: &mut Vec,
) -> Result>, ErrorGuaranteed> {
let Some(expr) = expr else { return Ok(None) };
@@ -139,10 +140,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
ascriptions.push(ascription);
kind = subpattern.kind;
}
- PatKind::ExpandedConstant { is_inline, def_id, subpattern } => {
- if is_inline {
- inline_consts.extend(def_id.as_local());
- }
+ PatKind::ExpandedConstant { def_id, subpattern } => {
+ expanded_consts.push(def_id);
kind = subpattern.kind;
}
_ => break,
@@ -221,10 +220,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// Collect extra data while lowering the endpoints, to be reapplied later.
let mut ascriptions = vec![];
- let mut inline_consts = vec![];
+ let mut expanded_consts = vec![];
let mut lower_endpoint =
- |expr| self.lower_pattern_range_endpoint(expr, &mut ascriptions, &mut inline_consts);
+ |expr| self.lower_pattern_range_endpoint(expr, &mut ascriptions, &mut expanded_consts);
let lo = lower_endpoint(lo_expr)?.unwrap_or(PatRangeBoundary::NegInfinity);
let hi = lower_endpoint(hi_expr)?.unwrap_or(PatRangeBoundary::PosInfinity);
@@ -269,17 +268,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// `Foo::<'a>::A..=Foo::B`), we need to put the ascriptions for the associated
// constants somewhere. Have them on the range pattern.
for ascription in ascriptions {
- kind = PatKind::AscribeUserType {
- ascription,
- subpattern: Box::new(Pat { span, ty, kind }),
- };
+ let subpattern = Box::new(Pat { span, ty, kind });
+ kind = PatKind::AscribeUserType { ascription, subpattern };
}
- for def in inline_consts {
- kind = PatKind::ExpandedConstant {
- def_id: def.to_def_id(),
- is_inline: true,
- subpattern: Box::new(Pat { span, ty, kind }),
- };
+ for def_id in expanded_consts {
+ let subpattern = Box::new(Pat { span, ty, kind });
+ kind = PatKind::ExpandedConstant { def_id, subpattern };
}
Ok(kind)
}
@@ -290,6 +284,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let mut span = pat.span;
let kind = match pat.kind {
+ hir::PatKind::Missing => PatKind::Missing,
+
hir::PatKind::Wild => PatKind::Wild,
hir::PatKind::Never => PatKind::Never,
@@ -567,15 +563,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// Lower the named constant to a THIR pattern.
let args = self.typeck_results.node_args(id);
let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args });
- let subpattern = self.const_to_pat(c, ty, id, span);
-
- // Wrap the pattern in a marker node to indicate that it is the result
- // of lowering a named constant. This marker is used for improved
- // diagnostics in some situations, but has no effect at runtime.
- let mut pattern = {
- let kind = PatKind::ExpandedConstant { subpattern, def_id, is_inline: false };
- Box::new(Pat { span, ty, kind })
- };
+ let mut pattern = self.const_to_pat(c, ty, id, span);
// If this is an associated constant with an explicit user-written
// type, add an ascription node (e.g. ` as MyTrait>::CONST`).
@@ -612,18 +600,37 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let ty = tcx.typeck(def_id).node_type(block.hir_id);
let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id());
- let parent_args =
- tcx.erase_regions(ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id));
+ let parent_args = ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id);
let args = ty::InlineConstArgs::new(tcx, ty::InlineConstArgsParts { parent_args, ty }).args;
- debug_assert!(!args.has_free_regions());
-
let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args };
- let subpattern = self.const_to_pat(ty::Const::new_unevaluated(self.tcx, ct), ty, id, span);
+ let c = ty::Const::new_unevaluated(self.tcx, ct);
+ let pattern = self.const_to_pat(c, ty, id, span);
- // Wrap the pattern in a marker node to indicate that it is the result
- // of lowering an inline const block.
- PatKind::ExpandedConstant { subpattern, def_id: def_id.to_def_id(), is_inline: true }
+ // Apply a type ascription for the inline constant.
+ let annotation = {
+ let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
+ let args = ty::InlineConstArgs::new(
+ tcx,
+ ty::InlineConstArgsParts { parent_args, ty: infcx.next_ty_var(span) },
+ )
+ .args;
+ infcx.canonicalize_user_type_annotation(ty::UserType::new(ty::UserTypeKind::TypeOf(
+ def_id.to_def_id(),
+ ty::UserArgs { args, user_self_ty: None },
+ )))
+ };
+ let annotation =
+ CanonicalUserTypeAnnotation { user_ty: Box::new(annotation), span, inferred_ty: ty };
+ PatKind::AscribeUserType {
+ subpattern: pattern,
+ ascription: Ascription {
+ annotation,
+ // Note that we use `Contravariant` here. See the `variance` field documentation
+ // for details.
+ variance: ty::Contravariant,
+ },
+ }
}
/// Lowers the kinds of "expression" that can appear in a HIR pattern:
@@ -635,43 +642,41 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
expr: &'tcx hir::PatExpr<'tcx>,
pat_ty: Option>,
) -> PatKind<'tcx> {
- let (lit, neg) = match &expr.kind {
- hir::PatExprKind::Path(qpath) => {
- return self.lower_path(qpath, expr.hir_id, expr.span).kind;
- }
+ match &expr.kind {
+ hir::PatExprKind::Path(qpath) => self.lower_path(qpath, expr.hir_id, expr.span).kind,
hir::PatExprKind::ConstBlock(anon_const) => {
- return self.lower_inline_const(anon_const, expr.hir_id, expr.span);
+ self.lower_inline_const(anon_const, expr.hir_id, expr.span)
}
- hir::PatExprKind::Lit { lit, negated } => (lit, *negated),
- };
-
- // We handle byte string literal patterns by using the pattern's type instead of the
- // literal's type in `const_to_pat`: if the literal `b"..."` matches on a slice reference,
- // the pattern's type will be `&[u8]` whereas the literal's type is `&[u8; 3]`; using the
- // pattern's type means we'll properly translate it to a slice reference pattern. This works
- // because slices and arrays have the same valtree representation.
- // HACK: As an exception, use the literal's type if `pat_ty` is `String`; this can happen if
- // `string_deref_patterns` is enabled. There's a special case for that when lowering to MIR.
- // FIXME(deref_patterns): This hack won't be necessary once `string_deref_patterns` is
- // superseded by a more general implementation of deref patterns.
- let ct_ty = match pat_ty {
- Some(pat_ty)
- if let ty::Adt(def, _) = *pat_ty.kind()
- && self.tcx.is_lang_item(def.did(), LangItem::String) =>
- {
- if !self.tcx.features().string_deref_patterns() {
- span_bug!(
- expr.span,
- "matching on `String` went through without enabling string_deref_patterns"
- );
- }
- self.typeck_results.node_type(expr.hir_id)
+ hir::PatExprKind::Lit { lit, negated } => {
+ // We handle byte string literal patterns by using the pattern's type instead of the
+ // literal's type in `const_to_pat`: if the literal `b"..."` matches on a slice reference,
+ // the pattern's type will be `&[u8]` whereas the literal's type is `&[u8; 3]`; using the
+ // pattern's type means we'll properly translate it to a slice reference pattern. This works
+ // because slices and arrays have the same valtree representation.
+ // HACK: As an exception, use the literal's type if `pat_ty` is `String`; this can happen if
+ // `string_deref_patterns` is enabled. There's a special case for that when lowering to MIR.
+ // FIXME(deref_patterns): This hack won't be necessary once `string_deref_patterns` is
+ // superseded by a more general implementation of deref patterns.
+ let ct_ty = match pat_ty {
+ Some(pat_ty)
+ if let ty::Adt(def, _) = *pat_ty.kind()
+ && self.tcx.is_lang_item(def.did(), LangItem::String) =>
+ {
+ if !self.tcx.features().string_deref_patterns() {
+ span_bug!(
+ expr.span,
+ "matching on `String` went through without enabling string_deref_patterns"
+ );
+ }
+ self.typeck_results.node_type(expr.hir_id)
+ }
+ Some(pat_ty) => pat_ty,
+ None => self.typeck_results.node_type(expr.hir_id),
+ };
+ let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg: *negated };
+ let constant = self.tcx.at(expr.span).lit_to_const(lit_input);
+ self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind
}
- Some(pat_ty) => pat_ty,
- None => self.typeck_results.node_type(expr.hir_id),
- };
- let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg };
- let constant = self.tcx.at(expr.span).lit_to_const(lit_input);
- self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind
+ }
}
}
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index 16cef0ec3ac..37248941e2c 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -664,6 +664,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
print_indented!(self, "kind: PatKind {", depth_lvl);
match pat_kind {
+ PatKind::Missing => unreachable!(),
PatKind::Wild => {
print_indented!(self, "Wild", depth_lvl + 1);
}
@@ -740,10 +741,9 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
- PatKind::ExpandedConstant { def_id, is_inline, subpattern } => {
+ PatKind::ExpandedConstant { def_id, subpattern } => {
print_indented!(self, "ExpandedConstant {", depth_lvl + 1);
print_indented!(self, format!("def_id: {def_id:?}"), depth_lvl + 2);
- print_indented!(self, format!("is_inline: {is_inline:?}"), depth_lvl + 2);
print_indented!(self, "subpattern:", depth_lvl + 2);
self.print_pat(subpattern, depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 9405b58ab3b..3647bf2c378 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2987,9 +2987,7 @@ impl<'a> Parser<'a> {
}
match ty {
Ok(ty) => {
- let ident = Ident::new(kw::Empty, this.prev_token.span);
- let bm = BindingMode::NONE;
- let pat = this.mk_pat_ident(ty.span, bm, ident);
+ let pat = this.mk_pat(ty.span, PatKind::Missing);
(pat, ty)
}
// If this is a C-variadic argument and we hit an error, return the error.
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 2cd09aa8959..e00fd40ecee 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -75,10 +75,11 @@ impl<'a> Parser<'a> {
let stmt = if self.token.is_keyword(kw::Super) && self.is_keyword_ahead(1, &[kw::Let]) {
self.collect_tokens(None, attrs, force_collect, |this, attrs| {
+ let super_span = this.token.span;
this.expect_keyword(exp!(Super))?;
- this.psess.gated_spans.gate(sym::super_let, this.prev_token.span);
this.expect_keyword(exp!(Let))?;
- let local = this.parse_local(attrs)?; // FIXME(mara): implement super let
+ this.psess.gated_spans.gate(sym::super_let, super_span);
+ let local = this.parse_local(Some(super_span), attrs)?;
let trailing = Trailing::from(capture_semi && this.token == token::Semi);
Ok((
this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Let(local)),
@@ -89,7 +90,7 @@ impl<'a> Parser<'a> {
} else if self.token.is_keyword(kw::Let) {
self.collect_tokens(None, attrs, force_collect, |this, attrs| {
this.expect_keyword(exp!(Let))?;
- let local = this.parse_local(attrs)?;
+ let local = this.parse_local(None, attrs)?;
let trailing = Trailing::from(capture_semi && this.token == token::Semi);
Ok((
this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Let(local)),
@@ -294,7 +295,7 @@ impl<'a> Parser<'a> {
force_collect: ForceCollect,
) -> PResult<'a, Stmt> {
let stmt = self.collect_tokens(None, attrs, force_collect, |this, attrs| {
- let local = this.parse_local(attrs)?;
+ let local = this.parse_local(None, attrs)?;
// FIXME - maybe capture semicolon in recovery?
Ok((
this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Let(local)),
@@ -308,8 +309,8 @@ impl<'a> Parser<'a> {
}
/// Parses a local variable declaration.
- fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P> {
- let lo = self.prev_token.span;
+ fn parse_local(&mut self, super_: Option, attrs: AttrVec) -> PResult<'a, P> {
+ let lo = super_.unwrap_or(self.prev_token.span);
if self.token.is_keyword(kw::Const) && self.look_ahead(1, |t| t.is_ident()) {
self.dcx().emit_err(errors::ConstLetMutuallyExclusive { span: lo.to(self.token.span) });
@@ -411,6 +412,7 @@ impl<'a> Parser<'a> {
};
let hi = if self.token == token::Semi { self.token.span } else { self.prev_token.span };
Ok(P(ast::Local {
+ super_,
ty,
pat,
kind,
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 669349f3380..9161b23428a 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1598,7 +1598,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
if target == Target::ForeignMod
&& let hir::Node::Item(item) = self.tcx.hir_node(hir_id)
&& let Item { kind: ItemKind::ForeignMod { abi, .. }, .. } = item
- && !matches!(abi, ExternAbi::Rust | ExternAbi::RustIntrinsic)
+ && !matches!(abi, ExternAbi::Rust)
{
return;
}
diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs
index 1278e98afcf..71815448172 100644
--- a/compiler/rustc_passes/src/input_stats.rs
+++ b/compiler/rustc_passes/src/input_stats.rs
@@ -295,6 +295,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
record_variants!(
(self, p, p.kind, Some(p.hir_id), hir, Pat, PatKind),
[
+ Missing,
Wild,
Binding,
Struct,
@@ -597,6 +598,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
record_variants!(
(self, p, p.kind, None, ast, Pat, PatKind),
[
+ Missing,
Wild,
Ident,
Struct,
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index d79e9263f61..06eb76c30c5 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -96,7 +96,7 @@ use rustc_middle::query::Providers;
use rustc_middle::span_bug;
use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt};
use rustc_session::lint;
-use rustc_span::{BytePos, Span, Symbol, kw, sym};
+use rustc_span::{BytePos, Span, Symbol, sym};
use tracing::{debug, instrument};
use self::LiveNodeKind::*;
@@ -1481,9 +1481,6 @@ impl<'tcx> Liveness<'_, 'tcx> {
fn should_warn(&self, var: Variable) -> Option {
let name = self.ir.variable_name(var);
- if name == kw::Empty {
- return None;
- }
let name = name.as_str();
if name.as_bytes()[0] == b'_' {
return None;
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index 31c4ee0fa0b..88d45ead295 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -460,7 +460,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
PatKind::AscribeUserType { subpattern, .. }
| PatKind::ExpandedConstant { subpattern, .. } => return self.lower_pat(subpattern),
PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat),
- PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
+ PatKind::Missing | PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
ctor = Wildcard;
fields = vec![];
arity = 0;
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 20e19caf909..1389e8c811e 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -4009,22 +4009,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.report_error(ident.span, error(ident));
}
- // Record as bound if it's valid:
- let ident_valid = ident.name != kw::Empty;
- if ident_valid {
- bindings.last_mut().unwrap().1.insert(ident);
- }
+ // Record as bound.
+ bindings.last_mut().unwrap().1.insert(ident);
if already_bound_or {
// `Variant1(a) | Variant2(a)`, ok
// Reuse definition from the first `a`.
self.innermost_rib_bindings(ValueNS)[&ident]
} else {
+ // A completely fresh binding is added to the set.
let res = Res::Local(pat_id);
- if ident_valid {
- // A completely fresh binding add to the set if it's valid.
- self.innermost_rib_bindings(ValueNS).insert(ident, res);
- }
+ self.innermost_rib_bindings(ValueNS).insert(ident, res);
res
}
}
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index 36b68cc1398..6e13b87c41d 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -491,7 +491,6 @@ impl RustcInternal for Abi {
Abi::CCmseNonSecureCall => rustc_abi::ExternAbi::CCmseNonSecureCall,
Abi::CCmseNonSecureEntry => rustc_abi::ExternAbi::CCmseNonSecureEntry,
Abi::System { unwind } => rustc_abi::ExternAbi::System { unwind },
- Abi::RustIntrinsic => rustc_abi::ExternAbi::RustIntrinsic,
Abi::RustCall => rustc_abi::ExternAbi::RustCall,
Abi::Unadjusted => rustc_abi::ExternAbi::Unadjusted,
Abi::RustCold => rustc_abi::ExternAbi::RustCold,
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index 1ba25aa0e97..28fc68d5e49 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -871,7 +871,6 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi {
ExternAbi::CCmseNonSecureCall => Abi::CCmseNonSecureCall,
ExternAbi::CCmseNonSecureEntry => Abi::CCmseNonSecureEntry,
ExternAbi::System { unwind } => Abi::System { unwind },
- ExternAbi::RustIntrinsic => Abi::RustIntrinsic,
ExternAbi::RustCall => Abi::RustCall,
ExternAbi::Unadjusted => Abi::Unadjusted,
ExternAbi::RustCold => Abi::RustCold,
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 1efa2fe13c5..3fcbbb0e138 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -1093,7 +1093,6 @@ pub enum Abi {
CCmseNonSecureCall,
CCmseNonSecureEntry,
System { unwind: bool },
- RustIntrinsic,
RustCall,
Unadjusted,
RustCold,
diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs
index 209d7483e61..c779720f97b 100644
--- a/compiler/rustc_target/src/callconv/loongarch.rs
+++ b/compiler/rustc_target/src/callconv/loongarch.rs
@@ -1,6 +1,6 @@
use rustc_abi::{
- BackendRepr, ExternAbi, FieldsShape, HasDataLayout, Primitive, Reg, RegKind, Size,
- TyAbiInterface, TyAndLayout, Variants,
+ BackendRepr, FieldsShape, HasDataLayout, Primitive, Reg, RegKind, Size, TyAbiInterface,
+ TyAndLayout, Variants,
};
use crate::callconv::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform};
@@ -364,15 +364,11 @@ where
}
}
-pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, abi: ExternAbi)
+pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
{
- if abi == ExternAbi::RustIntrinsic {
- return;
- }
-
let grlen = cx.data_layout().pointer_size.bits();
for arg in fn_abi.args.iter_mut() {
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index 55e39d093e2..7ecc46cc69d 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -717,16 +717,16 @@ impl<'a, Ty> FnAbi<'a, Ty> {
}
}
- pub fn adjust_for_rust_abi(&mut self, cx: &C, abi: ExternAbi)
+ pub fn adjust_for_rust_abi(&mut self, cx: &C)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
{
let spec = cx.target_spec();
match &*spec.arch {
- "x86" => x86::compute_rust_abi_info(cx, self, abi),
- "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self, abi),
- "loongarch64" => loongarch::compute_rust_abi_info(cx, self, abi),
+ "x86" => x86::compute_rust_abi_info(cx, self),
+ "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self),
+ "loongarch64" => loongarch::compute_rust_abi_info(cx, self),
"aarch64" => aarch64::compute_rust_abi_info(cx, self),
_ => {}
};
@@ -850,10 +850,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
//
// Note that the intrinsic ABI is exempt here as those are not
// real functions anyway, and the backend expects very specific types.
- if abi != ExternAbi::RustIntrinsic
- && spec.simd_types_indirect
- && !can_pass_simd_directly(arg)
- {
+ if spec.simd_types_indirect && !can_pass_simd_directly(arg) {
arg.make_indirect();
}
}
diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs
index 7368e225efa..cd1d3cd1eee 100644
--- a/compiler/rustc_target/src/callconv/riscv.rs
+++ b/compiler/rustc_target/src/callconv/riscv.rs
@@ -5,8 +5,8 @@
// https://github.com/llvm/llvm-project/blob/8e780252a7284be45cf1ba224cabd884847e8e92/clang/lib/CodeGen/TargetInfo.cpp#L9311-L9773
use rustc_abi::{
- BackendRepr, ExternAbi, FieldsShape, HasDataLayout, Primitive, Reg, RegKind, Size,
- TyAbiInterface, TyAndLayout, Variants,
+ BackendRepr, FieldsShape, HasDataLayout, Primitive, Reg, RegKind, Size, TyAbiInterface,
+ TyAndLayout, Variants,
};
use crate::callconv::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform};
@@ -370,15 +370,11 @@ where
}
}
-pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, abi: ExternAbi)
+pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
{
- if abi == ExternAbi::RustIntrinsic {
- return;
- }
-
let xlen = cx.data_layout().pointer_size.bits();
for arg in fn_abi.args.iter_mut() {
diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs
index ba3c1406211..8328f818f9b 100644
--- a/compiler/rustc_target/src/callconv/x86.rs
+++ b/compiler/rustc_target/src/callconv/x86.rs
@@ -1,6 +1,6 @@
use rustc_abi::{
- AddressSpace, Align, BackendRepr, ExternAbi, HasDataLayout, Primitive, Reg, RegKind,
- TyAbiInterface, TyAndLayout,
+ AddressSpace, Align, BackendRepr, HasDataLayout, Primitive, Reg, RegKind, TyAbiInterface,
+ TyAndLayout,
};
use crate::callconv::{ArgAttribute, FnAbi, PassMode};
@@ -193,7 +193,7 @@ pub(crate) fn fill_inregs<'a, Ty, C>(
}
}
-pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, abi: ExternAbi)
+pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
@@ -201,10 +201,7 @@ where
// Avoid returning floats in x87 registers on x86 as loading and storing from x87
// registers will quiet signalling NaNs. Also avoid using SSE registers since they
// are not always available (depending on target features).
- if !fn_abi.ret.is_ignore()
- // Intrinsics themselves are not "real" functions, so theres no need to change their ABIs.
- && abi != ExternAbi::RustIntrinsic
- {
+ if !fn_abi.ret.is_ignore() {
let has_float = match fn_abi.ret.layout.backend_repr {
BackendRepr::Scalar(s) => matches!(s.primitive(), Primitive::Float(_)),
BackendRepr::ScalarPair(s1, s2) => {
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 79f73ef28b3..64171fcc7ab 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2962,14 +2962,9 @@ impl Target {
pub fn is_abi_supported(&self, abi: ExternAbi) -> bool {
use ExternAbi::*;
match abi {
- Rust
- | C { .. }
- | System { .. }
- | RustIntrinsic
- | RustCall
- | Unadjusted
- | Cdecl { .. }
- | RustCold => true,
+ Rust | C { .. } | System { .. } | RustCall | Unadjusted | Cdecl { .. } | RustCold => {
+ true
+ }
EfiApi => {
["arm", "aarch64", "riscv32", "riscv64", "x86", "x86_64"].contains(&&self.arch[..])
}
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 48d5a4a0fcb..3d4ab33240a 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -244,7 +244,7 @@ fn fn_sig_for_fn_abi<'tcx>(
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv {
use rustc_abi::ExternAbi::*;
match tcx.sess.target.adjust_abi(abi, c_variadic) {
- RustIntrinsic | Rust | RustCall => Conv::Rust,
+ Rust | RustCall => Conv::Rust,
// This is intentionally not using `Conv::Cold`, as that has to preserve
// even SIMD registers, which is generally not a good trade-off.
@@ -660,7 +660,7 @@ fn fn_abi_adjust_for_abi<'tcx>(
let tcx = cx.tcx();
if abi.is_rustic_abi() {
- fn_abi.adjust_for_rust_abi(cx, abi);
+ fn_abi.adjust_for_rust_abi(cx);
// Look up the deduced parameter attributes for this function, if we have its def ID and
// we're optimizing in non-incremental mode. We'll tag its parameters with those attributes
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index afd6192d7c4..7fa57df9928 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -8,6 +8,7 @@
//! Note: any changes to the constness of intrinsics should be discussed with the language team.
//! This includes changes in the stability of the constness.
//!
+//! //FIXME(#132735) "old" style intrinsics support has been removed
//! In order to make an intrinsic usable at compile-time, it needs to be declared in the "new"
//! style, i.e. as a `#[rustc_intrinsic]` function, not inside an `extern` block. Then copy the
//! implementation from to
diff --git a/src/doc/unstable-book/src/language-features/intrinsics.md b/src/doc/unstable-book/src/language-features/intrinsics.md
index 975b400447e..a0e38f340f5 100644
--- a/src/doc/unstable-book/src/language-features/intrinsics.md
+++ b/src/doc/unstable-book/src/language-features/intrinsics.md
@@ -52,9 +52,8 @@ with any regular function.
Various intrinsics have native MIR operations that they correspond to. Instead of requiring
backends to implement both the intrinsic and the MIR operation, the `lower_intrinsics` pass
will convert the calls to the MIR operation. Backends do not need to know about these intrinsics
-at all. These intrinsics only make sense without a body, and can either be declared as a "rust-intrinsic"
-or as a `#[rustc_intrinsic]`. The body is never used, as calls to the intrinsic do not exist
-anymore after MIR analyses.
+at all. These intrinsics only make sense without a body, and can be declared as a `#[rustc_intrinsic]`.
+The body is never used, as calls to the intrinsic do not exist anymore after MIR analyses.
## Intrinsics without fallback logic
@@ -70,28 +69,3 @@ These are written without a body:
#[rustc_intrinsic]
pub fn abort() -> !;
```
-
-### Legacy extern ABI based intrinsics
-
-*This style is deprecated, always prefer the above form.*
-
-These are imported as if they were FFI functions, with the special
-`rust-intrinsic` ABI. For example, if one was in a freestanding
-context, but wished to be able to `transmute` between types, and
-perform efficient pointer arithmetic, one would import those functions
-via a declaration like
-
-```rust
-#![feature(intrinsics)]
-#![allow(internal_features)]
-# fn main() {}
-
-extern "rust-intrinsic" {
- fn transmute(x: T) -> U;
-
- fn arith_offset(dst: *const T, offset: isize) -> *const T;
-}
-```
-
-As with any other FFI functions, these are by default always `unsafe` to call.
-You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call.
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index d3ddb77c0b3..06e75fe1764 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -11,7 +11,6 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{BodyId, Mutability};
-use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety;
use rustc_index::IndexVec;
use rustc_metadata::rendered_const;
use rustc_middle::span_bug;
@@ -687,8 +686,6 @@ impl Item {
hir::FnHeader {
safety: if tcx.codegen_fn_attrs(def_id).safe_target_features {
hir::HeaderSafety::SafeTargetFeatures
- } else if abi == ExternAbi::RustIntrinsic {
- intrinsic_operation_unsafety(tcx, def_id.expect_local()).into()
} else {
safety.into()
},
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index f81db58950c..afcca81a485 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -304,6 +304,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
Symbol::intern(&match &p.kind {
// FIXME(never_patterns): does this make sense?
+ PatKind::Missing => unreachable!(),
PatKind::Wild
| PatKind::Err(_)
| PatKind::Never
diff --git a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
index cd9ab2764ac..3afb687040f 100644
--- a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
+++ b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
@@ -45,6 +45,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
pats.iter().all(unary_pattern)
}
match &pat.kind {
+ PatKind::Missing => unreachable!(),
PatKind::Slice(_, _, _)
| PatKind::Range(_, _, _)
| PatKind::Binding(..)
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
index 250f17fa902..a21597ffb93 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
@@ -253,6 +253,7 @@ fn iter_matching_struct_fields<'a>(
impl<'a> NormalizedPat<'a> {
fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) -> Self {
match pat.kind {
+ PatKind::Missing => unreachable!(),
PatKind::Wild | PatKind::Binding(.., None) => Self::Wild,
PatKind::Binding(.., Some(pat))
| PatKind::Box(pat)
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index 56fbd626eef..836c46240ce 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -406,6 +406,7 @@ impl<'a> PatState<'a> {
pats.iter().map(|p| p.pat),
),
+ PatKind::Missing => unreachable!(),
PatKind::Wild
| PatKind::Binding(_, _, _, None)
| PatKind::Expr(_)
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index f43715d6752..8966e6851ac 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -224,6 +224,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec>, focus_idx: us
// We're trying to find whatever kind (~"constructor") we found in `alternatives[start..]`.
let changed = match &mut focus_kind {
+ Missing => unreachable!(),
// These pattern forms are "leafs" and do not have sub-patterns.
// Therefore they are not some form of constructor `C`,
// with which a pattern `C(p_0)` may be formed,
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 4309cd2c9ab..b7dcd2ffb0e 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -676,6 +676,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
}
match pat.value.kind {
+ PatKind::Missing => unreachable!(),
PatKind::Wild => kind!("Wild"),
PatKind::Never => kind!("Never"),
PatKind::Binding(ann, _, name, sub) => {
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index eba576392eb..c5dce26143b 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -33,6 +33,7 @@ pub fn eq_id(l: Ident, r: Ident) -> bool {
pub fn eq_pat(l: &Pat, r: &Pat) -> bool {
use PatKind::*;
match (&l.kind, &r.kind) {
+ (Missing, _) | (_, Missing) => unreachable!(),
(Paren(l), _) => eq_pat(l, r),
(_, Paren(r)) => eq_pat(l, r),
(Wild, Wild) | (Rest, Rest) => true,
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 9938e64d242..b813cd361ed 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -1124,6 +1124,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
pub fn hash_pat(&mut self, pat: &Pat<'_>) {
std::mem::discriminant(&pat.kind).hash(&mut self.s);
match pat.kind {
+ PatKind::Missing => unreachable!(),
PatKind::Binding(BindingMode(by_ref, mutability), _, _, pat) => {
std::mem::discriminant(&by_ref).hash(&mut self.s);
std::mem::discriminant(&mutability).hash(&mut self.s);
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 6d2c2a2d692..bcb0f8349e2 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -1858,6 +1858,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
}
match pat.kind {
+ PatKind::Missing => unreachable!(),
PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable.
PatKind::Binding(_, _, _, pat) => pat.is_some_and(|pat| is_refutable(cx, pat)),
PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index cc02b71f05c..e4c50f2ebdb 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -400,7 +400,6 @@ pub enum FnAbi {
Rust,
RustCall,
RustCold,
- RustIntrinsic,
Stdcall,
StdcallUnwind,
System,
@@ -457,7 +456,6 @@ impl FnAbi {
s if *s == sym::riscv_dash_interrupt_dash_s => FnAbi::RiscvInterruptS,
s if *s == sym::rust_dash_call => FnAbi::RustCall,
s if *s == sym::rust_dash_cold => FnAbi::RustCold,
- s if *s == sym::rust_dash_intrinsic => FnAbi::RustIntrinsic,
s if *s == sym::Rust => FnAbi::Rust,
s if *s == sym::stdcall_dash_unwind => FnAbi::StdcallUnwind,
s if *s == sym::stdcall => FnAbi::Stdcall,
@@ -500,7 +498,6 @@ impl FnAbi {
FnAbi::Rust => "Rust",
FnAbi::RustCall => "rust-call",
FnAbi::RustCold => "rust-cold",
- FnAbi::RustIntrinsic => "rust-intrinsic",
FnAbi::Stdcall => "stdcall",
FnAbi::StdcallUnwind => "stdcall-unwind",
FnAbi::System => "system",
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
index f61ecabb7e4..06ac5b1ffad 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
@@ -59,19 +59,7 @@ impl Evaluator<'_> {
let function_data = self.db.function_data(def);
let attrs = self.db.attrs(def.into());
- let is_intrinsic = attrs.by_key(&sym::rustc_intrinsic).exists()
- // Keep this around for a bit until extern "rustc-intrinsic" abis are no longer used
- || (match &function_data.abi {
- Some(abi) => *abi == sym::rust_dash_intrinsic,
- None => match def.lookup(self.db.upcast()).container {
- hir_def::ItemContainerId::ExternBlockId(block) => {
- let id = block.lookup(self.db.upcast()).id;
- id.item_tree(self.db.upcast())[id.value].abi.as_ref()
- == Some(&sym::rust_dash_intrinsic)
- }
- _ => false,
- },
- });
+ let is_intrinsic = attrs.by_key(&sym::rustc_intrinsic).exists();
if is_intrinsic {
return self.exec_intrinsic(
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
index 89d89fe2230..0cfd36d9166 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -18,7 +18,6 @@ use hir_def::{
TypeOrConstParamId,
};
use hir_expand::name::Name;
-use intern::sym;
use rustc_abi::TargetDataLayout;
use rustc_hash::FxHashSet;
use smallvec::{smallvec, SmallVec};
@@ -303,26 +302,13 @@ pub fn is_fn_unsafe_to_call(
let loc = func.lookup(db.upcast());
match loc.container {
- hir_def::ItemContainerId::ExternBlockId(block) => {
- let id = block.lookup(db.upcast()).id;
- let is_intrinsic_block =
- id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic);
- if is_intrinsic_block {
- // legacy intrinsics
- // extern "rust-intrinsic" intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
- if db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists() {
- Unsafety::Safe
- } else {
- Unsafety::Unsafe
- }
+ hir_def::ItemContainerId::ExternBlockId(_block) => {
+ // Function in an `extern` block are always unsafe to call, except when
+ // it is marked as `safe`.
+ if data.is_safe() {
+ Unsafety::Safe
} else {
- // Function in an `extern` block are always unsafe to call, except when
- // it is marked as `safe`.
- if data.is_safe() {
- Unsafety::Safe
- } else {
- Unsafety::Unsafe
- }
+ Unsafety::Unsafe
}
}
_ => Unsafety::Safe,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs
index 7c2cc2a6c1d..a3554114f4c 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs
@@ -36,7 +36,6 @@ const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[
"wasm",
"system",
"system-unwind",
- "rust-intrinsic",
"rust-call",
"unadjusted",
];
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index 6b470d921f7..5dfd826d7f9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -6945,9 +6945,8 @@ fn hover_feature() {
Various intrinsics have native MIR operations that they correspond to. Instead of requiring
backends to implement both the intrinsic and the MIR operation, the `lower_intrinsics` pass
will convert the calls to the MIR operation. Backends do not need to know about these intrinsics
- at all. These intrinsics only make sense without a body, and can either be declared as a "rust-intrinsic"
- or as a `#[rustc_intrinsic]`. The body is never used, as calls to the intrinsic do not exist
- anymore after MIR analyses.
+ at all. These intrinsics only make sense without a body, and can be as a `#[rustc_intrinsic]`.
+ The body is never used, as calls to the intrinsic do not exist anymore after MIR analyses.
## Intrinsics without fallback logic
@@ -6960,29 +6959,6 @@ fn hover_feature() {
`#[rustc_intrinsic_must_be_overridden]` to the function to ensure that backends don't
invoke the body.
- ### Legacy extern ABI based intrinsics
-
- These are imported as if they were FFI functions, with the special
- `rust-intrinsic` ABI. For example, if one was in a freestanding
- context, but wished to be able to `transmute` between types, and
- perform efficient pointer arithmetic, one would import those functions
- via a declaration like
-
- ```rust
- #![feature(intrinsics)]
- #![allow(internal_features)]
- # fn main() {}
-
- extern "rust-intrinsic" {
- fn transmute(x: T) -> U;
-
- fn arith_offset(dst: *const T, offset: isize) -> *const T;
- }
- ```
-
- As with any other FFI functions, these are by default always `unsafe` to call.
- You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call.
-
"#]],
)
}
diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
index 6b77c72cee8..d4f334289f0 100644
--- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
+++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
@@ -125,7 +125,6 @@ define_symbols! {
riscv_dash_interrupt_dash_s = "riscv-interrupt-s",
rust_dash_call = "rust-call",
rust_dash_cold = "rust-cold",
- rust_dash_intrinsic = "rust-intrinsic",
stdcall_dash_unwind = "stdcall-unwind",
system_dash_unwind = "system-unwind",
sysv64_dash_unwind = "sysv64-unwind",
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index 322af97d9dc..5c3be769f9e 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -2442,11 +2442,7 @@ pub(crate) fn span_hi_for_param(context: &RewriteContext<'_>, param: &ast::Param
}
pub(crate) fn is_named_param(param: &ast::Param) -> bool {
- if let ast::PatKind::Ident(_, ident, _) = param.pat.kind {
- ident.name != symbol::kw::Empty
- } else {
- true
- }
+ !matches!(param.pat.kind, ast::PatKind::Missing)
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs
index 8dc94574503..cb3879f4be8 100644
--- a/src/tools/rustfmt/src/patterns.rs
+++ b/src/tools/rustfmt/src/patterns.rs
@@ -42,6 +42,7 @@ pub(crate) fn is_short_pattern(
fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool {
match &pat.kind {
+ ast::PatKind::Missing => unreachable!(),
ast::PatKind::Rest | ast::PatKind::Never | ast::PatKind::Wild | ast::PatKind::Err(_) => {
true
}
@@ -100,6 +101,7 @@ impl Rewrite for Pat {
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
match self.kind {
+ PatKind::Missing => unreachable!(),
PatKind::Or(ref pats) => {
let pat_strs = pats
.iter()
diff --git a/tests/assembly/simd-bitmask.rs b/tests/assembly/simd-bitmask.rs
index a632791153b..e4122461087 100644
--- a/tests/assembly/simd-bitmask.rs
+++ b/tests/assembly/simd-bitmask.rs
@@ -35,9 +35,8 @@ pub struct m64x2([i64; 2]);
#[repr(simd)]
pub struct m64x4([i64; 4]);
-extern "rust-intrinsic" {
- fn simd_bitmask(mask: V) -> B;
-}
+#[rustc_intrinsic]
+unsafe fn simd_bitmask(mask: V) -> B;
// CHECK-LABEL: bitmask_m8x16
#[no_mangle]
diff --git a/tests/assembly/simd-intrinsic-gather.rs b/tests/assembly/simd-intrinsic-gather.rs
index 8c17a58046d..bcab0ba1cc0 100644
--- a/tests/assembly/simd-intrinsic-gather.rs
+++ b/tests/assembly/simd-intrinsic-gather.rs
@@ -22,9 +22,8 @@ pub struct m64x4([i64; 4]);
#[repr(simd)]
pub struct pf64x4([*const f64; 4]);
-extern "rust-intrinsic" {
- fn simd_gather(values: V, mask: M, pointer: P) -> V;
-}
+#[rustc_intrinsic]
+unsafe fn simd_gather(values: V, mask: M, pointer: P) -> V;
// CHECK-LABEL: gather_f64x4
#[no_mangle]
diff --git a/tests/assembly/simd-intrinsic-mask-load.rs b/tests/assembly/simd-intrinsic-mask-load.rs
index a0d0514c014..d3f3453a780 100644
--- a/tests/assembly/simd-intrinsic-mask-load.rs
+++ b/tests/assembly/simd-intrinsic-mask-load.rs
@@ -34,9 +34,8 @@ pub struct f64x4([f64; 4]);
#[repr(simd)]
pub struct m64x4([i64; 4]);
-extern "rust-intrinsic" {
- fn simd_masked_load(mask: M, pointer: P, values: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_masked_load(mask: M, pointer: P, values: T) -> T;
// CHECK-LABEL: load_i8x16
#[no_mangle]
diff --git a/tests/assembly/simd-intrinsic-mask-reduce.rs b/tests/assembly/simd-intrinsic-mask-reduce.rs
index 959c4ddefdb..8b15ed0a254 100644
--- a/tests/assembly/simd-intrinsic-mask-reduce.rs
+++ b/tests/assembly/simd-intrinsic-mask-reduce.rs
@@ -20,10 +20,10 @@ use minicore::*;
#[repr(simd)]
pub struct mask8x16([i8; 16]);
-extern "rust-intrinsic" {
- fn simd_reduce_all(x: T) -> bool;
- fn simd_reduce_any(x: T) -> bool;
-}
+#[rustc_intrinsic]
+unsafe fn simd_reduce_all(x: T) -> bool;
+#[rustc_intrinsic]
+unsafe fn simd_reduce_any(x: T) -> bool;
// CHECK-LABEL: mask_reduce_all:
#[no_mangle]
diff --git a/tests/assembly/simd-intrinsic-mask-store.rs b/tests/assembly/simd-intrinsic-mask-store.rs
index 4be9194943c..001762e5060 100644
--- a/tests/assembly/simd-intrinsic-mask-store.rs
+++ b/tests/assembly/simd-intrinsic-mask-store.rs
@@ -34,9 +34,8 @@ pub struct f64x4([f64; 4]);
#[repr(simd)]
pub struct m64x4([i64; 4]);
-extern "rust-intrinsic" {
- fn simd_masked_store(mask: M, pointer: P, values: T);
-}
+#[rustc_intrinsic]
+unsafe fn simd_masked_store(mask: M, pointer: P, values: T);
// CHECK-LABEL: store_i8x16
#[no_mangle]
diff --git a/tests/assembly/simd-intrinsic-scatter.rs b/tests/assembly/simd-intrinsic-scatter.rs
index 715de04af4d..d77dfad3546 100644
--- a/tests/assembly/simd-intrinsic-scatter.rs
+++ b/tests/assembly/simd-intrinsic-scatter.rs
@@ -22,9 +22,8 @@ pub struct m64x4([i64; 4]);
#[repr(simd)]
pub struct pf64x4([*mut f64; 4]);
-extern "rust-intrinsic" {
- fn simd_scatter(values: V, pointer: P, mask: M);
-}
+#[rustc_intrinsic]
+unsafe fn simd_scatter(values: V, pointer: P, mask: M);
// CHECK-LABEL: scatter_f64x4
#[no_mangle]
diff --git a/tests/assembly/simd-intrinsic-select.rs b/tests/assembly/simd-intrinsic-select.rs
index 7f1e42662bf..4f8d6b825b6 100644
--- a/tests/assembly/simd-intrinsic-select.rs
+++ b/tests/assembly/simd-intrinsic-select.rs
@@ -48,9 +48,8 @@ pub struct f64x8([f64; 8]);
#[repr(simd)]
pub struct m64x8([i64; 8]);
-extern "rust-intrinsic" {
- fn simd_select(mask: M, a: V, b: V) -> V;
-}
+#[rustc_intrinsic]
+unsafe fn simd_select(mask: M, a: V, b: V) -> V;
// CHECK-LABEL: select_i8x16
#[no_mangle]
diff --git a/tests/codegen/autodiffv.rs b/tests/codegen/autodiff/batched.rs
similarity index 100%
rename from tests/codegen/autodiffv.rs
rename to tests/codegen/autodiff/batched.rs
diff --git a/tests/codegen/autodiff.rs b/tests/codegen/autodiff/scalar.rs
similarity index 100%
rename from tests/codegen/autodiff.rs
rename to tests/codegen/autodiff/scalar.rs
diff --git a/tests/codegen/autodiff/sret.rs b/tests/codegen/autodiff/sret.rs
new file mode 100644
index 00000000000..5ead90041ed
--- /dev/null
+++ b/tests/codegen/autodiff/sret.rs
@@ -0,0 +1,45 @@
+//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat
+//@ no-prefer-dynamic
+//@ needs-enzyme
+
+// This test is almost identical to the scalar.rs one,
+// but we intentionally add a few more floats.
+// `df` would ret `{ f64, f32, f32 }`, but is lowered as an sret.
+// We therefore use this test to verify some of our sret handling.
+
+#![feature(autodiff)]
+
+use std::autodiff::autodiff;
+
+#[no_mangle]
+#[autodiff(df, Reverse, Active, Active, Active)]
+fn primal(x: f32, y: f32) -> f64 {
+ (x * x * y) as f64
+}
+
+// CHECK:define internal fastcc void @_ZN4sret2df17h93be4316dd8ea006E(ptr dead_on_unwind noalias nocapture noundef nonnull writable writeonly align 8 dereferenceable(16) initializes((0, 16)) %_0, float noundef %x, float noundef %y)
+// CHECK-NEXT:start:
+// CHECK-NEXT: %0 = tail call fastcc { double, float, float } @diffeprimal(float %x, float %y)
+// CHECK-NEXT: %.elt = extractvalue { double, float, float } %0, 0
+// CHECK-NEXT: store double %.elt, ptr %_0, align 8
+// CHECK-NEXT: %_0.repack1 = getelementptr inbounds nuw i8, ptr %_0, i64 8
+// CHECK-NEXT: %.elt2 = extractvalue { double, float, float } %0, 1
+// CHECK-NEXT: store float %.elt2, ptr %_0.repack1, align 8
+// CHECK-NEXT: %_0.repack3 = getelementptr inbounds nuw i8, ptr %_0, i64 12
+// CHECK-NEXT: %.elt4 = extractvalue { double, float, float } %0, 2
+// CHECK-NEXT: store float %.elt4, ptr %_0.repack3, align 4
+// CHECK-NEXT: ret void
+// CHECK-NEXT:}
+
+fn main() {
+ let x = std::hint::black_box(3.0);
+ let y = std::hint::black_box(2.5);
+ let scalar = std::hint::black_box(1.0);
+ let (r1, r2, r3) = df(x, y, scalar);
+ // 3*3*1.5 = 22.5
+ assert_eq!(r1, 22.5);
+ // 2*x*y = 2*3*2.5 = 15.0
+ assert_eq!(r2, 15.0);
+ // x*x*1 = 3*3 = 9
+ assert_eq!(r3, 9.0);
+}
diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs
index 2ae2f40d7b3..e0192f8b45a 100644
--- a/tests/codegen/avr/avr-func-addrspace.rs
+++ b/tests/codegen/avr/avr-func-addrspace.rs
@@ -17,9 +17,8 @@
extern crate minicore;
use minicore::*;
-extern "rust-intrinsic" {
- pub fn transmute(src: Src) -> Dst;
-}
+#[rustc_intrinsic]
+pub unsafe fn transmute(src: Src) -> Dst;
pub static mut STORAGE_FOO: fn(&usize, &mut u32) -> Result<(), ()> = arbitrary_black_box;
pub static mut STORAGE_BAR: u32 = 12;
diff --git a/tests/codegen/emscripten-catch-unwind-js-eh.rs b/tests/codegen/emscripten-catch-unwind-js-eh.rs
index 018ad5454fc..3ab4b5c9c63 100644
--- a/tests/codegen/emscripten-catch-unwind-js-eh.rs
+++ b/tests/codegen/emscripten-catch-unwind-js-eh.rs
@@ -23,13 +23,12 @@ fn size_of() -> usize {
loop {}
}
-extern "rust-intrinsic" {
- fn catch_unwind(
- try_fn: fn(_: *mut u8),
- data: *mut u8,
- catch_fn: fn(_: *mut u8, _: *mut u8),
- ) -> i32;
-}
+#[rustc_intrinsic]
+unsafe fn catch_unwind(
+ try_fn: fn(_: *mut u8),
+ data: *mut u8,
+ catch_fn: fn(_: *mut u8, _: *mut u8),
+) -> i32;
// CHECK-LABEL: @ptr_size
#[no_mangle]
diff --git a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs
index 0fc9ae96720..d0571e4df08 100644
--- a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs
+++ b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs
@@ -21,14 +21,12 @@ impl Copy for *mut T {}
fn size_of() -> usize {
loop {}
}
-
-extern "rust-intrinsic" {
- fn catch_unwind(
- try_fn: fn(_: *mut u8),
- data: *mut u8,
- catch_fn: fn(_: *mut u8, _: *mut u8),
- ) -> i32;
-}
+#[rustc_intrinsic]
+unsafe fn catch_unwind(
+ try_fn: fn(_: *mut u8),
+ data: *mut u8,
+ catch_fn: fn(_: *mut u8, _: *mut u8),
+) -> i32;
// CHECK-LABEL: @ptr_size
#[no_mangle]
diff --git a/tests/codegen/intrinsic-no-unnamed-attr.rs b/tests/codegen/intrinsic-no-unnamed-attr.rs
index fce0de80d7b..35eb025ab6b 100644
--- a/tests/codegen/intrinsic-no-unnamed-attr.rs
+++ b/tests/codegen/intrinsic-no-unnamed-attr.rs
@@ -2,9 +2,9 @@
#![feature(intrinsics)]
-extern "rust-intrinsic" {
- fn sqrtf32(x: f32) -> f32;
-}
+#[rustc_intrinsic]
+unsafe fn sqrtf32(x: f32) -> f32;
+
// CHECK: @llvm.sqrt.f32(float) #{{[0-9]*}}
fn main() {
diff --git a/tests/codegen/intrinsics/nontemporal.rs b/tests/codegen/intrinsics/nontemporal.rs
index 1d4fae83c29..a151d4bd297 100644
--- a/tests/codegen/intrinsics/nontemporal.rs
+++ b/tests/codegen/intrinsics/nontemporal.rs
@@ -18,9 +18,8 @@
extern crate minicore;
use minicore::*;
-extern "rust-intrinsic" {
- pub fn nontemporal_store(ptr: *mut T, val: T);
-}
+#[rustc_intrinsic]
+pub unsafe fn nontemporal_store(ptr: *mut T, val: T);
#[no_mangle]
pub fn a(a: &mut u32, b: u32) {
diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs
index 4859d935461..5afddc5ff73 100644
--- a/tests/mir-opt/lower_intrinsics.rs
+++ b/tests/mir-opt/lower_intrinsics.rs
@@ -153,11 +153,10 @@ pub fn discriminant(t: T) {
core::intrinsics::discriminant_value(&E::B);
}
-extern "rust-intrinsic" {
- // Cannot use `std::intrinsics::copy_nonoverlapping` as that is a wrapper function
- #[rustc_nounwind]
- fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize);
-}
+// Cannot use `std::intrinsics::copy_nonoverlapping` as that is a wrapper function
+#[rustc_nounwind]
+#[rustc_intrinsic]
+unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize);
// EMIT_MIR lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff
pub fn f_copy_nonoverlapping() {
diff --git a/tests/run-make/atomic-lock-free/atomic_lock_free.rs b/tests/run-make/atomic-lock-free/atomic_lock_free.rs
index 1f1116b9bfd..b49c5044f31 100644
--- a/tests/run-make/atomic-lock-free/atomic_lock_free.rs
+++ b/tests/run-make/atomic-lock-free/atomic_lock_free.rs
@@ -2,9 +2,8 @@
#![crate_type = "rlib"]
#![no_core]
-extern "rust-intrinsic" {
- fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T;
#[lang = "sized"]
trait Sized {}
diff --git a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs
index 2f97fc1ed95..c91cd695cee 100644
--- a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs
+++ b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs
@@ -37,10 +37,9 @@ mod minicore {
#[inline]
#[rustc_diagnostic_item = "ptr_write_volatile"]
pub unsafe fn write_volatile(dst: *mut T, src: T) {
- extern "rust-intrinsic" {
- #[rustc_nounwind]
- pub fn volatile_store(dst: *mut T, val: T);
- }
+ #[rustc_intrinsic]
+ pub unsafe fn volatile_store(dst: *mut T, val: T);
+
unsafe { volatile_store(dst, src) };
}
}
diff --git a/tests/ui/abi/abi-typo-unstable.stderr b/tests/ui/abi/abi-typo-unstable.feature_disabled.stderr
similarity index 55%
rename from tests/ui/abi/abi-typo-unstable.stderr
rename to tests/ui/abi/abi-typo-unstable.feature_disabled.stderr
index 9ba67ad7dbe..1934b483c47 100644
--- a/tests/ui/abi/abi-typo-unstable.stderr
+++ b/tests/ui/abi/abi-typo-unstable.feature_disabled.stderr
@@ -1,8 +1,8 @@
-error[E0703]: invalid ABI: found `rust-intrinsec`
- --> $DIR/abi-typo-unstable.rs:2:8
+error[E0703]: invalid ABI: found `rust-cull`
+ --> $DIR/abi-typo-unstable.rs:5:8
|
-LL | extern "rust-intrinsec" fn rust_intrinsic() {}
- | ^^^^^^^^^^^^^^^^ invalid ABI
+LL | extern "rust-cull" fn rust_call(_: ()) {}
+ | ^^^^^^^^^^^ invalid ABI
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
diff --git a/tests/ui/abi/abi-typo-unstable.feature_enabled.stderr b/tests/ui/abi/abi-typo-unstable.feature_enabled.stderr
new file mode 100644
index 00000000000..868b9509830
--- /dev/null
+++ b/tests/ui/abi/abi-typo-unstable.feature_enabled.stderr
@@ -0,0 +1,16 @@
+error[E0703]: invalid ABI: found `rust-cull`
+ --> $DIR/abi-typo-unstable.rs:5:8
+ |
+LL | extern "rust-cull" fn rust_call(_: ()) {}
+ | ^^^^^^^^^^^ invalid ABI
+ |
+ = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+help: there's a similarly named valid ABI `rust-call`
+ |
+LL - extern "rust-cull" fn rust_call(_: ()) {}
+LL + extern "rust-call" fn rust_call(_: ()) {}
+ |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0703`.
diff --git a/tests/ui/abi/abi-typo-unstable.rs b/tests/ui/abi/abi-typo-unstable.rs
index 94991a5eb17..75366217fa2 100644
--- a/tests/ui/abi/abi-typo-unstable.rs
+++ b/tests/ui/abi/abi-typo-unstable.rs
@@ -1,6 +1,11 @@
-// rust-intrinsic is unstable and not enabled, so it should not be suggested as a fix
-extern "rust-intrinsec" fn rust_intrinsic() {} //~ ERROR invalid ABI
+//@ revisions: feature_disabled feature_enabled
+#![cfg_attr(feature_enabled, feature(unboxed_closures))]
+
+// rust-call is unstable and not enabled, so it should not be suggested as a fix
+extern "rust-cull" fn rust_call(_: ()) {}
+//~^ ERROR invalid ABI
+//[feature_enabled]~| HELP there's a similarly named valid ABI
fn main() {
- rust_intrinsic();
+ rust_call(());
}
diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr
index d7d2161e7ad..1be8db5ddf4 100644
--- a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr
+++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr
@@ -10,24 +10,6 @@ LL - fn get(x: T, y: U) -> Get::Value {}
LL + fn get(x: T, y: U) -> ::Value {}
|
-error[E0223]: ambiguous associated type
- --> $DIR/associated-types-in-ambiguous-context.rs:13:23
- |
-LL | fn grab(&self) -> Grab::Value;
- | ^^^^^^^^^^^ help: use fully-qualified syntax: `::Value`
-
-error[E0223]: ambiguous associated type
- --> $DIR/associated-types-in-ambiguous-context.rs:16:22
- |
-LL | fn get(&self) -> Get::Value;
- | ^^^^^^^^^^
- |
-help: if there were a type named `Example` that implemented `Get`, you could use the fully-qualified path
- |
-LL - fn get(&self) -> Get::Value;
-LL + fn get(&self) -> ::Value;
- |
-
error[E0223]: ambiguous associated type
--> $DIR/associated-types-in-ambiguous-context.rs:22:17
|
@@ -56,6 +38,24 @@ LL + type X = as Deref>::Target;
|
and N other candidates
+error[E0223]: ambiguous associated type
+ --> $DIR/associated-types-in-ambiguous-context.rs:13:23
+ |
+LL | fn grab(&self) -> Grab::Value;
+ | ^^^^^^^^^^^ help: use fully-qualified syntax: `::Value`
+
+error[E0223]: ambiguous associated type
+ --> $DIR/associated-types-in-ambiguous-context.rs:16:22
+ |
+LL | fn get(&self) -> Get::Value;
+ | ^^^^^^^^^^
+ |
+help: if there were a type named `Example` that implemented `Get`, you could use the fully-qualified path
+ |
+LL - fn get(&self) -> Get::Value;
+LL + fn get(&self) -> ::Value;
+ |
+
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr b/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr
index 3a6b8008fce..02d5231f713 100644
--- a/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr
+++ b/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr
@@ -23,12 +23,6 @@ LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16;
= note: for more information, see issue #41686
= note: `#[warn(anonymous_parameters)]` on by default
-error[E0220]: associated type `Assoc` not found for `Self`
- --> $DIR/ice-mutability-error-slicing-121807.rs:7:36
- |
-LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16;
- | ^^^^^ associated type `Assoc` not found
-
error[E0185]: method `read_dword` has a `&self` declaration in the impl, but not in the trait
--> $DIR/ice-mutability-error-slicing-121807.rs:17:5
|
@@ -47,6 +41,12 @@ LL | extern "C" fn read_word(&mut self) -> u8;
LL | impl MemoryUnit for ROM {
| ^^^^^^^^^^^^^^^^^^^^^^^ missing `read_word` in implementation
+error[E0220]: associated type `Assoc` not found for `Self`
+ --> $DIR/ice-mutability-error-slicing-121807.rs:7:36
+ |
+LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16;
+ | ^^^^^ associated type `Assoc` not found
+
error: aborting due to 4 previous errors; 1 warning emitted
Some errors have detailed explanations: E0046, E0185, E0220, E0261.
diff --git a/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr b/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr
index 190ddeaa8f2..a656bb67bcb 100644
--- a/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr
+++ b/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr
@@ -8,12 +8,6 @@ LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16;
= note: for more information, see issue #41686
= note: `#[warn(anonymous_parameters)]` on by default
-error[E0220]: associated type `Assoc` not found for `Self`
- --> $DIR/trait-impl-argument-difference-ice.rs:4:36
- |
-LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16;
- | ^^^^^ associated type `Assoc` not found
-
error[E0185]: method `read_dword` has a `&self` declaration in the impl, but not in the trait
--> $DIR/trait-impl-argument-difference-ice.rs:14:5
|
@@ -32,6 +26,12 @@ LL | extern "C" fn read_word(&mut self) -> u8;
LL | impl MemoryUnit for ROM {
| ^^^^^^^^^^^^^^^^^^^^^^^ missing `read_word` in implementation
+error[E0220]: associated type `Assoc` not found for `Self`
+ --> $DIR/trait-impl-argument-difference-ice.rs:4:36
+ |
+LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16;
+ | ^^^^^ associated type `Assoc` not found
+
error[E0596]: cannot borrow `*self` as mutable, as it is behind a `&` reference
--> $DIR/trait-impl-argument-difference-ice.rs:16:19
|
diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs
index b2b3c61a722..3e0a5b36ddc 100644
--- a/tests/ui/delegation/ice-issue-124347.rs
+++ b/tests/ui/delegation/ice-issue-124347.rs
@@ -4,7 +4,6 @@
// FIXME(fn_delegation): `recursive delegation` error should be emitted here
trait Trait {
reuse Trait::foo { &self.0 }
- //~^ ERROR recursive delegation is not supported yet
}
reuse foo;
diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr
index 74c4b5cd949..2955c044203 100644
--- a/tests/ui/delegation/ice-issue-124347.stderr
+++ b/tests/ui/delegation/ice-issue-124347.stderr
@@ -1,23 +1,17 @@
-error: recursive delegation is not supported yet
- --> $DIR/ice-issue-124347.rs:6:18
- |
-LL | reuse Trait::foo { &self.0 }
- | ^^^ callee defined here
-
error[E0391]: cycle detected when computing generics of `foo`
- --> $DIR/ice-issue-124347.rs:10:7
+ --> $DIR/ice-issue-124347.rs:9:7
|
LL | reuse foo;
| ^^^
|
= note: ...which immediately requires computing generics of `foo` again
note: cycle used when checking that `foo` is well-formed
- --> $DIR/ice-issue-124347.rs:10:7
+ --> $DIR/ice-issue-124347.rs:9:7
|
LL | reuse foo;
| ^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/drop/drop-order-comparisons.e2021.stderr b/tests/ui/drop/drop-order-comparisons.e2021.stderr
index 601b0a38412..0717a8c1b9b 100644
--- a/tests/ui/drop/drop-order-comparisons.e2021.stderr
+++ b/tests/ui/drop/drop-order-comparisons.e2021.stderr
@@ -31,39 +31,23 @@ LL | | }, e.mark(3), e.ok(4));
note: `#3` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `_v` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
note: the lint level is defined here
--> $DIR/drop-order-comparisons.rs:28:25
@@ -95,21 +79,13 @@ LL | | }, e.mark(1), e.ok(4));
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
warning: relative drop order changing in Rust 2024
@@ -135,21 +111,13 @@ LL | | }, e.mark(1), e.ok(4));
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
warning: relative drop order changing in Rust 2024
@@ -175,21 +143,13 @@ LL | | }, e.mark(2), e.ok(3));
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
warning: relative drop order changing in Rust 2024
@@ -215,21 +175,13 @@ LL | | }, e.mark(2), e.ok(3));
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
warning: `if let` assigns a shorter lifetime since Edition 2024
@@ -245,12 +197,8 @@ LL | _ = (if let Ok(_) = e.ok(4).as_ref() {
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:127:5
|
@@ -279,12 +227,8 @@ LL | _ = (if let Ok(_) = e.err(4).as_ref() {} else {
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:145:44
|
@@ -312,12 +256,8 @@ LL | if let Ok(_) = e.err(4).as_ref() {} else {
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:247:43
|
@@ -345,12 +285,8 @@ LL | if let true = e.err(9).is_ok() {} else {
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:352:41
|
@@ -378,12 +314,8 @@ LL | if let Ok(_v) = e.err(8) {} else {
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:355:35
|
@@ -411,12 +343,8 @@ LL | if let Ok(_) = e.err(7) {} else {
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:358:34
|
@@ -444,12 +372,8 @@ LL | if let Ok(_) = e.err(6).as_ref() {} else {
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:361:43
|
@@ -477,12 +401,8 @@ LL | if let Ok(_v) = e.err(5) {} else {
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:365:35
|
@@ -510,12 +430,8 @@ LL | if let Ok(_) = e.err(4) {} else {
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:368:34
|
@@ -543,12 +459,8 @@ LL | if let Ok(_) = e.err(4).as_ref() {} else {
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:571:1
|
-LL | / impl<'b> Drop for LogDrop<'b> {
-LL | | fn drop(&mut self) {
-LL | | self.0.mark(self.1);
-LL | | }
-LL | | }
- | |_^
+LL | impl<'b> Drop for LogDrop<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/drop-order-comparisons.rs:404:43
|
diff --git a/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr b/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr
index 070ba1c6a4c..0d6974d516b 100644
--- a/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr
+++ b/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr
@@ -11,12 +11,8 @@ LL | if let Some(_value) = Droppy.get() {
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope-gated.rs:14:1
|
-LL | / impl Drop for Droppy {
-LL | | fn drop(&mut self) {
-LL | | println!("dropped");
-LL | | }
-LL | | }
- | |_^
+LL | impl Drop for Droppy {
+ | ^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope-gated.rs:30:5
|
diff --git a/tests/ui/drop/lint-if-let-rescope-with-macro.stderr b/tests/ui/drop/lint-if-let-rescope-with-macro.stderr
index f1ca0ba57de..a0afb8eddb5 100644
--- a/tests/ui/drop/lint-if-let-rescope-with-macro.stderr
+++ b/tests/ui/drop/lint-if-let-rescope-with-macro.stderr
@@ -18,12 +18,8 @@ LL | | };
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope-with-macro.rs:22:1
|
-LL | / impl Drop for Droppy {
-LL | | fn drop(&mut self) {
-LL | | println!("dropped");
-LL | | }
-LL | | }
- | |_^
+LL | impl Drop for Droppy {
+ | ^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope-with-macro.rs:12:38
|
diff --git a/tests/ui/drop/lint-if-let-rescope.stderr b/tests/ui/drop/lint-if-let-rescope.stderr
index e95ec8fcea7..ca2416efcb1 100644
--- a/tests/ui/drop/lint-if-let-rescope.stderr
+++ b/tests/ui/drop/lint-if-let-rescope.stderr
@@ -11,12 +11,8 @@ LL | if let Some(_value) = droppy().get() {
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
-LL | / impl Drop for Droppy {
-LL | | fn drop(&mut self) {
-LL | | println!("dropped");
-LL | | }
-LL | | }
- | |_^
+LL | impl Drop for Droppy {
+ | ^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope.rs:32:5
|
@@ -55,21 +51,13 @@ LL | } else if let Some(_value) = droppy().get() {
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
-LL | / impl Drop for Droppy {
-LL | | fn drop(&mut self) {
-LL | | println!("dropped");
-LL | | }
-LL | | }
- | |_^
+LL | impl Drop for Droppy {
+ | ^^^^^^^^^^^^^^^^^^^^
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
-LL | / impl Drop for Droppy {
-LL | | fn drop(&mut self) {
-LL | | println!("dropped");
-LL | | }
-LL | | }
- | |_^
+LL | impl Drop for Droppy {
+ | ^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope.rs:42:5
|
@@ -105,12 +93,8 @@ LL | } else if let Some(_value) = droppy().get() {
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
-LL | / impl Drop for Droppy {
-LL | | fn drop(&mut self) {
-LL | | println!("dropped");
-LL | | }
-LL | | }
- | |_^
+LL | impl Drop for Droppy {
+ | ^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope.rs:54:5
|
@@ -140,12 +124,8 @@ LL | if let Some(1) = { if let Some(_value) = Droppy.get() { Some(1) } else
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
-LL | / impl Drop for Droppy {
-LL | | fn drop(&mut self) {
-LL | | println!("dropped");
-LL | | }
-LL | | }
- | |_^
+LL | impl Drop for Droppy {
+ | ^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope.rs:58:69
|
@@ -170,12 +150,8 @@ LL | if (if let Some(_value) = droppy().get() { true } else { false }) {
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
-LL | / impl Drop for Droppy {
-LL | | fn drop(&mut self) {
-LL | | println!("dropped");
-LL | | }
-LL | | }
- | |_^
+LL | impl Drop for Droppy {
+ | ^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope.rs:72:53
|
@@ -200,12 +176,8 @@ LL | } else if (((if let Some(_value) = droppy().get() { true } else { false
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
-LL | / impl Drop for Droppy {
-LL | | fn drop(&mut self) {
-LL | | println!("dropped");
-LL | | }
-LL | | }
- | |_^
+LL | impl Drop for Droppy {
+ | ^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope.rs:78:62
|
@@ -230,12 +202,8 @@ LL | while (if let Some(_value) = droppy().get() { false } else { true }) {
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
-LL | / impl Drop for Droppy {
-LL | | fn drop(&mut self) {
-LL | | println!("dropped");
-LL | | }
-LL | | }
- | |_^
+LL | impl Drop for Droppy {
+ | ^^^^^^^^^^^^^^^^^^^^
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope.rs:90:57
|
diff --git a/tests/ui/drop/lint-tail-expr-drop-order.stderr b/tests/ui/drop/lint-tail-expr-drop-order.stderr
index 6ff9b7c1268..e124e9874d0 100644
--- a/tests/ui/drop/lint-tail-expr-drop-order.stderr
+++ b/tests/ui/drop/lint-tail-expr-drop-order.stderr
@@ -21,17 +21,13 @@ LL | }
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
note: `x` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
note: the lint level is defined here
--> $DIR/lint-tail-expr-drop-order.rs:6:9
@@ -62,17 +58,13 @@ LL | }
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
note: `x` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
error: relative drop order changing in Rust 2024
@@ -98,17 +90,13 @@ LL | }
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
note: `x` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
error: relative drop order changing in Rust 2024
@@ -134,10 +122,8 @@ LL | }
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
error: relative drop order changing in Rust 2024
@@ -185,17 +171,13 @@ LL | }
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
note: `x` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
error: relative drop order changing in Rust 2024
@@ -221,23 +203,13 @@ LL | }
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:193:5
|
-LL | / impl Drop for LoudDropper3 {
-LL | |
-LL | | fn drop(&mut self) {
-LL | | println!("loud drop");
-LL | | }
-LL | | }
- | |_____^
+LL | impl Drop for LoudDropper3 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `x` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:205:5
|
-LL | / impl Drop for LoudDropper2 {
-LL | |
-LL | | fn drop(&mut self) {
-LL | | println!("loud drop");
-LL | | }
-LL | | }
- | |_____^
+LL | impl Drop for LoudDropper2 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
error: relative drop order changing in Rust 2024
@@ -263,17 +235,13 @@ LL | ));
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
note: `_x` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
-LL | / impl Drop for LoudDropper {
-... |
-LL | | }
- | |_^
+LL | impl Drop for LoudDropper {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
error: aborting due to 8 previous errors
diff --git a/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr b/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr
index b0f971dd5ce..7bf452e2496 100644
--- a/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr
+++ b/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr
@@ -27,24 +27,18 @@ LL | }
note: `#2` invokes this custom destructor
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:9:1
|
-LL | / impl std::ops::Drop for Drop {
-LL | | fn drop(&mut self) {}
-LL | | }
- | |_^
+LL | impl std::ops::Drop for Drop {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `#1` invokes this custom destructor
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:9:1
|
-LL | / impl std::ops::Drop for Drop {
-LL | | fn drop(&mut self) {}
-LL | | }
- | |_^
+LL | impl std::ops::Drop for Drop {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `e` invokes this custom destructor
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:9:1
|
-LL | / impl std::ops::Drop for Drop {
-LL | | fn drop(&mut self) {}
-LL | | }
- | |_^
+LL | impl std::ops::Drop for Drop {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
note: the lint level is defined here
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:6:9
diff --git a/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr b/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr
index 832e7ef4dc3..2cf244185e6 100644
--- a/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr
+++ b/tests/ui/dyn-compatibility/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr
@@ -187,166 +187,6 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're
LL | fn parrot() -> &'static mut Trait {
| +++++++
-error[E0782]: expected a type, found a trait
- --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:52:16
- |
-LL | fn foo(_: &Trait);
- | ^^^^^
- |
-help: use a new generic type parameter, constrained by `Trait`
- |
-LL - fn foo(_: &Trait);
-LL + fn foo(_: &T);
- |
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
- |
-LL | fn foo(_: &impl Trait);
- | ++++
-help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
- |
-LL | fn foo(_: &dyn Trait);
- | +++
-
-error[E0782]: expected a type, found a trait
- --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:55:19
- |
-LL | fn bar(_: &'a Trait);
- | ^^^^^
- |
-help: use a new generic type parameter, constrained by `Trait`
- |
-LL - fn bar(_: &'a Trait);
-LL + fn bar(_: &'a T);
- |
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
- |
-LL | fn bar(_: &'a impl Trait);
- | ++++
-help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
- |
-LL | fn bar(_: &'a dyn Trait);
- | +++
-
-error[E0782]: expected a type, found a trait
- --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:59:22
- |
-LL | fn alice<'a>(_: &Trait);
- | ^^^^^
- |
-help: use a new generic type parameter, constrained by `Trait`
- |
-LL - fn alice<'a>(_: &Trait);
-LL + fn alice<'a, T: Trait>(_: &T);
- |
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
- |
-LL | fn alice<'a>(_: &impl Trait);
- | ++++
-help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
- |
-LL | fn alice<'a>(_: &dyn Trait);
- | +++
-
-error[E0782]: expected a type, found a trait
- --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:62:23
- |
-LL | fn bob<'a>(_: &'a Trait);
- | ^^^^^
- |
-help: use a new generic type parameter, constrained by `Trait`
- |
-LL - fn bob<'a>(_: &'a Trait);
-LL + fn bob<'a, T: Trait>(_: &'a T);
- |
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
- |
-LL | fn bob<'a>(_: &'a impl Trait);
- | ++++
-help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
- |
-LL | fn bob<'a>(_: &'a dyn Trait);
- | +++
-
-error[E0782]: expected a type, found a trait
- --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:65:18
- |
-LL | fn cat() -> &Trait;
- | ^^^^^
- |
-help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
- |
-LL | fn cat() -> &impl Trait;
- | ++++
-help: alternatively, you can return an owned trait object
- |
-LL - fn cat() -> &Trait;
-LL + fn cat() -> Box;
- |
-
-error[E0782]: expected a type, found a trait
- --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:69:22
- |
-LL | fn dog<'a>() -> &Trait {
- | ^^^^^
- |
-help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
- |
-LL | fn dog<'a>() -> &impl Trait {
- | ++++
-help: alternatively, you can return an owned trait object
- |
-LL - fn dog<'a>() -> &Trait {
-LL + fn dog<'a>() -> Box {
- |
-
-error[E0782]: expected a type, found a trait
- --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:75:24
- |
-LL | fn kitten() -> &'a Trait {
- | ^^^^^
- |
-help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
- |
-LL | fn kitten() -> &'a impl Trait {
- | ++++
-help: alternatively, you can return an owned trait object
- |
-LL - fn kitten() -> &'a Trait {
-LL + fn kitten() -> Box {
- |
-
-error[E0782]: expected a type, found a trait
- --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:81:27
- |
-LL | fn puppy<'a>() -> &'a Trait {
- | ^^^^^
- |
-help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
- |
-LL | fn puppy<'a>() -> &'a impl Trait {
- | ++++
-help: alternatively, you can return an owned trait object
- |
-LL - fn puppy<'a>() -> &'a Trait {
-LL + fn puppy<'a>() -> Box {
- |
-
-error[E0782]: expected a type, found a trait
- --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:86:25
- |
-LL | fn parrot() -> &mut Trait {
- | ^^^^^
- |
-help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
- |
-LL | fn parrot() -> &mut impl Trait {
- | ++++
-help: alternatively, you can return an owned trait object
- |
-LL - fn parrot() -> &mut Trait {
-LL + fn parrot() -> Box {
- |
-
error[E0782]: expected a type, found a trait
--> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:93:12
|
@@ -667,6 +507,166 @@ LL - fn parrot() -> &mut Trait {
LL + fn parrot() -> Box {
|
+error[E0782]: expected a type, found a trait
+ --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:52:16
+ |
+LL | fn foo(_: &Trait);
+ | ^^^^^
+ |
+help: use a new generic type parameter, constrained by `Trait`
+ |
+LL - fn foo(_: &Trait);
+LL + fn foo(_: &T);
+ |
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+ |
+LL | fn foo(_: &impl Trait);
+ | ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+ |
+LL | fn foo(_: &dyn Trait);
+ | +++
+
+error[E0782]: expected a type, found a trait
+ --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:55:19
+ |
+LL | fn bar(_: &'a Trait);
+ | ^^^^^
+ |
+help: use a new generic type parameter, constrained by `Trait`
+ |
+LL - fn bar(_: &'a Trait);
+LL + fn bar(_: &'a T);
+ |
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+ |
+LL | fn bar(_: &'a impl Trait);
+ | ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+ |
+LL | fn bar(_: &'a dyn Trait);
+ | +++
+
+error[E0782]: expected a type, found a trait
+ --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:59:22
+ |
+LL | fn alice<'a>(_: &Trait);
+ | ^^^^^
+ |
+help: use a new generic type parameter, constrained by `Trait`
+ |
+LL - fn alice<'a>(_: &Trait);
+LL + fn alice<'a, T: Trait>(_: &T);
+ |
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+ |
+LL | fn alice<'a>(_: &impl Trait);
+ | ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+ |
+LL | fn alice<'a>(_: &dyn Trait);
+ | +++
+
+error[E0782]: expected a type, found a trait
+ --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:62:23
+ |
+LL | fn bob<'a>(_: &'a Trait);
+ | ^^^^^
+ |
+help: use a new generic type parameter, constrained by `Trait`
+ |
+LL - fn bob<'a>(_: &'a Trait);
+LL + fn bob<'a, T: Trait>(_: &'a T);
+ |
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+ |
+LL | fn bob<'a>(_: &'a impl Trait);
+ | ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+ |
+LL | fn bob<'a>(_: &'a dyn Trait);
+ | +++
+
+error[E0782]: expected a type, found a trait
+ --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:65:18
+ |
+LL | fn cat() -> &Trait;
+ | ^^^^^
+ |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+ |
+LL | fn cat() -> &impl Trait;
+ | ++++
+help: alternatively, you can return an owned trait object
+ |
+LL - fn cat() -> &Trait;
+LL + fn cat() -> Box;
+ |
+
+error[E0782]: expected a type, found a trait
+ --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:69:22
+ |
+LL | fn dog<'a>() -> &Trait {
+ | ^^^^^
+ |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+ |
+LL | fn dog<'a>() -> &impl Trait {
+ | ++++
+help: alternatively, you can return an owned trait object
+ |
+LL - fn dog<'a>() -> &Trait {
+LL + fn dog<'a>() -> Box {
+ |
+
+error[E0782]: expected a type, found a trait
+ --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:75:24
+ |
+LL | fn kitten() -> &'a Trait {
+ | ^^^^^
+ |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+ |
+LL | fn kitten() -> &'a impl Trait {
+ | ++++
+help: alternatively, you can return an owned trait object
+ |
+LL - fn kitten() -> &'a Trait {
+LL + fn kitten() -> Box {
+ |
+
+error[E0782]: expected a type, found a trait
+ --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:81:27
+ |
+LL | fn puppy<'a>() -> &'a Trait {
+ | ^^^^^
+ |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+ |
+LL | fn puppy<'a>() -> &'a impl Trait {
+ | ++++
+help: alternatively, you can return an owned trait object
+ |
+LL - fn puppy<'a>() -> &'a Trait {
+LL + fn puppy<'a>() -> Box {
+ |
+
+error[E0782]: expected a type, found a trait
+ --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:86:25
+ |
+LL | fn parrot() -> &mut Trait {
+ | ^^^^^
+ |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+ |
+LL | fn parrot() -> &mut impl Trait {
+ | ++++
+help: alternatively, you can return an owned trait object
+ |
+LL - fn parrot() -> &mut Trait {
+LL + fn parrot() -> Box {
+ |
+
error: aborting due to 42 previous errors
Some errors have detailed explanations: E0106, E0261, E0782.
diff --git a/tests/ui/error-codes/E0092.rs b/tests/ui/error-codes/E0092.rs
index ddaace98bd4..19a7c65a48e 100644
--- a/tests/ui/error-codes/E0092.rs
+++ b/tests/ui/error-codes/E0092.rs
@@ -1,7 +1,6 @@
#![feature(intrinsics)]
-extern "rust-intrinsic" {
- fn atomic_foo(); //~ ERROR E0092
-}
-fn main() {
-}
+#[rustc_intrinsic]
+unsafe fn atomic_foo(); //~ ERROR E0092
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0092.stderr b/tests/ui/error-codes/E0092.stderr
index 4ff2e6f077d..003c989fd59 100644
--- a/tests/ui/error-codes/E0092.stderr
+++ b/tests/ui/error-codes/E0092.stderr
@@ -1,8 +1,8 @@
error[E0092]: unrecognized atomic operation function: `foo`
- --> $DIR/E0092.rs:3:5
+ --> $DIR/E0092.rs:4:11
|
-LL | fn atomic_foo();
- | ^^^^^^^^^^^^^^^^ unrecognized atomic operation
+LL | unsafe fn atomic_foo();
+ | ^^^^^^^^^^ unrecognized atomic operation
error: aborting due to 1 previous error
diff --git a/tests/ui/error-codes/E0093.rs b/tests/ui/error-codes/E0093.rs
index a2f0b1ae443..24df7a9a32b 100644
--- a/tests/ui/error-codes/E0093.rs
+++ b/tests/ui/error-codes/E0093.rs
@@ -1,8 +1,7 @@
#![feature(intrinsics)]
-extern "rust-intrinsic" {
- fn foo();
- //~^ ERROR E0093
-}
-fn main() {
-}
+#[rustc_intrinsic]
+unsafe fn foo();
+//~^ ERROR E0093
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0093.stderr b/tests/ui/error-codes/E0093.stderr
index 51c367b343a..d81bf53976a 100644
--- a/tests/ui/error-codes/E0093.stderr
+++ b/tests/ui/error-codes/E0093.stderr
@@ -1,8 +1,8 @@
error[E0093]: unrecognized intrinsic function: `foo`
- --> $DIR/E0093.rs:3:5
+ --> $DIR/E0093.rs:4:11
|
-LL | fn foo();
- | ^^^^^^^^^ unrecognized intrinsic
+LL | unsafe fn foo();
+ | ^^^ unrecognized intrinsic
|
= help: if you're adding an intrinsic, be sure to update `check_intrinsic_type`
diff --git a/tests/ui/error-codes/E0622.rs b/tests/ui/error-codes/E0622.rs
index 08c6d171296..0c2a4f226d8 100644
--- a/tests/ui/error-codes/E0622.rs
+++ b/tests/ui/error-codes/E0622.rs
@@ -1,6 +1,14 @@
#![feature(intrinsics)]
-extern "rust-intrinsic" {
- pub static atomic_singlethreadfence_seqcst : unsafe extern "rust-intrinsic" fn();
+
+extern "C" {
+
+ #[rustc_intrinsic]
+ pub static atomic_singlethreadfence_seqcst: unsafe extern "C" fn();
//~^ ERROR intrinsic must be a function [E0622]
}
-fn main() { unsafe { atomic_singlethreadfence_seqcst(); } }
+
+fn main() {
+ unsafe {
+ atomic_singlethreadfence_seqcst();
+ }
+}
diff --git a/tests/ui/error-codes/E0622.stderr b/tests/ui/error-codes/E0622.stderr
index 739ec984fc6..c0aea542af0 100644
--- a/tests/ui/error-codes/E0622.stderr
+++ b/tests/ui/error-codes/E0622.stderr
@@ -1,8 +1,8 @@
error[E0622]: intrinsic must be a function
- --> $DIR/E0622.rs:3:5
+ --> $DIR/E0622.rs:6:5
|
-LL | pub static atomic_singlethreadfence_seqcst : unsafe extern "rust-intrinsic" fn();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a function
+LL | pub static atomic_singlethreadfence_seqcst: unsafe extern "C" fn();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a function
error: aborting due to 1 previous error
diff --git a/tests/ui/extern/extern-with-type-bounds.rs b/tests/ui/extern/extern-with-type-bounds.rs
deleted file mode 100644
index 3fbddfc99a6..00000000000
--- a/tests/ui/extern/extern-with-type-bounds.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-#![feature(intrinsics, rustc_attrs)]
-
-// Intrinsics are the only (?) extern blocks supporting generics.
-// Once intrinsics have to be declared via `#[rustc_intrinsic]`,
-// the entire support for generics in extern fn can probably be removed.
-
-extern "rust-intrinsic" {
- // Silent bounds made explicit to make sure they are actually
- // resolved.
- fn transmute(val: T) -> U;
-
- // Bounds aren't checked right now, so this should work
- // even though it's incorrect.
- fn size_of_val(x: *const T) -> usize;
-
- // Unresolved bounds should still error.
- fn align_of() -> usize;
- //~^ ERROR cannot find trait `NoSuchTrait` in this scope
-}
-
-fn main() {}
diff --git a/tests/ui/extern/extern-with-type-bounds.stderr b/tests/ui/extern/extern-with-type-bounds.stderr
deleted file mode 100644
index 893947e831f..00000000000
--- a/tests/ui/extern/extern-with-type-bounds.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0405]: cannot find trait `NoSuchTrait` in this scope
- --> $DIR/extern-with-type-bounds.rs:17:20
- |
-LL | fn align_of() -> usize;
- | ^^^^^^^^^^^ not found in this scope
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0405`.
diff --git a/tests/ui/feature-gates/feature-gate-abi.rs b/tests/ui/feature-gates/feature-gate-abi.rs
index 2af623734ee..bafd3643788 100644
--- a/tests/ui/feature-gates/feature-gate-abi.rs
+++ b/tests/ui/feature-gates/feature-gate-abi.rs
@@ -8,19 +8,10 @@
extern crate minicore;
use minicore::*;
-// Functions
-extern "rust-intrinsic" fn f1() {} //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
- //~^ ERROR intrinsic must be in
-extern "rust-intrinsic" fn f2() {} //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
- //~^ ERROR intrinsic must be in
extern "rust-call" fn f4(_: ()) {} //~ ERROR extern "rust-call" ABI is experimental and subject to change
// Methods in trait definition
trait Tr {
- extern "rust-intrinsic" fn m1(); //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
- //~^ ERROR intrinsic must be in
- extern "rust-intrinsic" fn m2(); //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
- //~^ ERROR intrinsic must be in
extern "rust-call" fn m4(_: ()); //~ ERROR extern "rust-call" ABI is experimental and subject to change
extern "rust-call" fn dm4(_: ()) {} //~ ERROR extern "rust-call" ABI is experimental and subject to change
@@ -30,28 +21,16 @@ struct S;
// Methods in trait impl
impl Tr for S {
- extern "rust-intrinsic" fn m1() {} //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
- //~^ ERROR intrinsic must be in
- extern "rust-intrinsic" fn m2() {} //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
- //~^ ERROR intrinsic must be in
extern "rust-call" fn m4(_: ()) {} //~ ERROR extern "rust-call" ABI is experimental and subject to change
}
// Methods in inherent impl
impl S {
- extern "rust-intrinsic" fn im1() {} //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
- //~^ ERROR intrinsic must be in
- extern "rust-intrinsic" fn im2() {} //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
- //~^ ERROR intrinsic must be in
extern "rust-call" fn im4(_: ()) {} //~ ERROR extern "rust-call" ABI is experimental and subject to change
}
// Function pointer types
-type A1 = extern "rust-intrinsic" fn(); //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
-type A2 = extern "rust-intrinsic" fn(); //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
type A4 = extern "rust-call" fn(_: ()); //~ ERROR extern "rust-call" ABI is experimental and subject to change
// Foreign modules
-extern "rust-intrinsic" {} //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
-extern "rust-intrinsic" {} //~ ERROR extern "rust-intrinsic" ABI is an implementation detail
extern "rust-call" {} //~ ERROR extern "rust-call" ABI is experimental and subject to change
diff --git a/tests/ui/feature-gates/feature-gate-abi.stderr b/tests/ui/feature-gates/feature-gate-abi.stderr
index a974c0099cb..7897a60b34f 100644
--- a/tests/ui/feature-gates/feature-gate-abi.stderr
+++ b/tests/ui/feature-gates/feature-gate-abi.stderr
@@ -1,23 +1,5 @@
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:12:8
- |
-LL | extern "rust-intrinsic" fn f1() {}
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:14:8
- |
-LL | extern "rust-intrinsic" fn f2() {}
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
error[E0658]: the extern "rust-call" ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:16:8
+ --> $DIR/feature-gate-abi.rs:11:8
|
LL | extern "rust-call" fn f4(_: ()) {}
| ^^^^^^^^^^^
@@ -26,26 +8,8 @@ LL | extern "rust-call" fn f4(_: ()) {}
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:20:12
- |
-LL | extern "rust-intrinsic" fn m1();
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:22:12
- |
-LL | extern "rust-intrinsic" fn m2();
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
error[E0658]: the extern "rust-call" ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:24:12
+ --> $DIR/feature-gate-abi.rs:15:12
|
LL | extern "rust-call" fn m4(_: ());
| ^^^^^^^^^^^
@@ -55,7 +19,7 @@ LL | extern "rust-call" fn m4(_: ());
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the extern "rust-call" ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:26:12
+ --> $DIR/feature-gate-abi.rs:17:12
|
LL | extern "rust-call" fn dm4(_: ()) {}
| ^^^^^^^^^^^
@@ -64,26 +28,8 @@ LL | extern "rust-call" fn dm4(_: ()) {}
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:33:12
- |
-LL | extern "rust-intrinsic" fn m1() {}
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:35:12
- |
-LL | extern "rust-intrinsic" fn m2() {}
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
error[E0658]: the extern "rust-call" ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:37:12
+ --> $DIR/feature-gate-abi.rs:24:12
|
LL | extern "rust-call" fn m4(_: ()) {}
| ^^^^^^^^^^^
@@ -92,26 +38,8 @@ LL | extern "rust-call" fn m4(_: ()) {}
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:42:12
- |
-LL | extern "rust-intrinsic" fn im1() {}
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:44:12
- |
-LL | extern "rust-intrinsic" fn im2() {}
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
error[E0658]: the extern "rust-call" ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:46:12
+ --> $DIR/feature-gate-abi.rs:29:12
|
LL | extern "rust-call" fn im4(_: ()) {}
| ^^^^^^^^^^^
@@ -120,26 +48,8 @@ LL | extern "rust-call" fn im4(_: ()) {}
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:50:18
- |
-LL | type A1 = extern "rust-intrinsic" fn();
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:51:18
- |
-LL | type A2 = extern "rust-intrinsic" fn();
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
error[E0658]: the extern "rust-call" ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:52:18
+ --> $DIR/feature-gate-abi.rs:33:18
|
LL | type A4 = extern "rust-call" fn(_: ());
| ^^^^^^^^^^^
@@ -148,26 +58,8 @@ LL | type A4 = extern "rust-call" fn(_: ());
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:55:8
- |
-LL | extern "rust-intrinsic" {}
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-abi.rs:56:8
- |
-LL | extern "rust-intrinsic" {}
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
error[E0658]: the extern "rust-call" ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:57:8
+ --> $DIR/feature-gate-abi.rs:36:8
|
LL | extern "rust-call" {}
| ^^^^^^^^^^^
@@ -176,54 +68,6 @@ LL | extern "rust-call" {}
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:20:32
- |
-LL | extern "rust-intrinsic" fn m1();
- | ^^
-
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:22:32
- |
-LL | extern "rust-intrinsic" fn m2();
- | ^^
-
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:12:33
- |
-LL | extern "rust-intrinsic" fn f1() {}
- | ^^
-
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:14:33
- |
-LL | extern "rust-intrinsic" fn f2() {}
- | ^^
-
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:33:37
- |
-LL | extern "rust-intrinsic" fn m1() {}
- | ^^
-
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:35:37
- |
-LL | extern "rust-intrinsic" fn m2() {}
- | ^^
-
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:42:38
- |
-LL | extern "rust-intrinsic" fn im1() {}
- | ^^
-
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:44:38
- |
-LL | extern "rust-intrinsic" fn im2() {}
- | ^^
-
-error: aborting due to 27 previous errors
+error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-intrinsics.rs b/tests/ui/feature-gates/feature-gate-intrinsics.rs
index 65806a0223e..b7ebba67272 100644
--- a/tests/ui/feature-gates/feature-gate-intrinsics.rs
+++ b/tests/ui/feature-gates/feature-gate-intrinsics.rs
@@ -1,8 +1,5 @@
-extern "rust-intrinsic" { //~ ERROR "rust-intrinsic" ABI is an implementation detail
- fn bar(); //~ ERROR unrecognized intrinsic function: `bar`
-}
-
-extern "rust-intrinsic" fn baz() {} //~ ERROR "rust-intrinsic" ABI is an implementation detail
-//~^ ERROR intrinsic must be in
+#[rustc_intrinsic]
+//~^ ERROR the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items
+fn bar();
fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-intrinsics.stderr b/tests/ui/feature-gates/feature-gate-intrinsics.stderr
index 97246f05258..a7a725883a9 100644
--- a/tests/ui/feature-gates/feature-gate-intrinsics.stderr
+++ b/tests/ui/feature-gates/feature-gate-intrinsics.stderr
@@ -1,36 +1,12 @@
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-intrinsics.rs:1:8
+error[E0658]: the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items
+ --> $DIR/feature-gate-intrinsics.rs:1:1
|
-LL | extern "rust-intrinsic" {
- | ^^^^^^^^^^^^^^^^
+LL | #[rustc_intrinsic]
+ | ^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gate-intrinsics.rs:5:8
- |
-LL | extern "rust-intrinsic" fn baz() {}
- | ^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(intrinsics)]` to the crate attributes to enable
- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+error: aborting due to 1 previous error
-error[E0093]: unrecognized intrinsic function: `bar`
- --> $DIR/feature-gate-intrinsics.rs:2:5
- |
-LL | fn bar();
- | ^^^^^^^^^ unrecognized intrinsic
- |
- = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type`
-
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-intrinsics.rs:5:34
- |
-LL | extern "rust-intrinsic" fn baz() {}
- | ^^
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0093, E0658.
-For more information about an error, try `rustc --explain E0093`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-super-let.rs b/tests/ui/feature-gates/feature-gate-super-let.rs
index cfe92a42669..7be08003913 100644
--- a/tests/ui/feature-gates/feature-gate-super-let.rs
+++ b/tests/ui/feature-gates/feature-gate-super-let.rs
@@ -2,3 +2,10 @@ fn main() {
super let a = 1;
//~^ ERROR `super let` is experimental
}
+
+// Check that it also isn't accepted in cfg'd out code.
+#[cfg(any())]
+fn a() {
+ super let a = 1;
+ //~^ ERROR `super let` is experimental
+}
diff --git a/tests/ui/feature-gates/feature-gate-super-let.stderr b/tests/ui/feature-gates/feature-gate-super-let.stderr
index a64e1b374f9..4d088594f6d 100644
--- a/tests/ui/feature-gates/feature-gate-super-let.stderr
+++ b/tests/ui/feature-gates/feature-gate-super-let.stderr
@@ -8,6 +8,16 @@ LL | super let a = 1;
= help: add `#![feature(super_let)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: aborting due to 1 previous error
+error[E0658]: `super let` is experimental
+ --> $DIR/feature-gate-super-let.rs:9:5
+ |
+LL | super let a = 1;
+ | ^^^^^
+ |
+ = note: see issue #139076 for more information
+ = help: add `#![feature(super_let)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.rs b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.rs
index 2328798d74c..44c0f1130f0 100644
--- a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.rs
+++ b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.rs
@@ -5,9 +5,9 @@
fn main() {
let a = &[1, 2, 3];
println!("{}", {
- extern "rust-intrinsic" { //~ ERROR "rust-intrinsic" ABI is an implementation detail
- fn atomic_fence();
- }
+ #[rustc_intrinsic] //~ ERROR the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items
+ unsafe fn atomic_fence();
+
atomic_fence(); //~ ERROR: is unsafe
42
});
diff --git a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr
index 86f88fdff5f..aaaaeece67a 100644
--- a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr
+++ b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr
@@ -1,13 +1,13 @@
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/feature-gated-feature-in-macro-arg.rs:8:16
+error[E0658]: the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items
+ --> $DIR/feature-gated-feature-in-macro-arg.rs:8:9
|
-LL | extern "rust-intrinsic" {
- | ^^^^^^^^^^^^^^^^
+LL | #[rustc_intrinsic]
+ | ^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error[E0133]: call to unsafe function `main::atomic_fence` is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `atomic_fence` is unsafe and requires unsafe function or block
--> $DIR/feature-gated-feature-in-macro-arg.rs:11:9
|
LL | atomic_fence();
diff --git a/tests/ui/intrinsics/always-extern.rs b/tests/ui/intrinsics/always-extern.rs
deleted file mode 100644
index 0afd8353455..00000000000
--- a/tests/ui/intrinsics/always-extern.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-#![feature(intrinsics)]
-
-trait Foo {
- extern "rust-intrinsic" fn foo(&self); //~ ERROR intrinsic must
-}
-
-impl Foo for () {
- extern "rust-intrinsic" fn foo(&self) { //~ ERROR intrinsic must
- }
-}
-
-extern "rust-intrinsic" fn hello() {//~ ERROR intrinsic must
- //~^ ERROR unrecognized intrinsic function: `hello`
-}
-
-fn main() {
-}
diff --git a/tests/ui/intrinsics/always-extern.stderr b/tests/ui/intrinsics/always-extern.stderr
deleted file mode 100644
index 44b889c6faa..00000000000
--- a/tests/ui/intrinsics/always-extern.stderr
+++ /dev/null
@@ -1,34 +0,0 @@
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/always-extern.rs:4:32
- |
-LL | extern "rust-intrinsic" fn foo(&self);
- | ^^^
-
-error[E0093]: unrecognized intrinsic function: `hello`
- --> $DIR/always-extern.rs:12:28
- |
-LL | extern "rust-intrinsic" fn hello() {
- | ^^^^^ unrecognized intrinsic
- |
- = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type`
-
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/always-extern.rs:8:43
- |
-LL | extern "rust-intrinsic" fn foo(&self) {
- | ___________________________________________^
-LL | | }
- | |_____^
-
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/always-extern.rs:12:36
- |
-LL | extern "rust-intrinsic" fn hello() {
- | ____________________________________^
-LL | |
-LL | | }
- | |_^
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0093`.
diff --git a/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs b/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs
index f3b9d569ce3..1014ac6f560 100644
--- a/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs
+++ b/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs
@@ -1,14 +1,11 @@
#![feature(intrinsics)]
pub mod rusti {
- extern "rust-intrinsic" {
- pub fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T;
- }
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T;
}
#[inline(always)]
pub fn atomic_xchg_seqcst(dst: *mut isize, src: isize) -> isize {
- unsafe {
- rusti::atomic_xchg_seqcst(dst, src)
- }
+ unsafe { rusti::atomic_xchg_seqcst(dst, src) }
}
diff --git a/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs b/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs
index 5520430e140..e9f9270de87 100644
--- a/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs
+++ b/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs
@@ -1,7 +1,8 @@
fn main() {
read_via_copy();
+ //~^ ERROR call to unsafe function `read_via_copy` is unsafe and requires unsafe function or block
}
-extern "rust-intrinsic" fn read_via_copy() {}
-//~^ ERROR "rust-intrinsic" ABI is an implementation detail
-//~| ERROR intrinsic must be in `extern "rust-intrinsic" { ... }` block
+#[rustc_intrinsic]
+//~^ ERROR the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items
+unsafe fn read_via_copy() {}
diff --git a/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr b/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr
index c6682693f74..6711c77a11e 100644
--- a/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr
+++ b/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr
@@ -1,18 +1,21 @@
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/incorrect-read_via_copy-defn.rs:5:8
+error[E0658]: the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items
+ --> $DIR/incorrect-read_via_copy-defn.rs:6:1
|
-LL | extern "rust-intrinsic" fn read_via_copy() {}
- | ^^^^^^^^^^^^^^^^
+LL | #[rustc_intrinsic]
+ | ^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/incorrect-read_via_copy-defn.rs:5:44
+error[E0133]: call to unsafe function `read_via_copy` is unsafe and requires unsafe function or block
+ --> $DIR/incorrect-read_via_copy-defn.rs:2:5
|
-LL | extern "rust-intrinsic" fn read_via_copy() {}
- | ^^
+LL | read_via_copy();
+ | ^^^^^^^^^^^^^^^ call to unsafe function
+ |
+ = note: consult the function's documentation for information on how to avoid undefined behavior
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/intrinsics/incorrect-transmute.rs b/tests/ui/intrinsics/incorrect-transmute.rs
index 15d1ab939ed..25fbc7a92ee 100644
--- a/tests/ui/intrinsics/incorrect-transmute.rs
+++ b/tests/ui/intrinsics/incorrect-transmute.rs
@@ -1,7 +1,8 @@
fn main() {
transmute(); // does not ICE
+ //~^ ERROR call to unsafe function `transmute` is unsafe and requires unsafe function or block
}
-extern "rust-intrinsic" fn transmute() {}
-//~^ ERROR "rust-intrinsic" ABI is an implementation detail
-//~| ERROR intrinsic must be in `extern "rust-intrinsic" { ... }` block
+#[rustc_intrinsic]
+//~^ ERROR the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items
+unsafe fn transmute() {}
diff --git a/tests/ui/intrinsics/incorrect-transmute.stderr b/tests/ui/intrinsics/incorrect-transmute.stderr
index 99dfb9847ff..6145a11c4ae 100644
--- a/tests/ui/intrinsics/incorrect-transmute.stderr
+++ b/tests/ui/intrinsics/incorrect-transmute.stderr
@@ -1,18 +1,21 @@
-error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable
- --> $DIR/incorrect-transmute.rs:5:8
+error[E0658]: the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items
+ --> $DIR/incorrect-transmute.rs:6:1
|
-LL | extern "rust-intrinsic" fn transmute() {}
- | ^^^^^^^^^^^^^^^^
+LL | #[rustc_intrinsic]
+ | ^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(intrinsics)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/incorrect-transmute.rs:5:40
+error[E0133]: call to unsafe function `transmute` is unsafe and requires unsafe function or block
+ --> $DIR/incorrect-transmute.rs:2:5
|
-LL | extern "rust-intrinsic" fn transmute() {}
- | ^^
+LL | transmute(); // does not ICE
+ | ^^^^^^^^^^^ call to unsafe function
+ |
+ = note: consult the function's documentation for information on how to avoid undefined behavior
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/intrinsics/intrinsic-atomics.rs b/tests/ui/intrinsics/intrinsic-atomics.rs
index 4ad267e3ddb..6bc3f8d884d 100644
--- a/tests/ui/intrinsics/intrinsic-atomics.rs
+++ b/tests/ui/intrinsics/intrinsic-atomics.rs
@@ -2,33 +2,51 @@
#![feature(intrinsics)]
mod rusti {
- extern "rust-intrinsic" {
- pub fn atomic_cxchg_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool);
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_cxchg_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool);
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_cxchg_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool);
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_cxchg_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_load_seqcst(src: *const T) -> T;
- pub fn atomic_load_acquire(src: *const T) -> T;
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_cxchgweak_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool);
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_cxchgweak_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool);
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_cxchgweak_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_store_seqcst(dst: *mut T, val: T);
- pub fn atomic_store_release(dst: *mut T, val: T);
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_load_seqcst(src: *const T) -> T;
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_load_acquire(src: *const T) -> T;
- pub fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T;
- pub fn atomic_xchg_acquire(dst: *mut T, src: T) -> T;
- pub fn atomic_xchg_release(dst: *mut T, src: T) -> T;
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_store_seqcst(dst: *mut T, val: T);
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_store_release(dst: *mut T, val: T);
- pub fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd_acquire(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd_release(dst: *mut T, src: T) -> T;
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T;
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_xchg_acquire(dst: *mut T, src: T) -> T;
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_xchg_release(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_seqcst(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_acquire(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_release(dst: *mut T, src: T) -> T;
- }
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T;
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_xadd_acquire(dst: *mut T, src: T) -> T;
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_xadd_release(dst: *mut T, src: T) -> T;
+
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_xsub_seqcst(dst: *mut T, src: T) -> T;
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_xsub_acquire(dst: *mut T, src: T) -> T;
+ #[rustc_intrinsic]
+ pub unsafe fn atomic_xsub_release(dst: *mut T, src: T) -> T;
}
pub fn main() {
@@ -39,9 +57,9 @@ pub fn main() {
*x = 5;
assert_eq!(rusti::atomic_load_acquire(&*x), 5);
- rusti::atomic_store_seqcst(&mut *x,3);
+ rusti::atomic_store_seqcst(&mut *x, 3);
assert_eq!(*x, 3);
- rusti::atomic_store_release(&mut *x,1);
+ rusti::atomic_store_release(&mut *x, 1);
assert_eq!(*x, 1);
assert_eq!(rusti::atomic_cxchg_seqcst_seqcst(&mut *x, 1, 2), (1, true));
diff --git a/tests/ui/intrinsics/invalid-ABI-rust-intrinsic.rs b/tests/ui/intrinsics/invalid-ABI-rust-intrinsic.rs
new file mode 100644
index 00000000000..4b777deb8b5
--- /dev/null
+++ b/tests/ui/intrinsics/invalid-ABI-rust-intrinsic.rs
@@ -0,0 +1,19 @@
+#![feature(intrinsics)]
+
+trait Foo {
+ extern "rust-intrinsic" fn foo(&self); //~ ERROR invalid ABI
+}
+
+impl Foo for () {
+ extern "rust-intrinsic" fn foo(&self) { //~ ERROR invalid ABI
+ }
+}
+
+extern "rust-intrinsic" fn hello() { //~ ERROR invalid ABI
+}
+
+extern "rust-intrinsic" {
+ //~^ ERROR invalid ABI
+}
+
+fn main() {}
diff --git a/tests/ui/intrinsics/invalid-ABI-rust-intrinsic.stderr b/tests/ui/intrinsics/invalid-ABI-rust-intrinsic.stderr
new file mode 100644
index 00000000000..fc8bf62915b
--- /dev/null
+++ b/tests/ui/intrinsics/invalid-ABI-rust-intrinsic.stderr
@@ -0,0 +1,35 @@
+error[E0703]: invalid ABI: found `rust-intrinsic`
+ --> $DIR/invalid-ABI-rust-intrinsic.rs:4:12
+ |
+LL | extern "rust-intrinsic" fn foo(&self);
+ | ^^^^^^^^^^^^^^^^ invalid ABI
+ |
+ = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+
+error[E0703]: invalid ABI: found `rust-intrinsic`
+ --> $DIR/invalid-ABI-rust-intrinsic.rs:8:12
+ |
+LL | extern "rust-intrinsic" fn foo(&self) {
+ | ^^^^^^^^^^^^^^^^ invalid ABI
+ |
+ = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+
+error[E0703]: invalid ABI: found `rust-intrinsic`
+ --> $DIR/invalid-ABI-rust-intrinsic.rs:12:8
+ |
+LL | extern "rust-intrinsic" fn hello() {
+ | ^^^^^^^^^^^^^^^^ invalid ABI
+ |
+ = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+
+error[E0703]: invalid ABI: found `rust-intrinsic`
+ --> $DIR/invalid-ABI-rust-intrinsic.rs:15:8
+ |
+LL | extern "rust-intrinsic" {
+ | ^^^^^^^^^^^^^^^^ invalid ABI
+ |
+ = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0703`.
diff --git a/tests/ui/intrinsics/issue-28575.rs b/tests/ui/intrinsics/issue-28575.rs
index 141136d25b2..841bc45138a 100644
--- a/tests/ui/intrinsics/issue-28575.rs
+++ b/tests/ui/intrinsics/issue-28575.rs
@@ -2,6 +2,7 @@
extern "C" {
pub static FOO: extern "rust-intrinsic" fn();
+ //~^ ERROR invalid ABI
}
fn main() {
diff --git a/tests/ui/intrinsics/issue-28575.stderr b/tests/ui/intrinsics/issue-28575.stderr
index 8a7816f231f..09c52aa4c99 100644
--- a/tests/ui/intrinsics/issue-28575.stderr
+++ b/tests/ui/intrinsics/issue-28575.stderr
@@ -1,11 +1,20 @@
+error[E0703]: invalid ABI: found `rust-intrinsic`
+ --> $DIR/issue-28575.rs:4:28
+ |
+LL | pub static FOO: extern "rust-intrinsic" fn();
+ | ^^^^^^^^^^^^^^^^ invalid ABI
+ |
+ = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+
error[E0133]: use of extern static is unsafe and requires unsafe function or block
- --> $DIR/issue-28575.rs:8:5
+ --> $DIR/issue-28575.rs:9:5
|
LL | FOO()
| ^^^ use of extern static
|
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0133`.
+Some errors have detailed explanations: E0133, E0703.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
index 915a23b5905..4c301f9dbb0 100644
--- a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
+++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
@@ -1,13 +1,14 @@
#![feature(intrinsics)]
#![feature(rustc_attrs)]
-extern "rust-intrinsic" {
- fn size_of() -> usize; //~ ERROR intrinsic safety mismatch
- //~^ ERROR intrinsic safety mismatch
-}
+#[rustc_intrinsic]
+unsafe fn size_of() -> usize;
+//~^ ERROR intrinsic safety mismatch
+//~| ERROR intrinsic has wrong type
#[rustc_intrinsic]
-const fn assume(_b: bool) {} //~ ERROR intrinsic safety mismatch
+const fn assume(_b: bool) {}
+//~^ ERROR intrinsic safety mismatch
//~| ERROR intrinsic has wrong type
#[rustc_intrinsic]
diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
index aa4f294232d..04f6daeced2 100644
--- a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
+++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
@@ -1,16 +1,17 @@
error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
- --> $DIR/safe-intrinsic-mismatch.rs:5:5
+ --> $DIR/safe-intrinsic-mismatch.rs:5:1
|
-LL | fn size_of() -> usize;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | unsafe fn size_of() -> usize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
- --> $DIR/safe-intrinsic-mismatch.rs:5:5
+error[E0308]: intrinsic has wrong type
+ --> $DIR/safe-intrinsic-mismatch.rs:5:18
|
-LL | fn size_of() -> usize;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | unsafe fn size_of() -> usize;
+ | ^^^ expected safe fn, found unsafe fn
|
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+ = note: expected signature `fn() -> _`
+ found signature `unsafe fn() -> _`
error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume`
--> $DIR/safe-intrinsic-mismatch.rs:10:1
@@ -28,13 +29,13 @@ LL | const fn assume(_b: bool) {}
found signature `fn(_)`
error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `const_deallocate`
- --> $DIR/safe-intrinsic-mismatch.rs:14:1
+ --> $DIR/safe-intrinsic-mismatch.rs:15:1
|
LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: intrinsic has wrong type
- --> $DIR/safe-intrinsic-mismatch.rs:14:26
+ --> $DIR/safe-intrinsic-mismatch.rs:15:26
|
LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
| ^ expected unsafe fn, found safe fn
diff --git a/tests/ui/lint/internal_features.rs b/tests/ui/lint/internal_features.rs
index 32ce9540cb3..6456078a5c2 100644
--- a/tests/ui/lint/internal_features.rs
+++ b/tests/ui/lint/internal_features.rs
@@ -4,8 +4,7 @@
//~^ ERROR: internal
//~| ERROR: internal
-extern "rust-intrinsic" {
- fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize);
-}
+#[rustc_intrinsic]
+unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize);
fn main() {}
diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs
index 40033f546d3..3490d3efc59 100644
--- a/tests/ui/macros/stringify.rs
+++ b/tests/ui/macros/stringify.rs
@@ -515,6 +515,8 @@ fn test_meta() {
#[test]
fn test_pat() {
+ // PatKind::Missing: untestable in isolation.
+
// PatKind::Wild
c1!(pat, [ _ ], "_");
diff --git a/tests/ui/print-calling-conventions.stdout b/tests/ui/print-calling-conventions.stdout
index 539b2d5dee4..feee8cc3aa9 100644
--- a/tests/ui/print-calling-conventions.stdout
+++ b/tests/ui/print-calling-conventions.stdout
@@ -19,7 +19,6 @@ riscv-interrupt-m
riscv-interrupt-s
rust-call
rust-cold
-rust-intrinsic
stdcall
stdcall-unwind
system
diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr
index 24e38948647..b369af62f87 100644
--- a/tests/ui/stats/input-stats.stderr
+++ b/tests/ui/stats/input-stats.stderr
@@ -5,25 +5,25 @@ ast-stats-1 Crate 40 ( 0.6%) 1 40
ast-stats-1 GenericArgs 40 ( 0.6%) 1 40
ast-stats-1 - AngleBracketed 40 ( 0.6%) 1
ast-stats-1 ExprField 48 ( 0.7%) 1 48
-ast-stats-1 Attribute 64 ( 1.0%) 2 32
+ast-stats-1 Attribute 64 ( 0.9%) 2 32
ast-stats-1 - DocComment 32 ( 0.5%) 1
ast-stats-1 - Normal 32 ( 0.5%) 1
ast-stats-1 WherePredicate 72 ( 1.1%) 1 72
ast-stats-1 - BoundPredicate 72 ( 1.1%) 1
ast-stats-1 ForeignItem 80 ( 1.2%) 1 80
ast-stats-1 - Fn 80 ( 1.2%) 1
-ast-stats-1 Local 80 ( 1.2%) 1 80
ast-stats-1 Arm 96 ( 1.4%) 2 48
+ast-stats-1 Local 96 ( 1.4%) 1 96
ast-stats-1 FnDecl 120 ( 1.8%) 5 24
ast-stats-1 Param 160 ( 2.4%) 4 40
ast-stats-1 Stmt 160 ( 2.4%) 5 32
ast-stats-1 - Let 32 ( 0.5%) 1
ast-stats-1 - MacCall 32 ( 0.5%) 1
ast-stats-1 - Expr 96 ( 1.4%) 3
-ast-stats-1 Block 192 ( 2.9%) 6 32
+ast-stats-1 Block 192 ( 2.8%) 6 32
ast-stats-1 FieldDef 208 ( 3.1%) 2 104
ast-stats-1 Variant 208 ( 3.1%) 2 104
-ast-stats-1 AssocItem 320 ( 4.8%) 4 80
+ast-stats-1 AssocItem 320 ( 4.7%) 4 80
ast-stats-1 - Fn 160 ( 2.4%) 2
ast-stats-1 - Type 160 ( 2.4%) 2
ast-stats-1 GenericBound 352 ( 5.2%) 4 88
@@ -33,7 +33,7 @@ ast-stats-1 Pat 504 ( 7.5%) 7 72
ast-stats-1 - Struct 72 ( 1.1%) 1
ast-stats-1 - Wild 72 ( 1.1%) 1
ast-stats-1 - Ident 360 ( 5.3%) 5
-ast-stats-1 Expr 576 ( 8.6%) 8 72
+ast-stats-1 Expr 576 ( 8.5%) 8 72
ast-stats-1 - Match 72 ( 1.1%) 1
ast-stats-1 - Path 72 ( 1.1%) 1
ast-stats-1 - Struct 72 ( 1.1%) 1
@@ -41,8 +41,8 @@ ast-stats-1 - Lit 144 ( 2.1%) 2
ast-stats-1 - Block 216 ( 3.2%) 3
ast-stats-1 PathSegment 744 (11.0%) 31 24
ast-stats-1 Ty 896 (13.3%) 14 64
-ast-stats-1 - Ptr 64 ( 1.0%) 1
-ast-stats-1 - Ref 64 ( 1.0%) 1
+ast-stats-1 - Ptr 64 ( 0.9%) 1
+ast-stats-1 - Ref 64 ( 0.9%) 1
ast-stats-1 - ImplicitSelf 128 ( 1.9%) 2
ast-stats-1 - Path 640 ( 9.5%) 10
ast-stats-1 Item 1_296 (19.2%) 9 144
@@ -53,7 +53,7 @@ ast-stats-1 - Trait 144 ( 2.1%) 1
ast-stats-1 - Fn 288 ( 4.3%) 2
ast-stats-1 - Use 432 ( 6.4%) 3
ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total 6_736 116
+ast-stats-1 Total 6_752 116
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size
@@ -66,8 +66,8 @@ ast-stats-2 WherePredicate 72 ( 1.0%) 1 72
ast-stats-2 - BoundPredicate 72 ( 1.0%) 1
ast-stats-2 ForeignItem 80 ( 1.1%) 1 80
ast-stats-2 - Fn 80 ( 1.1%) 1
-ast-stats-2 Local 80 ( 1.1%) 1 80
ast-stats-2 Arm 96 ( 1.3%) 2 48
+ast-stats-2 Local 96 ( 1.3%) 1 96
ast-stats-2 FnDecl 120 ( 1.6%) 5 24
ast-stats-2 InlineAsm 120 ( 1.6%) 1 120
ast-stats-2 Attribute 128 ( 1.7%) 4 32
@@ -84,14 +84,14 @@ ast-stats-2 Variant 208 ( 2.8%) 2 104
ast-stats-2 AssocItem 320 ( 4.3%) 4 80
ast-stats-2 - Fn 160 ( 2.2%) 2
ast-stats-2 - Type 160 ( 2.2%) 2
-ast-stats-2 GenericBound 352 ( 4.8%) 4 88
-ast-stats-2 - Trait 352 ( 4.8%) 4
+ast-stats-2 GenericBound 352 ( 4.7%) 4 88
+ast-stats-2 - Trait 352 ( 4.7%) 4
ast-stats-2 GenericParam 480 ( 6.5%) 5 96
ast-stats-2 Pat 504 ( 6.8%) 7 72
ast-stats-2 - Struct 72 ( 1.0%) 1
ast-stats-2 - Wild 72 ( 1.0%) 1
ast-stats-2 - Ident 360 ( 4.9%) 5
-ast-stats-2 Expr 648 ( 8.8%) 9 72
+ast-stats-2 Expr 648 ( 8.7%) 9 72
ast-stats-2 - InlineAsm 72 ( 1.0%) 1
ast-stats-2 - Match 72 ( 1.0%) 1
ast-stats-2 - Path 72 ( 1.0%) 1
@@ -113,7 +113,7 @@ ast-stats-2 - Trait 144 ( 1.9%) 1
ast-stats-2 - Fn 288 ( 3.9%) 2
ast-stats-2 - Use 576 ( 7.8%) 4
ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total 7_400 127
+ast-stats-2 Total 7_416 127
ast-stats-2
hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size
@@ -126,11 +126,11 @@ hir-stats TraitItemRef 56 ( 0.6%) 2 28
hir-stats GenericArg 64 ( 0.7%) 4 16
hir-stats - Type 16 ( 0.2%) 1
hir-stats - Lifetime 48 ( 0.5%) 3
-hir-stats Local 64 ( 0.7%) 1 64
hir-stats Param 64 ( 0.7%) 2 32
hir-stats Body 72 ( 0.8%) 3 24
hir-stats ImplItemRef 72 ( 0.8%) 2 36
hir-stats InlineAsm 72 ( 0.8%) 1 72
+hir-stats Local 72 ( 0.8%) 1 72
hir-stats WherePredicate 72 ( 0.8%) 3 24
hir-stats - BoundPredicate 72 ( 0.8%) 3
hir-stats Arm 80 ( 0.9%) 2 40
@@ -143,8 +143,8 @@ hir-stats Attribute 128 ( 1.4%) 4 32
hir-stats FieldDef 128 ( 1.4%) 2 64
hir-stats GenericArgs 144 ( 1.6%) 3 48
hir-stats Variant 144 ( 1.6%) 2 72
-hir-stats GenericBound 256 ( 2.9%) 4 64
-hir-stats - Trait 256 ( 2.9%) 4
+hir-stats GenericBound 256 ( 2.8%) 4 64
+hir-stats - Trait 256 ( 2.8%) 4
hir-stats Block 288 ( 3.2%) 6 48
hir-stats Pat 360 ( 4.0%) 5 72
hir-stats - Struct 72 ( 0.8%) 1
@@ -156,7 +156,7 @@ hir-stats Ty 720 ( 8.0%) 15 48
hir-stats - Ptr 48 ( 0.5%) 1
hir-stats - Ref 48 ( 0.5%) 1
hir-stats - Path 624 ( 6.9%) 13
-hir-stats Expr 768 ( 8.6%) 12 64
+hir-stats Expr 768 ( 8.5%) 12 64
hir-stats - InlineAsm 64 ( 0.7%) 1
hir-stats - Match 64 ( 0.7%) 1
hir-stats - Path 64 ( 0.7%) 1
@@ -174,5 +174,5 @@ hir-stats - Use 352 ( 3.9%) 4
hir-stats Path 1_240 (13.8%) 31 40
hir-stats PathSegment 1_920 (21.4%) 40 48
hir-stats ----------------------------------------------------------------
-hir-stats Total 8_980 180
+hir-stats Total 8_988 180
hir-stats
diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.stderr
index 7b0fd979991..e189012d15c 100644
--- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.stderr
+++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021-without-dyn.stderr
@@ -26,6 +26,20 @@ help: `A` is dyn-incompatible, use `impl A` to return an opaque type, as long as
LL | fn f(a: A) -> impl A;
| ++++
+error: associated item referring to unboxed trait object for its own trait
+ --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:4:13
+ |
+LL | trait A: Sized {
+ | - in this trait
+LL | fn f(a: A) -> A;
+ | ^ ^
+ |
+help: you might have meant to use `Self` to refer to the implementing type
+ |
+LL - fn f(a: A) -> A;
+LL + fn f(a: Self) -> Self;
+ |
+
error[E0782]: expected a type, found a trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:10:13
|
@@ -54,6 +68,20 @@ help: `B` is dyn-incompatible, use `impl B` to return an opaque type, as long as
LL | fn f(b: B) -> impl B;
| ++++
+error: associated item referring to unboxed trait object for its own trait
+ --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:10:13
+ |
+LL | trait B {
+ | - in this trait
+LL | fn f(b: B) -> B;
+ | ^ ^
+ |
+help: you might have meant to use `Self` to refer to the implementing type
+ |
+LL - fn f(b: B) -> B;
+LL + fn f(b: Self) -> Self;
+ |
+
error[E0782]: expected a type, found a trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:16:20
|
@@ -82,34 +110,6 @@ help: `C` is dyn-incompatible, use `impl C` to return an opaque type, as long as
LL | fn f(&self, c: C) -> impl C;
| ++++
-error: associated item referring to unboxed trait object for its own trait
- --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:4:13
- |
-LL | trait A: Sized {
- | - in this trait
-LL | fn f(a: A) -> A;
- | ^ ^
- |
-help: you might have meant to use `Self` to refer to the implementing type
- |
-LL - fn f(a: A) -> A;
-LL + fn f(a: Self) -> Self;
- |
-
-error: associated item referring to unboxed trait object for its own trait
- --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:10:13
- |
-LL | trait B {
- | - in this trait
-LL | fn f(b: B) -> B;
- | ^ ^
- |
-help: you might have meant to use `Self` to refer to the implementing type
- |
-LL - fn f(b: B) -> B;
-LL + fn f(b: Self) -> Self;
- |
-
error: associated item referring to unboxed trait object for its own trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:16:20
|
diff --git a/tests/ui/suggestions/issue-116434-2015.stderr b/tests/ui/suggestions/issue-116434-2015.stderr
index e7b8cd2f101..07a254432a2 100644
--- a/tests/ui/suggestions/issue-116434-2015.stderr
+++ b/tests/ui/suggestions/issue-116434-2015.stderr
@@ -12,19 +12,6 @@ help: if this is a dyn-compatible trait, use `dyn`
LL | fn foo() -> dyn Clone;
| +++
-warning: trait objects without an explicit `dyn` are deprecated
- --> $DIR/issue-116434-2015.rs:18:20
- |
-LL | fn handle() -> DbHandle;
- | ^^^^^^^^
- |
- = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see
-help: if this is a dyn-compatible trait, use `dyn`
- |
-LL | fn handle() -> dyn DbHandle;
- | +++
-
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-116434-2015.rs:3:17
|
@@ -53,6 +40,19 @@ help: there is an associated type with the same name
LL | fn foo() -> Self::Clone;
| ++++++
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/issue-116434-2015.rs:18:20
+ |
+LL | fn handle() -> DbHandle;
+ | ^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see
+help: if this is a dyn-compatible trait, use `dyn`
+ |
+LL | fn handle() -> dyn DbHandle;
+ | +++
+
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-116434-2015.rs:18:20
|
diff --git a/tests/ui/super-let.borrowck.stderr b/tests/ui/super-let.borrowck.stderr
new file mode 100644
index 00000000000..01ef29d8758
--- /dev/null
+++ b/tests/ui/super-let.borrowck.stderr
@@ -0,0 +1,174 @@
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:30:28
+ |
+LL | super let b = DropMe(&mut x);
+ | ------ `x` is borrowed here
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | }
+ | - borrow might be used here, when `b` is dropped and runs the `Drop` code for type `DropMe`
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:46:28
+ |
+LL | super let b = &DropMe(&mut x);
+ | --------------
+ | | |
+ | | `x` is borrowed here
+ | a temporary with access to the borrow is created here ...
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | }
+ | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DropMe`
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:64:32
+ |
+LL | super let b = identity(&DropMe(&mut x));
+ | --------------
+ | | |
+ | | `x` is borrowed here
+ | a temporary with access to the borrow is created here ...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | };
+ | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DropMe`
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:87:36
+ |
+LL | super let b = identity(&DropMe(&mut x));
+ | --------------
+ | | |
+ | | `x` is borrowed here
+ | a temporary with access to the borrow is created here ...
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | ));
+ | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DropMe`
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:107:28
+ |
+LL | super let b = DropMe(&mut x);
+ | ------ `x` is borrowed here
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | }
+ | - borrow might be used here, when `b` is dropped and runs the `Drop` code for type `DropMe`
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:125:28
+ |
+LL | super let b = DropMe(&mut x);
+ | ------ `x` is borrowed here
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | }
+ | - borrow might be used here, when `b` is dropped and runs the `Drop` code for type `DropMe`
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:143:28
+ |
+LL | super let b = DropMe(&mut x);
+ | ------ `x` is borrowed here
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | }
+ | - borrow might be used here, when `b` is dropped and runs the `Drop` code for type `DropMe`
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:159:28
+ |
+LL | b = DropMe(&mut x);
+ | ------ `x` is borrowed here
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+LL | drop(a);
+ | - borrow later used here
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/super-let.rs:172:33
+ |
+LL | #[cfg(borrowck)] { a = &String::from("asdf"); };
+ | ^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
+ | |
+ | creates a temporary value which is freed while still in use
+...
+LL | let _ = a;
+ | - borrow later used here
+ |
+ = note: consider using a `let` binding to create a longer lived value
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:206:28
+ |
+LL | super let d = &DropMe(&mut x);
+ | --------------
+ | | |
+ | | `x` is borrowed here
+ | a temporary with access to the borrow is created here ...
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | }
+ | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DropMe`
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:227:32
+ |
+LL | super let d = identity(&DropMe(&mut x));
+ | --------------
+ | | |
+ | | `x` is borrowed here
+ | a temporary with access to the borrow is created here ...
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | };
+ | - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DropMe`
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:246:28
+ |
+LL | super let b = DropMe(&mut x);
+ | ------ `x` is borrowed here
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | }
+ | - borrow might be used here, when `b` is dropped and runs the `Drop` code for type `DropMe`
+
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/super-let.rs:263:28
+ |
+LL | let dropme = Some(DropMe(&mut x));
+ | ------ `x` is borrowed here
+...
+LL | #[cfg(borrowck)] { x = true; }
+ | ^^^^^^^^ `x` is assigned to here but it was already borrowed
+...
+LL | }
+ | - borrow might be used here, when `x` is dropped and runs the `Drop` code for type `DropMe`
+
+error: aborting due to 13 previous errors
+
+Some errors have detailed explanations: E0506, E0716.
+For more information about an error, try `rustc --explain E0506`.
diff --git a/tests/ui/super-let.rs b/tests/ui/super-let.rs
new file mode 100644
index 00000000000..380470f792f
--- /dev/null
+++ b/tests/ui/super-let.rs
@@ -0,0 +1,286 @@
+// Check in two ways:
+// - borrowck: Check with borrow checking errors when things are alive and dead.
+// - runtime: Check with a mutable bool if things are dropped on time.
+//
+//@ revisions: runtime borrowck
+//@ [runtime] run-pass
+//@ [borrowck] check-fail
+
+#![allow(dropping_references)]
+#![feature(super_let, stmt_expr_attributes)]
+
+use std::convert::identity;
+
+struct DropMe<'a>(&'a mut bool);
+
+impl Drop for DropMe<'_> {
+ fn drop(&mut self) {
+ *self.0 = true;
+ }
+}
+
+// Check that a super let variable lives as long as the result of a block.
+fn extended_variable() {
+ let mut x = false;
+ {
+ let a = {
+ super let b = DropMe(&mut x);
+ &b
+ };
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ drop(a);
+ // DropMe is still alive here...
+ }
+ // ... but not here.
+ assert_eq!(x, true) // ok
+}
+
+// Check that the init expression of a super let is subject to (temporary) lifetime extension.
+fn extended_temporary() {
+ let mut x = false;
+ {
+ let a = {
+ super let b = &DropMe(&mut x);
+ b
+ };
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ drop(a);
+ // DropMe is still alive here...
+ }
+ // ... but not here.
+ assert_eq!(x, true); // ok
+}
+
+// Check that even non-extended temporaries live until the end of the block,
+// but (unlike extended temporaries) not beyond that.
+//
+// This is necessary for things like select(pin!(identity(&temp()))) to work.
+fn non_extended() {
+ let mut x = false;
+ {
+ let _a = {
+ // Use identity() to supress temporary lifetime extension.
+ super let b = identity(&DropMe(&mut x));
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ b
+ // DropMe is still alive here...
+ };
+ // ... but not here.
+ assert_eq!(x, true); // ok
+ }
+}
+
+// Check that even non-extended temporaries live until the end of the block,
+// but (unlike extended temporaries) not beyond that.
+//
+// This is necessary for things like select(pin!(identity(&temp()))) to work.
+fn non_extended_in_expression() {
+ let mut x = false;
+ {
+ identity((
+ {
+ // Use identity() to supress temporary lifetime extension.
+ super let b = identity(&DropMe(&mut x));
+ b
+ },
+ {
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ // DropMe is still alive here...
+ }
+ ));
+ // ... but not here.
+ assert_eq!(x, true); // ok
+ }
+}
+
+// Check `super let` in a match arm.
+fn match_arm() {
+ let mut x = false;
+ {
+ let a = match Some(123) {
+ Some(_) => {
+ super let b = DropMe(&mut x);
+ &b
+ }
+ None => unreachable!(),
+ };
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ drop(a);
+ // DropMe is still alive here...
+ }
+ // ... but not here.
+ assert_eq!(x, true); // ok
+}
+
+// Check `super let` in an if body.
+fn if_body() {
+ let mut x = false;
+ {
+ let a = if true {
+ super let b = DropMe(&mut x);
+ &b
+ } else {
+ unreachable!()
+ };
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ drop(a);
+ // DropMe is still alive here...
+ }
+ // ... but not here.
+ assert_eq!(x, true); // ok
+}
+
+// Check `super let` in an else body.
+fn else_body() {
+ let mut x = false;
+ {
+ let a = if false {
+ unreachable!()
+ } else {
+ super let b = DropMe(&mut x);
+ &b
+ };
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ drop(a);
+ // DropMe is still alive here...
+ }
+ // ... but not here.
+ assert_eq!(x, true); // ok
+}
+
+fn without_initializer() {
+ let mut x = false;
+ {
+ let a = {
+ super let b;
+ b = DropMe(&mut x);
+ b
+ };
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ drop(a);
+ // DropMe is still alive here...
+ }
+ // ... but not here.
+ assert_eq!(x, true);
+}
+
+// Assignment isn't special, even when assigning to a `super let` variable.
+fn assignment() {
+ let mut x = false;
+ {
+ super let a;
+ #[cfg(borrowck)] { a = &String::from("asdf"); }; //[borrowck]~ ERROR dropped while borrowed
+ #[cfg(runtime)] { a = drop(&DropMe(&mut x)); } // Temporary dropped at the `;` as usual.
+ assert_eq!(x, true);
+ let _ = a;
+ }
+}
+
+// `super let mut` should work just fine.
+fn mutable() {
+ let mut x = false;
+ {
+ let a = {
+ super let mut b = None;
+ &mut b
+ };
+ *a = Some(DropMe(&mut x));
+ }
+ assert_eq!(x, true);
+}
+
+// Temporary lifetime extension should recurse through `super let`s.
+fn multiple_levels() {
+ let mut x = false;
+ {
+ let a = {
+ super let b = {
+ super let c = {
+ super let d = &DropMe(&mut x);
+ d
+ };
+ c
+ };
+ b
+ };
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ drop(a);
+ // DropMe is still alive here...
+ }
+ // ... but not here.
+ assert_eq!(x, true);
+}
+
+// Non-extended temporaries should be dropped at the
+// end of the first parent statement that isn't `super`.
+fn multiple_levels_but_no_extension() {
+ let mut x = false;
+ {
+ let _a = {
+ super let b = {
+ super let c = {
+ super let d = identity(&DropMe(&mut x));
+ d
+ };
+ c
+ };
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ b
+ // DropMe is still alive here...
+ };
+ // ... but not here.
+ assert_eq!(x, true);
+ }
+}
+
+// Check for potential weird interactions with `let else`.
+fn super_let_and_let_else() {
+ let mut x = false;
+ {
+ let a = 'a: {
+ let Some(_) = Some(123) else { unreachable!() };
+ super let b = DropMe(&mut x);
+ let None = Some(123) else { break 'a &b };
+ unreachable!()
+ };
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ // DropMe is still alive here...
+ drop(a);
+ }
+ // ... but not here.
+ assert_eq!(x, true);
+}
+
+// Check if `super let .. else ..;` works.
+fn super_let_else() {
+ let mut x = false;
+ {
+ let a = {
+ let dropme = Some(DropMe(&mut x));
+ super let Some(x) = dropme else { unreachable!() };
+ &x
+ };
+ #[cfg(borrowck)] { x = true; } //[borrowck]~ ERROR borrowed
+ // DropMe is still alive here...
+ drop(a);
+ }
+ // ... but not here.
+ assert_eq!(x, true);
+}
+
+fn main() {
+ extended_variable();
+ extended_temporary();
+ non_extended();
+ non_extended_in_expression();
+ match_arm();
+ if_body();
+ else_body();
+ without_initializer();
+ assignment();
+ mutable();
+ multiple_levels();
+ multiple_levels_but_no_extension();
+ super_let_and_let_else();
+ super_let_else();
+}
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index 2a4a5a62ab4..7184244f5dc 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -439,6 +439,18 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) }
| | not allowed in type signatures
| help: replace with the correct return type: `(i32, i32)`
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs
+ --> $DIR/typeck_type_placeholder_item.rs:154:21
+ |
+LL | struct BadStruct<_>(_);
+ | ^ not allowed in type signatures
+ |
+help: use type parameters instead
+ |
+LL - struct BadStruct<_>(_);
+LL + struct BadStruct(T);
+ |
+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
--> $DIR/typeck_type_placeholder_item.rs:140:31
|
@@ -515,18 +527,6 @@ LL - fn assoc_fn_test3() -> _;
LL + fn assoc_fn_test3() -> T;
|
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs
- --> $DIR/typeck_type_placeholder_item.rs:154:21
- |
-LL | struct BadStruct<_>(_);
- | ^ not allowed in type signatures
- |
-help: use type parameters instead
- |
-LL - struct BadStruct<_>(_);
-LL + struct BadStruct(T);
- |
-
error[E0121]: the placeholder `_` is not allowed within types on item signatures for implementations
--> $DIR/typeck_type_placeholder_item.rs:159:15
|
diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs
index 31af323ecda..4d1f12e3490 100644
--- a/tests/ui/unpretty/expanded-exhaustive.rs
+++ b/tests/ui/unpretty/expanded-exhaustive.rs
@@ -574,6 +574,11 @@ mod items {
}
mod patterns {
+ /// PatKind::Missing
+ fn pat_missing() {
+ let _: fn(u32, T, &str);
+ }
+
/// PatKind::Wild
fn pat_wild() {
let _;
diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout
index 19ae66f7a07..d8da941a340 100644
--- a/tests/ui/unpretty/expanded-exhaustive.stdout
+++ b/tests/ui/unpretty/expanded-exhaustive.stdout
@@ -361,6 +361,7 @@ mod expressions {
+
{ builtin # offset_of(T, field) };
@@ -517,6 +518,8 @@ mod items {
}
}
mod patterns {
+ /// PatKind::Missing
+ fn pat_missing() { let _: fn(u32, T, &str); }
/// PatKind::Wild
fn pat_wild() { let _; }
/// PatKind::Ident
diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr
index 3b4de0753af..59eef0c6327 100644
--- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr
+++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr
@@ -53,6 +53,12 @@ LL | trait Trait {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:12
+ |
+LL | fn fnc(&self) -> Trait {
+ | ^^^^^^^^^^^^^^^^^^^^
+
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:44
|
@@ -66,12 +72,6 @@ help: if this is a dyn-compatible trait, use `dyn`
LL | fn fnc(&self) -> dyn Trait {
| +++
-error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
- --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:12
- |
-LL | fn fnc(&self) -> Trait {
- | ^^^^^^^^^^^^^^^^^^^^
-
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:21
|