Auto merge of #150798 - matthiaskrgr:rollup-ANxstUE, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang/rust#150675 (MGCA: Support tuple expressions as direct const arguments) - rust-lang/rust#150696 (enrich error info when tries to dlopen Enzyme) - rust-lang/rust#150747 (tests/ui/runtime/on-broken-pipe/with-rustc_main.rs: Not needed so remove) - rust-lang/rust#150757 (Fix `alloc_error_handler` signature mismatch) - rust-lang/rust#150777 (Stabilize `slice::element_offset`) - rust-lang/rust#150791 (Remove out of date FIXME comment.) r? @ghost
This commit is contained in:
commit
bca37a20bd
46 changed files with 437 additions and 177 deletions
|
|
@ -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()),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -34,7 +34,16 @@ impl<G: EmissionGuarantee> 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)]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<dyn std::error::Error>> {
|
||||
) -> 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<Mutex<EnzymeWrapper>> = OnceLock::new();
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum EnzymeLibraryError {
|
||||
NotFound { err: String },
|
||||
LoadFailed { err: String },
|
||||
}
|
||||
|
||||
impl From<libloading::Error> 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<MutexGuard<'static, Self>, Box<dyn std::error::Error>> {
|
||||
) -> Result<MutexGuard<'static, Self>, EnzymeLibraryError> {
|
||||
let mtx: &'static Mutex<EnzymeWrapper> = ENZYME_INSTANCE.get_or_try_init(|| {
|
||||
let w = Self::call_dynamic(sysroot)?;
|
||||
Ok::<_, Box<dyn std::error::Error>>(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<Self, Box<dyn std::error::Error>> {
|
||||
) -> Result<Self, EnzymeLibraryError> {
|
||||
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<String, String> {
|
||||
fn get_enzyme_path(sysroot: &Sysroot) -> Result<String, EnzymeLibraryError> {
|
||||
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::<Vec<String>>()
|
||||
.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())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Allo
|
|||
methods.push(AllocatorMethod {
|
||||
name: ALLOC_ERROR_HANDLER,
|
||||
special: None,
|
||||
inputs: &[],
|
||||
inputs: &[AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout }],
|
||||
output: AllocatorTy::Never,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ impl<'hir> 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<const N: usize>(...)`),
|
||||
/// 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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<T: Bound> Trait<T> for Foo` when finding
|
||||
|
|
|
|||
|
|
@ -259,17 +259,26 @@ impl AssocItemQSelf {
|
|||
/// Use this enum with `<dyn HirTyLowerer>::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::<Vec<_>>();
|
||||
|
||||
|
|
@ -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::<Vec<_>>();
|
||||
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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("_"),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
|
|
|
|||
|
|
@ -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)) => {
|
||||
|
|
|
|||
|
|
@ -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)) => {
|
||||
|
|
|
|||
|
|
@ -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::<Vec<_>>();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(|| {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -4809,8 +4809,6 @@ impl<T> [T] {
|
|||
/// # Examples
|
||||
/// Basic usage:
|
||||
/// ```
|
||||
/// #![feature(substr_range)]
|
||||
///
|
||||
/// let nums: &[u32] = &[1, 7, 1, 1];
|
||||
/// let num = &nums[2];
|
||||
///
|
||||
|
|
@ -4819,8 +4817,6 @@ impl<T> [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> [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<usize> {
|
||||
if T::IS_ZST {
|
||||
panic!("elements are zero-sized");
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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(..) => {},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
//@ known-bug: #133965
|
||||
//@ needs-rustc-debug-assertions
|
||||
|
||||
struct NonGeneric {}
|
||||
|
||||
#[derive(Default)]
|
||||
struct NonGeneric<'a, const N: usize> {}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -14,7 +14,6 @@ trait Bar<const N: usize> {}
|
|||
trait Bar<const N: dyn BB> {}
|
||||
//[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 }>;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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<const A: (u32, u32)>() {}
|
||||
fn takes_nested_tuple<const A: (u32, (u32, u32))>() {}
|
||||
|
||||
fn generic_caller<T: Trait, const N: u32, const N2: u32>() {
|
||||
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() {}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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<const A: (u32, u32)>() {}
|
||||
fn takes_nested_tuple<const A: (u32, (u32, u32))>() {}
|
||||
|
||||
fn generic_caller<T: Trait, const N: u32, const N2: u32>() {
|
||||
takes_tuple::<{ (N, N2) }>();
|
||||
takes_tuple::<{ (N, T::ASSOC) }>();
|
||||
|
||||
takes_nested_tuple::<{ (N, (N, N2)) }>();
|
||||
takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>();
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -23,7 +23,7 @@ error: struct expression with missing field initialiser for `field`
|
|||
--> $DIR/adt_expr_erroneuous_inits.rs:16:17
|
||||
|
|
||||
LL | accepts::<{ Foo::<u8> { }}>();
|
||||
| ^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
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::<u8> { 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
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ error: the constant `Option::<u32>::Some(N)` is not of type `Foo`
|
|||
--> $DIR/printing_valtrees_supports_non_values.rs:18:13
|
||||
|
|
||||
LL | foo::<{ Option::Some::<u32> { 0: N } }>;
|
||||
| ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option<u32>`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option<u32>`
|
||||
|
|
||||
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::<u32>::Some(<T as Trait>::ASSOC)` is not of type `F
|
|||
--> $DIR/printing_valtrees_supports_non_values.rs:23:13
|
||||
|
|
||||
LL | foo::<{ Option::Some::<u32> { 0: <T as Trait>::ASSOC } }>();
|
||||
| ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option<u32>`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option<u32>`
|
||||
|
|
||||
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::<u32>::Some(_)` is not of type `Foo`
|
|||
--> $DIR/printing_valtrees_supports_non_values.rs:30:12
|
||||
|
|
||||
LL | foo::<{Option::Some::<u32>{0: <T as Trait>::ASSOC}}>();
|
||||
| ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option<u32>`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option<u32>`
|
||||
|
|
||||
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::<u32>::Some(_)` is not of type `Foo`
|
|||
--> $DIR/printing_valtrees_supports_non_values.rs:36:13
|
||||
|
|
||||
LL | foo::<{ Option::Some::<u32> { 0: _ } }>();
|
||||
| ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option<u32>`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option<u32>`
|
||||
|
|
||||
note: required by a const generic parameter in `foo`
|
||||
--> $DIR/printing_valtrees_supports_non_values.rs:15:8
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ trait Foo<const N: Bar<2>> {
|
|||
//~^ 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() {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ LL | trait Foo<const N: dyn Bar<2>> {
|
|||
| +++
|
||||
|
||||
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<const M: Foo<2>> {}
|
||||
| ^^^^^^
|
||||
|
|
@ -32,7 +32,7 @@ LL | trait Foo<const N: Bar<2>> {
|
|||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
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<const M: Foo<2>> {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
@ -44,26 +44,6 @@ LL | trait Foo<const N: Bar<2>> {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= 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<const N: Bar<2>> {
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires computing type of `Bar::M`...
|
||||
--> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11
|
||||
|
|
||||
LL | trait Bar<const M: Foo<2>> {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
= 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<const N: Bar<2>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= 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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue