diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index f6edcaa64dfef..be0a1d490da6a 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -312,7 +312,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir, AmbigArg>) { self.insert( - const_arg.as_unambig_ct().span(), + const_arg.as_unambig_ct().span, const_arg.hir_id, Node::ConstArg(const_arg.as_unambig_ct()), ); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e11e24c0263f4..a81d2297ef85b 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2285,8 +2285,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // `ExprKind::Paren(ExprKind::Underscore)` and should also be lowered to `GenericArg::Infer` match c.value.peel_parens().kind { ExprKind::Underscore => { - let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ()); - self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind }) + let ct_kind = hir::ConstArgKind::Infer(()); + self.arena.alloc(hir::ConstArg { + hir_id: self.lower_node_id(c.id), + kind: ct_kind, + span: self.lower_span(c.value.span), + }) } _ => self.lower_anon_const_to_const_arg_and_alloc(c), } @@ -2356,7 +2360,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::ConstArgKind::Anon(ct) }; - self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind }) + self.arena.alloc(hir::ConstArg { + hir_id: self.next_id(), + kind: ct_kind, + span: self.lower_span(span), + }) } fn lower_const_item_rhs( @@ -2373,9 +2381,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let const_arg = ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Error( - DUMMY_SP, self.dcx().span_delayed_bug(DUMMY_SP, "no block"), ), + span: DUMMY_SP, }; hir::ConstItemRhs::TypeConst(self.arena.alloc(const_arg)) } @@ -2388,13 +2396,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { #[instrument(level = "debug", skip(self), ret)] fn lower_expr_to_const_arg_direct(&mut self, expr: &Expr) -> hir::ConstArg<'hir> { + let span = self.lower_span(expr.span); + let overly_complex_const = |this: &mut Self| { let e = this.dcx().struct_span_err( expr.span, "complex const arguments must be placed inside of a `const` block", ); - ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(expr.span, e.emit()) } + ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(e.emit()), span } }; match &expr.kind { @@ -2425,8 +2435,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::TupleCall(qpath, lowered_args), + span, } } + ExprKind::Tup(exprs) => { + let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| { + let expr = if let ExprKind::ConstBlock(anon_const) = &expr.kind { + let def_id = self.local_def_id(anon_const.id); + let def_kind = self.tcx.def_kind(def_id); + assert_eq!(DefKind::AnonConst, def_kind); + + self.lower_anon_const_to_const_arg(anon_const) + } else { + self.lower_expr_to_const_arg_direct(&expr) + }; + + &*self.arena.alloc(expr) + })); + + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Tup(exprs), span } + } ExprKind::Path(qself, path) => { let qpath = self.lower_qpath( expr.id, @@ -2439,7 +2467,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { None, ); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath) } + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath), span } } ExprKind::Struct(se) => { let path = self.lower_qpath( @@ -2480,11 +2508,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) })); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Struct(path, fields) } + ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Struct(path, fields), + span, + } } ExprKind::Underscore => ConstArg { hir_id: self.lower_node_id(expr.id), - kind: hir::ConstArgKind::Infer(expr.span, ()), + kind: hir::ConstArgKind::Infer(()), + span, }, ExprKind::Block(block, _) => { if let [stmt] = block.stmts.as_slice() @@ -2495,6 +2528,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | ExprKind::Path(..) | ExprKind::Struct(..) | ExprKind::Call(..) + | ExprKind::Tup(..) ) { return self.lower_expr_to_const_arg_direct(expr); @@ -2528,7 +2562,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { return match anon.mgca_disambiguation { MgcaDisambiguation::AnonConst => { let lowered_anon = self.lower_anon_const_to_anon_const(anon); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) } + ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Anon(lowered_anon), + span: lowered_anon.span, + } } MgcaDisambiguation::Direct => self.lower_expr_to_const_arg_direct(&anon.value), }; @@ -2565,11 +2603,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { return ConstArg { hir_id: self.lower_node_id(anon.id), kind: hir::ConstArgKind::Path(qpath), + span: self.lower_span(expr.span), }; } let lowered_anon = self.lower_anon_const_to_anon_const(anon); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) } + ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Anon(lowered_anon), + span: self.lower_span(expr.span), + } } /// See [`hir::ConstArg`] for when to use this function vs diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index f09bbb9c4972f..e066bce95158d 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -513,6 +513,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(self.arena.alloc(anon_const)), + span, }) } @@ -557,6 +558,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) }); let hir_id = self.next_id(); - self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id }) + self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id, span }) } } diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index a637ae8184b4f..85cb7499cca4e 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -1,4 +1,7 @@ -codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend. Did you install it via rustup? +codegen_llvm_autodiff_component_missing = autodiff backend not found in the sysroot: {$err} + .note = it will be distributed via rustup in the future + +codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend: {$err} codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index c73140e041b60..bd42cf5569664 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -34,7 +34,16 @@ impl Diagnostic<'_, G> for ParseTargetMachineConfig<'_> { #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_component_unavailable)] -pub(crate) struct AutoDiffComponentUnavailable; +pub(crate) struct AutoDiffComponentUnavailable { + pub err: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_llvm_autodiff_component_missing)] +#[note] +pub(crate) struct AutoDiffComponentMissing { + pub err: String, +} #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_without_lto)] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 0952747449932..438a74e0a0912 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -249,8 +249,14 @@ impl CodegenBackend for LlvmCodegenBackend { use crate::back::lto::enable_autodiff_settings; if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) { - if let Err(_) = llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) { - sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable); + match llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) { + Ok(_) => {} + Err(llvm::EnzymeLibraryError::NotFound { err }) => { + sess.dcx().emit_fatal(crate::errors::AutoDiffComponentMissing { err }); + } + Err(llvm::EnzymeLibraryError::LoadFailed { err }) => { + sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable { err }); + } } enable_autodiff_settings(&sess.opts.unstable_opts.autodiff); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index b11310b970d03..67fbc0f53adc9 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -153,7 +153,7 @@ pub(crate) mod Enzyme_AD { fn load_ptr_by_symbol_mut_void( lib: &libloading::Library, bytes: &[u8], - ) -> Result<*mut c_void, Box> { + ) -> Result<*mut c_void, libloading::Error> { unsafe { let s: libloading::Symbol<'_, *mut c_void> = lib.get(bytes)?; // libloading = 0.9.0: try_as_raw_ptr always succeeds and returns Some @@ -192,15 +192,27 @@ pub(crate) mod Enzyme_AD { static ENZYME_INSTANCE: OnceLock> = OnceLock::new(); + #[derive(Debug)] + pub(crate) enum EnzymeLibraryError { + NotFound { err: String }, + LoadFailed { err: String }, + } + + impl From for EnzymeLibraryError { + fn from(err: libloading::Error) -> Self { + Self::LoadFailed { err: format!("{err:?}") } + } + } + impl EnzymeWrapper { /// Initialize EnzymeWrapper with the given sysroot if not already initialized. /// Safe to call multiple times - subsequent calls are no-ops due to OnceLock. pub(crate) fn get_or_init( sysroot: &rustc_session::config::Sysroot, - ) -> Result, Box> { + ) -> Result, EnzymeLibraryError> { let mtx: &'static Mutex = ENZYME_INSTANCE.get_or_try_init(|| { let w = Self::call_dynamic(sysroot)?; - Ok::<_, Box>(Mutex::new(w)) + Ok::<_, EnzymeLibraryError>(Mutex::new(w)) })?; Ok(mtx.lock().unwrap()) @@ -351,7 +363,7 @@ pub(crate) mod Enzyme_AD { #[allow(non_snake_case)] fn call_dynamic( sysroot: &rustc_session::config::Sysroot, - ) -> Result> { + ) -> Result { let enzyme_path = Self::get_enzyme_path(sysroot)?; let lib = unsafe { libloading::Library::new(enzyme_path)? }; @@ -416,7 +428,7 @@ pub(crate) mod Enzyme_AD { }) } - fn get_enzyme_path(sysroot: &Sysroot) -> Result { + fn get_enzyme_path(sysroot: &Sysroot) -> Result { let llvm_version_major = unsafe { LLVMRustVersionMajor() }; let path_buf = sysroot @@ -434,15 +446,19 @@ pub(crate) mod Enzyme_AD { .map(|p| p.join("lib").display().to_string()) .collect::>() .join("\n* "); - format!( - "failed to find a `libEnzyme-{llvm_version_major}` folder \ + EnzymeLibraryError::NotFound { + err: format!( + "failed to find a `libEnzyme-{llvm_version_major}` folder \ in the sysroot candidates:\n* {candidates}" - ) + ), + } })?; Ok(path_buf .to_str() - .ok_or_else(|| format!("invalid UTF-8 in path: {}", path_buf.display()))? + .ok_or_else(|| EnzymeLibraryError::LoadFailed { + err: format!("invalid UTF-8 in path: {}", path_buf.display()), + })? .to_string()) } } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 8ab0b367f08a6..c8aa7c04585c8 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -6,7 +6,8 @@ use std::time::{Duration, Instant}; use itertools::Itertools; use rustc_abi::FIRST_VARIANT; use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorMethod, AllocatorTy, + ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorMethod, AllocatorMethodInput, + AllocatorTy, }; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; @@ -671,7 +672,7 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec ConstItemRhs<'hir> { pub fn span<'tcx>(&self, tcx: impl crate::intravisit::HirTyCtxt<'tcx>) -> Span { match self { ConstItemRhs::Body(body_id) => tcx.hir_body(*body_id).value.span, - ConstItemRhs::TypeConst(ct_arg) => ct_arg.span(), + ConstItemRhs::TypeConst(ct_arg) => ct_arg.span, } } } @@ -447,6 +447,7 @@ pub struct ConstArg<'hir, Unambig = ()> { #[stable_hasher(ignore)] pub hir_id: HirId, pub kind: ConstArgKind<'hir, Unambig>, + pub span: Span, } impl<'hir> ConstArg<'hir, AmbigArg> { @@ -475,7 +476,7 @@ impl<'hir> ConstArg<'hir> { /// Functions accepting ambiguous consts will not handle the [`ConstArgKind::Infer`] variant, if /// infer consts are relevant to you then care should be taken to handle them separately. pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> { - if let ConstArgKind::Infer(_, ()) = self.kind { + if let ConstArgKind::Infer(()) = self.kind { return None; } @@ -494,23 +495,13 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> { _ => None, } } - - pub fn span(&self) -> Span { - match self.kind { - ConstArgKind::Struct(path, _) => path.span(), - ConstArgKind::Path(path) => path.span(), - ConstArgKind::TupleCall(path, _) => path.span(), - ConstArgKind::Anon(anon) => anon.span, - ConstArgKind::Error(span, _) => span, - ConstArgKind::Infer(span, _) => span, - } - } } /// See [`ConstArg`]. #[derive(Clone, Copy, Debug, HashStable_Generic)] #[repr(u8, C)] pub enum ConstArgKind<'hir, Unambig = ()> { + Tup(&'hir [&'hir ConstArg<'hir, Unambig>]), /// **Note:** Currently this is only used for bare const params /// (`N` where `fn foo(...)`), /// not paths to any const (`N` where `const N: usize = ...`). @@ -523,10 +514,10 @@ pub enum ConstArgKind<'hir, Unambig = ()> { /// Tuple constructor variant TupleCall(QPath<'hir>, &'hir [&'hir ConstArg<'hir>]), /// Error const - Error(Span, ErrorGuaranteed), + Error(ErrorGuaranteed), /// This variant is not always used to represent inference consts, sometimes /// [`GenericArg::Infer`] is used instead. - Infer(Span, Unambig), + Infer(Unambig), } #[derive(Clone, Copy, Debug, HashStable_Generic)] @@ -572,7 +563,7 @@ impl GenericArg<'_> { match self { GenericArg::Lifetime(l) => l.ident.span, GenericArg::Type(t) => t.span, - GenericArg::Const(c) => c.span(), + GenericArg::Const(c) => c.span, GenericArg::Infer(i) => i.span, } } diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs index 4f9609fd360d7..2ac33a369cbdd 100644 --- a/compiler/rustc_hir/src/hir/tests.rs +++ b/compiler/rustc_hir/src/hir/tests.rs @@ -24,12 +24,16 @@ define_tests! { cast_ptr TyKind Ptr { 0: MutTy { ty: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }, mutbl: Mutability::Not }} cast_array TyKind Array { 0: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }, - 1: &ConstArg { hir_id: HirId::INVALID, kind: ConstArgKind::Anon(&AnonConst { + 1: &ConstArg { hir_id: HirId::INVALID, - def_id: LocalDefId { local_def_index: DefIndex::ZERO }, - body: BodyId { hir_id: HirId::INVALID }, + kind: ConstArgKind::Anon(&AnonConst { + hir_id: HirId::INVALID, + def_id: LocalDefId { local_def_index: DefIndex::ZERO }, + body: BodyId { hir_id: HirId::INVALID }, + span: DUMMY_SP, + }), span: DUMMY_SP, - })} + }, } cast_anon ConstArgKind Anon { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 853e7db0757a4..59db60fdc55c4 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1068,8 +1068,8 @@ pub fn walk_unambig_const_arg<'v, V: Visitor<'v>>( match const_arg.try_as_ambig_ct() { Some(ambig_ct) => visitor.visit_const_arg(ambig_ct), None => { - let ConstArg { hir_id, kind: _ } = const_arg; - visitor.visit_infer(*hir_id, const_arg.span(), InferKind::Const(const_arg)) + let ConstArg { hir_id, kind: _, span } = const_arg; + visitor.visit_infer(*hir_id, *span, InferKind::Const(const_arg)) } } } @@ -1078,9 +1078,13 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( visitor: &mut V, const_arg: &'v ConstArg<'v, AmbigArg>, ) -> V::Result { - let ConstArg { hir_id, kind } = const_arg; + let ConstArg { hir_id, kind, span: _ } = const_arg; try_visit!(visitor.visit_id(*hir_id)); match kind { + ConstArgKind::Tup(exprs) => { + walk_list!(visitor, visit_const_arg, *exprs); + V::Result::output() + } ConstArgKind::Struct(qpath, field_exprs) => { try_visit!(visitor.visit_qpath(qpath, *hir_id, qpath.span())); @@ -1099,7 +1103,7 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( } ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()), ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), - ConstArgKind::Error(_, _) => V::Result::output(), // errors and spans are not important + ConstArgKind::Error(_) => V::Result::output(), // errors and spans are not important } } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 9343bcd27a339..bacdf0049806e 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1479,23 +1479,27 @@ fn rendered_precise_capturing_args<'tcx>( fn const_param_default<'tcx>( tcx: TyCtxt<'tcx>, - def_id: LocalDefId, + local_def_id: LocalDefId, ) -> ty::EarlyBinder<'tcx, Const<'tcx>> { let hir::Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Const { default: Some(default_ct), .. }, .. - }) = tcx.hir_node_by_def_id(def_id) + }) = tcx.hir_node_by_def_id(local_def_id) else { span_bug!( - tcx.def_span(def_id), + tcx.def_span(local_def_id), "`const_param_default` expected a generic parameter with a constant" ) }; - let icx = ItemCtxt::new(tcx, def_id); - let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); + + let icx = ItemCtxt::new(tcx, local_def_id); + + let def_id = local_def_id.to_def_id(); + let identity_args = ty::GenericArgs::identity_for_item(tcx, tcx.parent(def_id)); + let ct = icx .lowerer() - .lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id(), identity_args)); + .lower_const_arg(default_ct, FeedConstTy::with_type_of(tcx, def_id, identity_args)); ty::EarlyBinder::bind(ct) } @@ -1553,7 +1557,7 @@ fn const_of_item<'tcx>( let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let ct = icx .lowerer() - .lower_const_arg(ct_arg, FeedConstTy::Param(def_id.to_def_id(), identity_args)); + .lower_const_arg(ct_arg, FeedConstTy::with_type_of(tcx, def_id.to_def_id(), identity_args)); if let Err(e) = icx.check_tainted_by_errors() && !ct.references_error() { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 51c6649218045..92b77a2042b18 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -381,7 +381,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { { let span = match term { hir::Term::Ty(ty) => ty.span, - hir::Term::Const(ct) => ct.span(), + hir::Term::Const(ct) => ct.span, }; (span, Some(ident.span), assoc_item.as_tag(), assoc_tag) } else { @@ -1466,7 +1466,7 @@ pub fn prohibit_assoc_item_constraint( hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(c) }, GenericParamDefKind::Const { .. }, ) => { - suggest_direct_use(&mut err, c.span()); + suggest_direct_use(&mut err, c.span); } (hir::AssocItemConstraintKind::Bound { bounds }, _) => { // Suggest `impl Trait for Foo` when finding diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index a22729fd287e2..aaa566760013c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -259,17 +259,26 @@ impl AssocItemQSelf { /// Use this enum with `::lower_const_arg` to instruct it with the /// desired behavior. #[derive(Debug, Clone, Copy)] -pub enum FeedConstTy<'a, 'tcx> { - /// Feed the type. - /// +pub enum FeedConstTy<'tcx> { + /// Feed the type to the (anno) const arg. + WithTy(Ty<'tcx>), + /// Don't feed the type. + No, +} + +impl<'tcx> FeedConstTy<'tcx> { /// The `DefId` belongs to the const param that we are supplying /// this (anon) const arg to. /// /// The list of generic args is used to instantiate the parameters /// used by the type of the const param specified by `DefId`. - Param(DefId, &'a [ty::GenericArg<'tcx>]), - /// Don't feed the type. - No, + pub fn with_type_of( + tcx: TyCtxt<'tcx>, + def_id: DefId, + generic_args: &[ty::GenericArg<'tcx>], + ) -> Self { + Self::WithTy(tcx.type_of(def_id).instantiate(tcx, generic_args)) + } } #[derive(Debug, Clone, Copy)] @@ -723,7 +732,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Ambig portions of `ConstArg` are handled in the match arm below .lower_const_arg( ct.as_unambig_ct(), - FeedConstTy::Param(param.def_id, preceding_args), + FeedConstTy::with_type_of(tcx, param.def_id, preceding_args), ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { @@ -2303,15 +2312,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { pub fn lower_const_arg( &self, const_arg: &hir::ConstArg<'tcx>, - feed: FeedConstTy<'_, 'tcx>, + feed: FeedConstTy<'tcx>, ) -> Const<'tcx> { let tcx = self.tcx(); - if let FeedConstTy::Param(param_def_id, args) = feed + if let FeedConstTy::WithTy(anon_const_type) = feed && let hir::ConstArgKind::Anon(anon) = &const_arg.kind { - let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args); - // FIXME(generic_const_parameter_types): Ideally we remove these errors below when // we have the ability to intermix typeck of anon const const args with the parent // bodies typeck. @@ -2324,7 +2331,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions()) { let e = self.dcx().span_err( - const_arg.span(), + const_arg.span, "anonymous constants with lifetimes in their type are not yet supported", ); tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); @@ -2335,7 +2342,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // variables otherwise we will ICE. if anon_const_type.has_non_region_infer() { let e = self.dcx().span_err( - const_arg.span(), + const_arg.span, "anonymous constants with inferred types are not yet supported", ); tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); @@ -2345,21 +2352,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // give the anon const any of the generics from the parent. if anon_const_type.has_non_region_param() { let e = self.dcx().span_err( - const_arg.span(), + const_arg.span, "anonymous constants referencing generics are not yet supported", ); tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); return ty::Const::new_error(tcx, e); } - tcx.feed_anon_const_type( - anon.def_id, - ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)), - ); + tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(anon_const_type)); } let hir_id = const_arg.hir_id; match const_arg.kind { + hir::ConstArgKind::Tup(exprs) => self.lower_const_arg_tup(exprs, feed, const_arg.span), hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => { debug!(?maybe_qself, ?path); let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself)); @@ -2373,19 +2378,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_self_ty, segment, hir_id, - const_arg.span(), + const_arg.span, ) .unwrap_or_else(|guar| Const::new_error(tcx, guar)) } hir::ConstArgKind::Struct(qpath, inits) => { - self.lower_const_arg_struct(hir_id, qpath, inits, const_arg.span()) + self.lower_const_arg_struct(hir_id, qpath, inits, const_arg.span) } hir::ConstArgKind::TupleCall(qpath, args) => { - self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span()) + self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span) } hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), - hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span), - hir::ConstArgKind::Error(_, e) => ty::Const::new_error(tcx, e), + hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span), + hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e), } } @@ -2464,7 +2469,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .zip(args) .map(|(field_def, arg)| { - self.lower_const_arg(arg, FeedConstTy::Param(field_def.did, adt_args)) + self.lower_const_arg(arg, FeedConstTy::with_type_of(tcx, field_def.did, adt_args)) }) .collect::>(); @@ -2480,6 +2485,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::Const::new_value(tcx, valtree, adt_ty) } + fn lower_const_arg_tup( + &self, + exprs: &'tcx [&'tcx hir::ConstArg<'tcx>], + feed: FeedConstTy<'tcx>, + span: Span, + ) -> Const<'tcx> { + let tcx = self.tcx(); + + let FeedConstTy::WithTy(ty) = feed else { + return Const::new_error_with_message(tcx, span, "unsupported const tuple"); + }; + + let ty::Tuple(tys) = ty.kind() else { + return Const::new_error_with_message(tcx, span, "const tuple must have a tuple type"); + }; + + let exprs = exprs + .iter() + .zip(tys.iter()) + .map(|(expr, ty)| self.lower_const_arg(expr, FeedConstTy::WithTy(ty))) + .collect::>(); + + let valtree = ty::ValTree::from_branches(tcx, exprs); + ty::Const::new_value(tcx, valtree, ty) + } + fn lower_const_arg_struct( &self, hir_id: HirId, @@ -2558,7 +2589,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { return ty::Const::new_error(tcx, e); } - self.lower_const_arg(expr.expr, FeedConstTy::Param(field_def.did, adt_args)) + self.lower_const_arg( + expr.expr, + FeedConstTy::with_type_of(tcx, field_def.did, adt_args), + ) } None => { let e = tcx.dcx().span_err( diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 65f6a11e8e9b9..7296ba6f964a4 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -301,7 +301,7 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { pub fn lower_const_arg_for_rustdoc<'tcx>( tcx: TyCtxt<'tcx>, hir_ct: &hir::ConstArg<'tcx>, - feed: FeedConstTy<'_, 'tcx>, + feed: FeedConstTy<'tcx>, ) -> Const<'tcx> { let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id); collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 932e78958345c..2c160ccef2b62 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1141,11 +1141,21 @@ impl<'a> State<'a> { fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) { match &const_arg.kind { + ConstArgKind::Tup(exprs) => { + self.popen(); + self.commasep_cmnt( + Inconsistent, + exprs, + |s, arg| s.print_const_arg(arg), + |arg| arg.span, + ); + self.pclose(); + } ConstArgKind::Struct(qpath, fields) => self.print_const_struct(qpath, fields), ConstArgKind::TupleCall(qpath, args) => self.print_const_ctor(qpath, args), ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), ConstArgKind::Anon(anon) => self.print_anon_const(anon), - ConstArgKind::Error(_, _) => self.word("/*ERROR*/"), + ConstArgKind::Error(_) => self.word("/*ERROR*/"), ConstArgKind::Infer(..) => self.word("_"), } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index c4fa39c6c2c84..9d7e09b020a75 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1705,7 +1705,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; }; if let hir::TyKind::Array(_, ct) = ty.peel_refs().kind { - let span = ct.span(); + let span = ct.span; self.dcx().try_steal_modify_and_emit_err( span, StashKey::UnderscoreForArrayLengths, @@ -1746,7 +1746,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; - let count_span = count.span(); + let count_span = count.span; let count = self.try_structurally_resolve_const( count_span, self.normalize(count_span, self.lower_const_arg(count, FeedConstTy::No)), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 339e77ac6edd6..a66ff2a23c250 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -525,7 +525,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn lower_const_arg( &self, const_arg: &'tcx hir::ConstArg<'tcx>, - feed: FeedConstTy<'_, 'tcx>, + feed: FeedConstTy<'tcx>, ) -> ty::Const<'tcx> { let ct = self.lowerer().lower_const_arg(const_arg, feed); self.register_wf_obligation( @@ -1228,7 +1228,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Ambiguous parts of `ConstArg` are handled in the match arms below .lower_const_arg( ct.as_unambig_ct(), - FeedConstTy::Param(param.def_id, preceding_args), + FeedConstTy::with_type_of(self.fcx.tcx, param.def_id, preceding_args), ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index e81537008bb5e..aab4e39855557 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -447,7 +447,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // We handle the ambig portions of `ConstArg` in the match arms below .lower_const_arg( ct.as_unambig_ct(), - FeedConstTy::Param(param.def_id, preceding_args), + FeedConstTy::with_type_of(self.cfcx.tcx, param.def_id, preceding_args), ) .into(), (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index 29006732aade5..f4a506d50a41b 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -74,12 +74,9 @@ fn gen_args(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> String { GenericArg::Type(ty) => { cx.tcx.sess.source_map().span_to_snippet(ty.span).unwrap_or_else(|_| "_".into()) } - GenericArg::Const(c) => cx - .tcx - .sess - .source_map() - .span_to_snippet(c.span()) - .unwrap_or_else(|_| "_".into()), + GenericArg::Const(c) => { + cx.tcx.sess.source_map().span_to_snippet(c.span).unwrap_or_else(|_| "_".into()) + } GenericArg::Infer(_) => String::from("_"), }) .collect::>(); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d79ab9eaf7597..d0e8bc50c4957 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1442,6 +1442,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ConstArgKind::Error(..) | hir::ConstArgKind::Struct(..) | hir::ConstArgKind::TupleCall(..) + | hir::ConstArgKind::Tup(..) | hir::ConstArgKind::Path(..) | hir::ConstArgKind::Infer(..) => true, hir::ConstArgKind::Anon(..) => false, diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 8cc66802e4353..ca783311586f1 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1003,7 +1003,7 @@ impl<'tcx> TyCtxt<'tcx> { Node::Field(field) => field.span, Node::AnonConst(constant) => constant.span, Node::ConstBlock(constant) => self.hir_body(constant.body).value.span, - Node::ConstArg(const_arg) => const_arg.span(), + Node::ConstArg(const_arg) => const_arg.span, Node::Expr(expr) => expr.span, Node::ExprField(field) => field.span, Node::ConstArgExprField(field) => field.span, diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index a46fcd30fef40..62e97c0c308c1 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -2666,7 +2666,6 @@ fn look_ahead_non_outermost_stream() { }); } -// FIXME(nnethercote) All the output is currently wrong. #[test] fn debug_lookahead() { create_default_session_globals_then(|| { diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index f7b85453448c4..b392b7747b554 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -419,7 +419,9 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { // Avoid overwriting `const_arg_context` as we may want to treat const blocks // as being anon consts if we are inside a const argument. - ExprKind::Struct(_) | ExprKind::Call(..) => return visit::walk_expr(self, expr), + ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) => { + return visit::walk_expr(self, expr); + } // FIXME(mgca): we may want to handle block labels in some manner ExprKind::Block(block, _) if let [stmt] = block.stmts.as_slice() => match stmt.kind { // FIXME(mgca): this probably means that mac calls that expand diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index cea69c6996281..47810e2578df6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1879,7 +1879,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let Some(length_val) = sz.found.try_to_target_usize(self.tcx) { Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { - span: length_arg.span(), + span: length_arg.span, length: length_val, }) } else { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 889fd4cd65df5..1bca13b14ed4c 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -4809,8 +4809,6 @@ impl [T] { /// # Examples /// Basic usage: /// ``` - /// #![feature(substr_range)] - /// /// let nums: &[u32] = &[1, 7, 1, 1]; /// let num = &nums[2]; /// @@ -4819,8 +4817,6 @@ impl [T] { /// ``` /// Returning `None` with an unaligned element: /// ``` - /// #![feature(substr_range)] - /// /// let arr: &[[u32; 2]] = &[[0, 1], [2, 3]]; /// let flat_arr: &[u32] = arr.as_flattened(); /// @@ -4834,7 +4830,7 @@ impl [T] { /// assert_eq!(arr.element_offset(weird_elm), None); // Points between element 0 and 1 /// ``` #[must_use] - #[unstable(feature = "substr_range", issue = "126769")] + #[stable(feature = "element_offset", since = "CURRENT_RUSTC_VERSION")] pub fn element_offset(&self, element: &T) -> Option { if T::IS_ZST { panic!("elements are zero-sized"); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8de3722fa69d4..e05d3e4164306 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -326,6 +326,10 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind hir::ConstArgKind::TupleCall(..) => { ConstantKind::Path { path: "/* TUPLE CALL */".to_string().into() } } + hir::ConstArgKind::Tup(..) => { + // FIXME(mgca): proper printing :3 + ConstantKind::Path { path: "/* TUPLE EXPR */".to_string().into() } + } hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer, } @@ -1809,7 +1813,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } hir::ConstArgKind::Struct(..) | hir::ConstArgKind::Path(..) - | hir::ConstArgKind::TupleCall(..) => { + | hir::ConstArgKind::TupleCall(..) + | hir::ConstArgKind::Tup(..) => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); print_const(cx, ct) } diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index 620e27fa67c62..261b03abba171 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -126,7 +126,7 @@ fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool { let ExprKind::Repeat(_, len_ct) = expr.kind else { return false; }; - !expr.span.contains(len_ct.span()) + !expr.span.contains(len_ct.span) } expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(expr) diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index f515f9987a802..455f76edc9047 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -321,6 +321,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }, ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), + ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index a44cd31dc1233..46b87fd5df961 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1140,7 +1140,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { + ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { None }, }, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index f1ee534c500d3..57c896c971722 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -661,6 +661,10 @@ impl HirEqInterExpr<'_, '_, '_> { } fn eq_const_arg(&mut self, left: &ConstArg<'_>, right: &ConstArg<'_>) -> bool { + if !self.check_ctxt(left.span.ctxt(), right.span.ctxt()) { + return false; + } + match (&left.kind, &right.kind) { (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p), (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body), @@ -679,11 +683,18 @@ impl HirEqInterExpr<'_, '_, '_> { .zip(*args_b) .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) } + (ConstArgKind::Tup(args_a), ConstArgKind::Tup(args_b)) => { + args_a + .iter() + .zip(*args_b) + .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) + } // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) | ConstArgKind::Anon(..) | ConstArgKind::TupleCall(..) + | ConstArgKind::Tup(..) | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) | ConstArgKind::Error(..), @@ -1560,6 +1571,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(arg); } }, + ConstArgKind::Tup(args) => { + for arg in *args { + self.hash_const_arg(arg); + } + }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, } } diff --git a/tests/crashes/133965.rs b/tests/crashes/133965.rs deleted file mode 100644 index 69f533ccbe987..0000000000000 --- a/tests/crashes/133965.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: #133965 -//@ needs-rustc-debug-assertions - -struct NonGeneric {} - -#[derive(Default)] -struct NonGeneric<'a, const N: usize> {} - -pub fn main() {} diff --git a/tests/incremental/const-generic-type-cycle.rs b/tests/incremental/const-generic-type-cycle.rs index 40a40ebd13fe5..5bcbc1d5dafef 100644 --- a/tests/incremental/const-generic-type-cycle.rs +++ b/tests/incremental/const-generic-type-cycle.rs @@ -14,7 +14,6 @@ trait Bar {} trait Bar {} //[cfail]~^ ERROR cycle detected when computing type of `Bar::N` //[cfail]~| ERROR cycle detected when computing type of `Bar::N` -//[cfail]~| ERROR cycle detected when computing type of `Bar::N` //[cfail]~| ERROR `(dyn Bar<{ 2 + 1 }> + 'static)` is forbidden as the type of a const generic parameter trait BB = Bar<{ 2 + 1 }>; diff --git a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr index 6cf4e881adae8..62bebd53b14a6 100644 --- a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr +++ b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr @@ -1,8 +1,8 @@ error: unconstrained generic constant - --> $DIR/doesnt_unify_evaluatable.rs:9:11 + --> $DIR/doesnt_unify_evaluatable.rs:9:13 | LL | bar::<{ T::ASSOC }>(); - | ^^^^^^^^^^^^ + | ^^^^^^^^ | help: try adding a `where` bound | diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.rs b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.rs new file mode 100644 index 0000000000000..e47052523fa39 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.rs @@ -0,0 +1,20 @@ +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] + +trait Trait { + #[type_const] + const ASSOC: usize; +} + +fn takes_tuple() {} +fn takes_nested_tuple() {} + +fn generic_caller() { + takes_tuple::<{ (N, N + 1) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_tuple::<{ (N, T::ASSOC + 1) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + + takes_nested_tuple::<{ (N, (N, N + 1)) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); //~ ERROR generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.stderr new file mode 100644 index 0000000000000..dbc64a1bf59d3 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.stderr @@ -0,0 +1,26 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/adt_expr_arg_tuple_expr_complex.rs:13:25 + | +LL | takes_tuple::<{ (N, N + 1) }>(); + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/adt_expr_arg_tuple_expr_complex.rs:14:25 + | +LL | takes_tuple::<{ (N, T::ASSOC + 1) }>(); + | ^^^^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/adt_expr_arg_tuple_expr_complex.rs:16:36 + | +LL | takes_nested_tuple::<{ (N, (N, N + 1)) }>(); + | ^^^^^ + +error: generic parameters may not be used in const operations + --> $DIR/adt_expr_arg_tuple_expr_complex.rs:17:44 + | +LL | takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); + | ^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs new file mode 100644 index 0000000000000..60c4c6e952cf2 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs @@ -0,0 +1,22 @@ +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] + +trait Trait { + #[type_const] + const ASSOC: usize; +} + +fn takes_tuple() {} +fn takes_nested_tuple() {} + +fn generic_caller() { + takes_tuple::<{ (N, N2) }>(); + takes_tuple::<{ (N, T::ASSOC) }>(); + + takes_nested_tuple::<{ (N, (N, N2)) }>(); + takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr index 49d3f67003dc0..72e0e94ff625b 100644 --- a/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr @@ -23,7 +23,7 @@ error: struct expression with missing field initialiser for `field` --> $DIR/adt_expr_erroneuous_inits.rs:16:17 | LL | accepts::<{ Foo:: { }}>(); - | ^^^^^^^^^ + | ^^^^^^^^^^^^^ error: struct expression with multiple initialisers for `field` --> $DIR/adt_expr_erroneuous_inits.rs:18:49 @@ -35,13 +35,13 @@ error: struct expression with invalid base path --> $DIR/adt_expr_erroneuous_inits.rs:20:17 | LL | accepts::<{ Fooo:: { field: const { 1 } }}>(); - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: struct expression with invalid base path --> $DIR/adt_expr_erroneuous_inits.rs:23:17 | LL | accepts::<{ NonStruct { }}>(); - | ^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr index b4f03e07b5690..bd21624689448 100644 --- a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr @@ -2,7 +2,7 @@ error: the constant `Option::::Some(N)` is not of type `Foo` --> $DIR/printing_valtrees_supports_non_values.rs:18:13 | LL | foo::<{ Option::Some:: { 0: N } }>; - | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` | note: required by a const generic parameter in `foo` --> $DIR/printing_valtrees_supports_non_values.rs:15:8 @@ -14,7 +14,7 @@ error: the constant `Option::::Some(::ASSOC)` is not of type `F --> $DIR/printing_valtrees_supports_non_values.rs:23:13 | LL | foo::<{ Option::Some:: { 0: ::ASSOC } }>(); - | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` | note: required by a const generic parameter in `foo` --> $DIR/printing_valtrees_supports_non_values.rs:15:8 @@ -37,7 +37,7 @@ error: the constant `Option::::Some(_)` is not of type `Foo` --> $DIR/printing_valtrees_supports_non_values.rs:30:12 | LL | foo::<{Option::Some::{0: ::ASSOC}}>(); - | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` | note: required by a const generic parameter in `foo` --> $DIR/printing_valtrees_supports_non_values.rs:15:8 @@ -49,7 +49,7 @@ error: the constant `Option::::Some(_)` is not of type `Foo` --> $DIR/printing_valtrees_supports_non_values.rs:36:13 | LL | foo::<{ Option::Some:: { 0: _ } }>(); - | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` | note: required by a const generic parameter in `foo` --> $DIR/printing_valtrees_supports_non_values.rs:15:8 diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr index fbcdf35461ec9..cc6144b9c88af 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr @@ -13,31 +13,31 @@ error: tuple constructor has 2 arguments but 1 were provided --> $DIR/tuple_ctor_erroneous.rs:23:23 | LL | accepts_point::<{ Point(N) }>(); - | ^^^^^ + | ^^^^^^^^ error: tuple constructor has 2 arguments but 3 were provided --> $DIR/tuple_ctor_erroneous.rs:26:23 | LL | accepts_point::<{ Point(N, N, N) }>(); - | ^^^^^ + | ^^^^^^^^^^^^^^ error: tuple constructor with invalid base path --> $DIR/tuple_ctor_erroneous.rs:29:23 | LL | accepts_point::<{ UnresolvedIdent(N, N) }>(); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ error: tuple constructor with invalid base path --> $DIR/tuple_ctor_erroneous.rs:33:23 | LL | accepts_point::<{ non_ctor(N, N) }>(); - | ^^^^^^^^ + | ^^^^^^^^^^^^^^ error: tuple constructor with invalid base path --> $DIR/tuple_ctor_erroneous.rs:36:23 | LL | accepts_point::<{ CONST_ITEM(N, N) }>(); - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: the constant `Point` is not of type `Point` --> $DIR/tuple_ctor_erroneous.rs:39:23 diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs new file mode 100644 index 0000000000000..8e5cd4248f149 --- /dev/null +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs @@ -0,0 +1,14 @@ +//@ needs-rustc-debug-assertions + +struct NonGeneric {} + +#[derive(Default)] +//~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied +//~^^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied +//~^^^ ERROR struct takes 0 generic arguments but 1 generic argument was supplied +//~^^^^ ERROR struct takes 0 generic arguments but 1 generic argument was supplied +struct NonGeneric<'a, const N: usize> {} +//~^ ERROR lifetime parameter `'a` is never used +//~^^ ERROR the name `NonGeneric` is defined multiple times + +pub fn main() {} diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr new file mode 100644 index 0000000000000..cf9c0d0ad3bee --- /dev/null +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr @@ -0,0 +1,81 @@ +error[E0428]: the name `NonGeneric` is defined multiple times + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:10:1 + | +LL | struct NonGeneric {} + | ----------------- previous definition of the type `NonGeneric` here +... +LL | struct NonGeneric<'a, const N: usize> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonGeneric` redefined here + | + = note: `NonGeneric` must be defined only once in the type namespace of this module + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + | +LL | #[derive(Default)] + | ^^^^^^^ expected 0 lifetime arguments +... +LL | struct NonGeneric<'a, const N: usize> {} + | -- help: remove the lifetime argument + | +note: struct defined here, with 0 lifetime parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + | +LL | #[derive(Default)] + | ^^^^^^^ expected 0 generic arguments + | +note: struct defined here, with 0 generic parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:10:19 + | +LL | struct NonGeneric<'a, const N: usize> {} + | ^^ unused lifetime parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + | +LL | #[derive(Default)] + | ^^^^^^^ expected 0 lifetime arguments +... +LL | struct NonGeneric<'a, const N: usize> {} + | -- help: remove the lifetime argument + | +note: struct defined here, with 0 lifetime parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + | +LL | #[derive(Default)] + | ^^^^^^^ expected 0 generic arguments +... +LL | struct NonGeneric<'a, const N: usize> {} + | - help: remove the unnecessary generic argument + | +note: struct defined here, with 0 generic parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0107, E0392, E0428. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs b/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs deleted file mode 100644 index c40590ad87f47..0000000000000 --- a/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-pass -//@ aux-build:sigpipe-utils.rs -//@ compile-flags: -Zon-broken-pipe=kill -//@ only-unix because SIGPIPE is a unix thing - -#![feature(rustc_attrs)] - -#[rustc_main] -fn rustc_main() { - extern crate sigpipe_utils; - - // `-Zon-broken-pipe=kill` is active, so SIGPIPE handler shall be - // SIG_DFL. Note that we have a #[rustc_main], but it should still work. - sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default); -} diff --git a/tests/ui/transmutability/non_scalar_alignment_value.stderr b/tests/ui/transmutability/non_scalar_alignment_value.stderr index 06487dea82e00..d22c6d0b27e82 100644 --- a/tests/ui/transmutability/non_scalar_alignment_value.stderr +++ b/tests/ui/transmutability/non_scalar_alignment_value.stderr @@ -11,25 +11,25 @@ error: struct expression with missing field initialiser for `alignment` --> $DIR/non_scalar_alignment_value.rs:15:32 | LL | alignment: Assume {}, - | ^^^^^^ + | ^^^^^^^^^ error: struct expression with missing field initialiser for `lifetimes` --> $DIR/non_scalar_alignment_value.rs:15:32 | LL | alignment: Assume {}, - | ^^^^^^ + | ^^^^^^^^^ error: struct expression with missing field initialiser for `safety` --> $DIR/non_scalar_alignment_value.rs:15:32 | LL | alignment: Assume {}, - | ^^^^^^ + | ^^^^^^^^^ error: struct expression with missing field initialiser for `validity` --> $DIR/non_scalar_alignment_value.rs:15:32 | LL | alignment: Assume {}, - | ^^^^^^ + | ^^^^^^^^^ error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs index 519e913480ec3..f2b9f037ea5f3 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs @@ -4,7 +4,6 @@ trait Foo> { //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| ERROR cycle detected when computing type of `Foo::N` - //~| ERROR cycle detected when computing type of `Foo::N` fn func() {} } diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr index 0ecb3e74eb571..4024f57af4ffd 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr @@ -13,7 +13,7 @@ LL | trait Foo> { | +++ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:20 + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:20 | LL | trait Bar> {} | ^^^^^^ @@ -32,7 +32,7 @@ LL | trait Foo> { | ^^^^^^^^^^^^^^^ | note: ...which requires computing type of `Bar::M`... - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11 + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:11 | LL | trait Bar> {} | ^^^^^^^^^^^^^^^ @@ -44,26 +44,6 @@ LL | trait 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[E0391]: cycle detected when computing type of `Foo::N` - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:3:11 - | -LL | trait Foo> { - | ^^^^^^^^^^^^^^^ - | -note: ...which requires computing type of `Bar::M`... - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11 - | -LL | trait Bar> {} - | ^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `Foo::N`, completing the cycle -note: cycle used when checking that `Foo` is well-formed - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:3:1 - | -LL | trait 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 - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 1 previous error; 2 warnings emitted For more information about this error, try `rustc --explain E0391`.