Auto merge of #129137 - camelid:lazy-def-macro-const, r=BoxyUwU
Fix anon const def-creation when macros are involved Fixes #128016. Ever since #125915, some `ast::AnonConst`s turn into `hir::ConstArgKind::Path`s, which don't have associated `DefId`s. To deal with the fact that we don't have resolution information in `DefCollector`, we decided to implement a process where if the anon const *appeared* to be trivial (i.e., `N` or `{ N }`), we would avoid creating a def for it in `DefCollector`. If later, in AST lowering, we realized it turned out to be a unit struct literal, or we were lowering it to something that didn't use `hir::ConstArg`, we'd create its def there. However, let's say we have a macro `m!()` that expands to a reference to a free constant `FOO`. If we use `m!()` in the body of an anon const (e.g., `Foo<{ m!() }>`), then in def collection, it appears to be a nontrivial anon const and we create a def. But the macro expands to something that looks like a trivial const arg, but is not, so in AST lowering we "fix" the mistake we assumed def collection made and create a def for it. This causes a duplicate definition ICE. The long-term fix for this is to delay the creation of defs for all expression-like nodes until AST lowering (see #128844 for an incomplete attempt at this). This would avoid issues like this one that are caused by hacky workarounds. However, doing this uncovers a pre-existing bug with opaque types that is quite involved to fix (see #129023). In the meantime, this PR fixes the bug by delaying def creation for anon consts whose bodies are macro invocations until after we expand the macro and know what is inside it. This is accomplished by adding information to create the anon const's def to the data in `Resolver.invocation_parents`. r? `@BoxyUwU`
This commit is contained in:
commit
d3a8524e80
37 changed files with 182 additions and 246 deletions
|
@ -1188,14 +1188,7 @@ impl Expr {
|
||||||
///
|
///
|
||||||
/// Does not ensure that the path resolves to a const param, the caller should check this.
|
/// Does not ensure that the path resolves to a const param, the caller should check this.
|
||||||
pub fn is_potential_trivial_const_arg(&self) -> bool {
|
pub fn is_potential_trivial_const_arg(&self) -> bool {
|
||||||
let this = if let ExprKind::Block(block, None) = &self.kind
|
let this = self.maybe_unwrap_block();
|
||||||
&& let [stmt] = block.stmts.as_slice()
|
|
||||||
&& let StmtKind::Expr(expr) = &stmt.kind
|
|
||||||
{
|
|
||||||
expr
|
|
||||||
} else {
|
|
||||||
self
|
|
||||||
};
|
|
||||||
|
|
||||||
if let ExprKind::Path(None, path) = &this.kind
|
if let ExprKind::Path(None, path) = &this.kind
|
||||||
&& path.is_potential_trivial_const_arg()
|
&& path.is_potential_trivial_const_arg()
|
||||||
|
@ -1206,6 +1199,17 @@ impl Expr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn maybe_unwrap_block(&self) -> &Expr {
|
||||||
|
if let ExprKind::Block(block, None) = &self.kind
|
||||||
|
&& let [stmt] = block.stmts.as_slice()
|
||||||
|
&& let StmtKind::Expr(expr) = &stmt.kind
|
||||||
|
{
|
||||||
|
expr
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_bound(&self) -> Option<GenericBound> {
|
pub fn to_bound(&self) -> Option<GenericBound> {
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
ExprKind::Path(None, path) => Some(GenericBound::Trait(
|
ExprKind::Path(None, path) => Some(GenericBound::Trait(
|
||||||
|
|
|
@ -220,9 +220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let parent_def_id = self.current_def_id_parent;
|
let parent_def_id = self.current_def_id_parent;
|
||||||
let node_id = self.next_node_id();
|
let node_id = self.next_node_id();
|
||||||
// HACK(min_generic_const_args): see lower_anon_const
|
// HACK(min_generic_const_args): see lower_anon_const
|
||||||
if !self.tcx.features().const_arg_path
|
if !expr.is_potential_trivial_const_arg() {
|
||||||
|| !expr.is_potential_trivial_const_arg()
|
|
||||||
{
|
|
||||||
self.create_def(
|
self.create_def(
|
||||||
parent_def_id,
|
parent_def_id,
|
||||||
node_id,
|
node_id,
|
||||||
|
|
|
@ -387,7 +387,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let node_id = self.next_node_id();
|
let node_id = self.next_node_id();
|
||||||
|
|
||||||
// HACK(min_generic_const_args): see lower_anon_const
|
// HACK(min_generic_const_args): see lower_anon_const
|
||||||
if !self.tcx.features().const_arg_path || !arg.is_potential_trivial_const_arg() {
|
if !arg.is_potential_trivial_const_arg() {
|
||||||
// Add a definition for the in-band const def.
|
// Add a definition for the in-band const def.
|
||||||
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
|
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2335,7 +2335,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> &'hir hir::ConstArg<'hir> {
|
) -> &'hir hir::ConstArg<'hir> {
|
||||||
let ct_kind = match res {
|
let ct_kind = match res {
|
||||||
Res::Def(DefKind::ConstParam, _) if self.tcx.features().const_arg_path => {
|
Res::Def(DefKind::ConstParam, _) => {
|
||||||
let qpath = self.lower_qpath(
|
let qpath = self.lower_qpath(
|
||||||
ty_id,
|
ty_id,
|
||||||
&None,
|
&None,
|
||||||
|
@ -2410,8 +2410,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
|
self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
|
||||||
debug!("res={:?}", maybe_res);
|
debug!("res={:?}", maybe_res);
|
||||||
// FIXME(min_generic_const_args): for now we only lower params to ConstArgKind::Path
|
// FIXME(min_generic_const_args): for now we only lower params to ConstArgKind::Path
|
||||||
if self.tcx.features().const_arg_path
|
if let Some(res) = maybe_res
|
||||||
&& let Some(res) = maybe_res
|
|
||||||
&& let Res::Def(DefKind::ConstParam, _) = res
|
&& let Res::Def(DefKind::ConstParam, _) = res
|
||||||
&& let ExprKind::Path(qself, path) = &expr.kind
|
&& let ExprKind::Path(qself, path) = &expr.kind
|
||||||
{
|
{
|
||||||
|
@ -2442,7 +2441,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
/// See [`hir::ConstArg`] for when to use this function vs
|
/// See [`hir::ConstArg`] for when to use this function vs
|
||||||
/// [`Self::lower_anon_const_to_const_arg`].
|
/// [`Self::lower_anon_const_to_const_arg`].
|
||||||
fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
|
fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
|
||||||
if self.tcx.features().const_arg_path && c.value.is_potential_trivial_const_arg() {
|
if c.value.is_potential_trivial_const_arg() {
|
||||||
// HACK(min_generic_const_args): see DefCollector::visit_anon_const
|
// HACK(min_generic_const_args): see DefCollector::visit_anon_const
|
||||||
// Over there, we guess if this is a bare param and only create a def if
|
// Over there, we guess if this is a bare param and only create a def if
|
||||||
// we think it's not. However we may can guess wrong (see there for example)
|
// we think it's not. However we may can guess wrong (see there for example)
|
||||||
|
|
|
@ -193,8 +193,6 @@ declare_features! (
|
||||||
(unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None),
|
(unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None),
|
||||||
/// Allows identifying the `compiler_builtins` crate.
|
/// Allows identifying the `compiler_builtins` crate.
|
||||||
(internal, compiler_builtins, "1.13.0", None),
|
(internal, compiler_builtins, "1.13.0", None),
|
||||||
/// Gating for a new desugaring of const arguments of usages of const parameters
|
|
||||||
(internal, const_arg_path, "1.81.0", None),
|
|
||||||
/// Allows writing custom MIR
|
/// Allows writing custom MIR
|
||||||
(internal, custom_mir, "1.65.0", None),
|
(internal, custom_mir, "1.65.0", None),
|
||||||
/// Outputs useful `assert!` messages
|
/// Outputs useful `assert!` messages
|
||||||
|
|
|
@ -295,20 +295,12 @@ impl<'tcx> Const<'tcx> {
|
||||||
_ => expr,
|
_ => expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let hir::ExprKind::Path(
|
if let hir::ExprKind::Path(hir::QPath::Resolved(
|
||||||
qpath @ hir::QPath::Resolved(
|
|
||||||
_,
|
_,
|
||||||
&hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
|
&hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
|
||||||
),
|
)) = expr.kind
|
||||||
) = expr.kind
|
|
||||||
{
|
{
|
||||||
if tcx.features().const_arg_path {
|
span_bug!(expr.span, "try_from_lit: received const param which shouldn't be possible");
|
||||||
span_bug!(
|
|
||||||
expr.span,
|
|
||||||
"try_from_lit: received const param which shouldn't be possible"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Some(Const::from_param(tcx, qpath, expr.hir_id));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let lit_input = match expr.kind {
|
let lit_input = match expr.kind {
|
||||||
|
|
|
@ -12,15 +12,23 @@ use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::{ImplTraitContext, Resolver};
|
use crate::{ImplTraitContext, InvocationParent, PendingAnonConstInfo, Resolver};
|
||||||
|
|
||||||
pub(crate) fn collect_definitions(
|
pub(crate) fn collect_definitions(
|
||||||
resolver: &mut Resolver<'_, '_>,
|
resolver: &mut Resolver<'_, '_>,
|
||||||
fragment: &AstFragment,
|
fragment: &AstFragment,
|
||||||
expansion: LocalExpnId,
|
expansion: LocalExpnId,
|
||||||
) {
|
) {
|
||||||
let (parent_def, impl_trait_context, in_attr) = resolver.invocation_parents[&expansion];
|
let InvocationParent { parent_def, pending_anon_const_info, impl_trait_context, in_attr } =
|
||||||
let mut visitor = DefCollector { resolver, parent_def, expansion, impl_trait_context, in_attr };
|
resolver.invocation_parents[&expansion];
|
||||||
|
let mut visitor = DefCollector {
|
||||||
|
resolver,
|
||||||
|
parent_def,
|
||||||
|
pending_anon_const_info,
|
||||||
|
expansion,
|
||||||
|
impl_trait_context,
|
||||||
|
in_attr,
|
||||||
|
};
|
||||||
fragment.visit_with(&mut visitor);
|
fragment.visit_with(&mut visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +36,13 @@ pub(crate) fn collect_definitions(
|
||||||
struct DefCollector<'a, 'ra, 'tcx> {
|
struct DefCollector<'a, 'ra, 'tcx> {
|
||||||
resolver: &'a mut Resolver<'ra, 'tcx>,
|
resolver: &'a mut Resolver<'ra, 'tcx>,
|
||||||
parent_def: LocalDefId,
|
parent_def: LocalDefId,
|
||||||
|
/// If we have an anon const that consists of a macro invocation, e.g. `Foo<{ m!() }>`,
|
||||||
|
/// we need to wait until we know what the macro expands to before we create the def for
|
||||||
|
/// the anon const. That's because we lower some anon consts into `hir::ConstArgKind::Path`,
|
||||||
|
/// which don't have defs.
|
||||||
|
///
|
||||||
|
/// See `Self::visit_anon_const()`.
|
||||||
|
pending_anon_const_info: Option<PendingAnonConstInfo>,
|
||||||
impl_trait_context: ImplTraitContext,
|
impl_trait_context: ImplTraitContext,
|
||||||
in_attr: bool,
|
in_attr: bool,
|
||||||
expansion: LocalExpnId,
|
expansion: LocalExpnId,
|
||||||
|
@ -111,10 +126,16 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
|
||||||
|
|
||||||
fn visit_macro_invoc(&mut self, id: NodeId) {
|
fn visit_macro_invoc(&mut self, id: NodeId) {
|
||||||
let id = id.placeholder_to_expn_id();
|
let id = id.placeholder_to_expn_id();
|
||||||
let old_parent = self
|
let pending_anon_const_info = self.pending_anon_const_info.take();
|
||||||
.resolver
|
let old_parent = self.resolver.invocation_parents.insert(
|
||||||
.invocation_parents
|
id,
|
||||||
.insert(id, (self.parent_def, self.impl_trait_context, self.in_attr));
|
InvocationParent {
|
||||||
|
parent_def: self.parent_def,
|
||||||
|
pending_anon_const_info,
|
||||||
|
impl_trait_context: self.impl_trait_context,
|
||||||
|
in_attr: self.in_attr,
|
||||||
|
},
|
||||||
|
);
|
||||||
assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation");
|
assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -326,46 +347,65 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_anon_const(&mut self, constant: &'a AnonConst) {
|
fn visit_anon_const(&mut self, constant: &'a AnonConst) {
|
||||||
if self.resolver.tcx.features().const_arg_path
|
|
||||||
&& constant.value.is_potential_trivial_const_arg()
|
|
||||||
{
|
|
||||||
// HACK(min_generic_const_args): don't create defs for anon consts if we think they will
|
// HACK(min_generic_const_args): don't create defs for anon consts if we think they will
|
||||||
// later be turned into ConstArgKind::Path's. because this is before resolve is done, we
|
// later be turned into ConstArgKind::Path's. because this is before resolve is done, we
|
||||||
// may accidentally identify a construction of a unit struct as a param and not create a
|
// may accidentally identify a construction of a unit struct as a param and not create a
|
||||||
// def. we'll then create a def later in ast lowering in this case. the parent of nested
|
// def. we'll then create a def later in ast lowering in this case. the parent of nested
|
||||||
// items will be messed up, but that's ok because there can't be any if we're just looking
|
// items will be messed up, but that's ok because there can't be any if we're just looking
|
||||||
// for bare idents.
|
// for bare idents.
|
||||||
visit::walk_anon_const(self, constant)
|
|
||||||
} else {
|
if matches!(constant.value.maybe_unwrap_block().kind, ExprKind::MacCall(..)) {
|
||||||
let def =
|
// See self.pending_anon_const_info for explanation
|
||||||
self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span);
|
self.pending_anon_const_info =
|
||||||
self.with_parent(def, |this| visit::walk_anon_const(this, constant));
|
Some(PendingAnonConstInfo { id: constant.id, span: constant.value.span });
|
||||||
|
return visit::walk_anon_const(self, constant);
|
||||||
|
} else if constant.value.is_potential_trivial_const_arg() {
|
||||||
|
return visit::walk_anon_const(self, constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let def = self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span);
|
||||||
|
self.with_parent(def, |this| visit::walk_anon_const(this, constant));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||||
|
if matches!(expr.kind, ExprKind::MacCall(..)) {
|
||||||
|
return self.visit_macro_invoc(expr.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let grandparent_def = if let Some(pending_anon) = self.pending_anon_const_info.take() {
|
||||||
|
// See self.pending_anon_const_info for explanation
|
||||||
|
if !expr.is_potential_trivial_const_arg() {
|
||||||
|
self.create_def(pending_anon.id, kw::Empty, DefKind::AnonConst, pending_anon.span)
|
||||||
|
} else {
|
||||||
|
self.parent_def
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.parent_def
|
||||||
|
};
|
||||||
|
|
||||||
|
self.with_parent(grandparent_def, |this| {
|
||||||
let parent_def = match expr.kind {
|
let parent_def = match expr.kind {
|
||||||
ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id),
|
|
||||||
ExprKind::Closure(..) | ExprKind::Gen(..) => {
|
ExprKind::Closure(..) | ExprKind::Gen(..) => {
|
||||||
self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
|
this.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
|
||||||
}
|
}
|
||||||
ExprKind::ConstBlock(ref constant) => {
|
ExprKind::ConstBlock(ref constant) => {
|
||||||
for attr in &expr.attrs {
|
for attr in &expr.attrs {
|
||||||
visit::walk_attribute(self, attr);
|
visit::walk_attribute(this, attr);
|
||||||
}
|
}
|
||||||
let def = self.create_def(
|
let def = this.create_def(
|
||||||
constant.id,
|
constant.id,
|
||||||
kw::Empty,
|
kw::Empty,
|
||||||
DefKind::InlineConst,
|
DefKind::InlineConst,
|
||||||
constant.value.span,
|
constant.value.span,
|
||||||
);
|
);
|
||||||
self.with_parent(def, |this| visit::walk_anon_const(this, constant));
|
this.with_parent(def, |this| visit::walk_anon_const(this, constant));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ => self.parent_def,
|
_ => this.parent_def,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.with_parent(parent_def, |this| visit::walk_expr(this, expr));
|
this.with_parent(parent_def, |this| visit::walk_expr(this, expr))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||||
|
|
|
@ -171,6 +171,29 @@ impl<'ra> ParentScope<'ra> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Debug, Clone)]
|
||||||
|
struct InvocationParent {
|
||||||
|
parent_def: LocalDefId,
|
||||||
|
pending_anon_const_info: Option<PendingAnonConstInfo>,
|
||||||
|
impl_trait_context: ImplTraitContext,
|
||||||
|
in_attr: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InvocationParent {
|
||||||
|
const ROOT: Self = Self {
|
||||||
|
parent_def: CRATE_DEF_ID,
|
||||||
|
pending_anon_const_info: None,
|
||||||
|
impl_trait_context: ImplTraitContext::Existential,
|
||||||
|
in_attr: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Debug, Clone)]
|
||||||
|
struct PendingAnonConstInfo {
|
||||||
|
id: NodeId,
|
||||||
|
span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Debug, Clone)]
|
#[derive(Copy, Debug, Clone)]
|
||||||
enum ImplTraitContext {
|
enum ImplTraitContext {
|
||||||
Existential,
|
Existential,
|
||||||
|
@ -1144,7 +1167,7 @@ pub struct Resolver<'ra, 'tcx> {
|
||||||
/// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
|
/// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
|
||||||
/// we know what parent node that fragment should be attached to thanks to this table,
|
/// we know what parent node that fragment should be attached to thanks to this table,
|
||||||
/// and how the `impl Trait` fragments were introduced.
|
/// and how the `impl Trait` fragments were introduced.
|
||||||
invocation_parents: FxHashMap<LocalExpnId, (LocalDefId, ImplTraitContext, bool /*in_attr*/)>,
|
invocation_parents: FxHashMap<LocalExpnId, InvocationParent>,
|
||||||
|
|
||||||
/// Some way to know that we are in a *trait* impl in `visit_assoc_item`.
|
/// Some way to know that we are in a *trait* impl in `visit_assoc_item`.
|
||||||
/// FIXME: Replace with a more general AST map (together with some other fields).
|
/// FIXME: Replace with a more general AST map (together with some other fields).
|
||||||
|
@ -1382,8 +1405,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
node_id_to_def_id.insert(CRATE_NODE_ID, crate_feed);
|
node_id_to_def_id.insert(CRATE_NODE_ID, crate_feed);
|
||||||
|
|
||||||
let mut invocation_parents = FxHashMap::default();
|
let mut invocation_parents = FxHashMap::default();
|
||||||
invocation_parents
|
invocation_parents.insert(LocalExpnId::ROOT, InvocationParent::ROOT);
|
||||||
.insert(LocalExpnId::ROOT, (CRATE_DEF_ID, ImplTraitContext::Existential, false));
|
|
||||||
|
|
||||||
let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'_>> = tcx
|
let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'_>> = tcx
|
||||||
.sess
|
.sess
|
||||||
|
|
|
@ -42,9 +42,9 @@ use crate::errors::{
|
||||||
use crate::imports::Import;
|
use crate::imports::Import;
|
||||||
use crate::Namespace::*;
|
use crate::Namespace::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
BindingKey, BuiltinMacroState, DeriveData, Determinacy, Finalize, MacroData, ModuleKind,
|
BindingKey, BuiltinMacroState, DeriveData, Determinacy, Finalize, InvocationParent, MacroData,
|
||||||
ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError,
|
ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
|
||||||
Resolver, ScopeSet, Segment, ToNameBinding, Used,
|
ResolutionError, Resolver, ScopeSet, Segment, ToNameBinding, Used,
|
||||||
};
|
};
|
||||||
|
|
||||||
type Res = def::Res<NodeId>;
|
type Res = def::Res<NodeId>;
|
||||||
|
@ -183,7 +183,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId {
|
fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId {
|
||||||
self.invocation_parents[&id].0
|
self.invocation_parents[&id].parent_def
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_dollar_crates(&mut self) {
|
fn resolve_dollar_crates(&mut self) {
|
||||||
|
@ -303,12 +303,12 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
|
||||||
.invocation_parents
|
.invocation_parents
|
||||||
.get(&invoc_id)
|
.get(&invoc_id)
|
||||||
.or_else(|| self.invocation_parents.get(&eager_expansion_root))
|
.or_else(|| self.invocation_parents.get(&eager_expansion_root))
|
||||||
.filter(|&&(mod_def_id, _, in_attr)| {
|
.filter(|&&InvocationParent { parent_def: mod_def_id, in_attr, .. }| {
|
||||||
in_attr
|
in_attr
|
||||||
&& invoc.fragment_kind == AstFragmentKind::Expr
|
&& invoc.fragment_kind == AstFragmentKind::Expr
|
||||||
&& self.tcx.def_kind(mod_def_id) == DefKind::Mod
|
&& self.tcx.def_kind(mod_def_id) == DefKind::Mod
|
||||||
})
|
})
|
||||||
.map(|&(mod_def_id, ..)| mod_def_id);
|
.map(|&InvocationParent { parent_def: mod_def_id, .. }| mod_def_id);
|
||||||
let (ext, res) = self.smart_resolve_macro_path(
|
let (ext, res) = self.smart_resolve_macro_path(
|
||||||
path,
|
path,
|
||||||
kind,
|
kind,
|
||||||
|
@ -951,7 +951,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
let node_id = self
|
let node_id = self
|
||||||
.invocation_parents
|
.invocation_parents
|
||||||
.get(&parent_scope.expansion)
|
.get(&parent_scope.expansion)
|
||||||
.map_or(ast::CRATE_NODE_ID, |id| self.def_id_to_node_id[id.0]);
|
.map_or(ast::CRATE_NODE_ID, |parent| {
|
||||||
|
self.def_id_to_node_id[parent.parent_def]
|
||||||
|
});
|
||||||
self.lint_buffer.buffer_lint(
|
self.lint_buffer.buffer_lint(
|
||||||
LEGACY_DERIVE_HELPERS,
|
LEGACY_DERIVE_HELPERS,
|
||||||
node_id,
|
node_id,
|
||||||
|
|
|
@ -599,7 +599,6 @@ symbols! {
|
||||||
conservative_impl_trait,
|
conservative_impl_trait,
|
||||||
console,
|
console,
|
||||||
const_allocate,
|
const_allocate,
|
||||||
const_arg_path,
|
|
||||||
const_async_blocks,
|
const_async_blocks,
|
||||||
const_closures,
|
const_closures,
|
||||||
const_compare_raw_pointers,
|
const_compare_raw_pointers,
|
||||||
|
|
|
@ -35,7 +35,7 @@ fn test_stable_mir() -> ControlFlow<()> {
|
||||||
// Get all items and split generic vs monomorphic items.
|
// Get all items and split generic vs monomorphic items.
|
||||||
let (generic, mono): (Vec<_>, Vec<_>) =
|
let (generic, mono): (Vec<_>, Vec<_>) =
|
||||||
items.into_iter().partition(|item| item.requires_monomorphization());
|
items.into_iter().partition(|item| item.requires_monomorphization());
|
||||||
assert_eq!(mono.len(), 4, "Expected 3 mono functions");
|
assert_eq!(mono.len(), 3, "Expected 3 mono functions");
|
||||||
assert_eq!(generic.len(), 2, "Expected 2 generic functions");
|
assert_eq!(generic.len(), 2, "Expected 2 generic functions");
|
||||||
|
|
||||||
// For all monomorphic items, get the correspondent instances.
|
// For all monomorphic items, get the correspondent instances.
|
||||||
|
|
|
@ -5,9 +5,7 @@
|
||||||
#![feature(with_negative_coherence)]
|
#![feature(with_negative_coherence)]
|
||||||
trait Trait {}
|
trait Trait {}
|
||||||
impl<const N: u8> Trait for [(); N] {}
|
impl<const N: u8> Trait for [(); N] {}
|
||||||
//~^ ERROR: mismatched types
|
|
||||||
impl<const N: i8> Trait for [(); N] {}
|
impl<const N: i8> Trait for [(); N] {}
|
||||||
//~^ ERROR: conflicting implementations of trait `Trait`
|
//~^ ERROR: conflicting implementations of trait `Trait`
|
||||||
//~| ERROR: mismatched types
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,25 +1,11 @@
|
||||||
error[E0119]: conflicting implementations of trait `Trait` for type `[(); _]`
|
error[E0119]: conflicting implementations of trait `Trait` for type `[(); _]`
|
||||||
--> $DIR/generic_const_type_mismatch.rs:9:1
|
--> $DIR/generic_const_type_mismatch.rs:8:1
|
||||||
|
|
|
|
||||||
LL | impl<const N: u8> Trait for [(); N] {}
|
LL | impl<const N: u8> Trait for [(); N] {}
|
||||||
| ----------------------------------- first implementation here
|
| ----------------------------------- first implementation here
|
||||||
LL |
|
|
||||||
LL | impl<const N: i8> Trait for [(); N] {}
|
LL | impl<const N: i8> Trait for [(); N] {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); _]`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); _]`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/generic_const_type_mismatch.rs:7:34
|
|
||||||
|
|
|
||||||
LL | impl<const N: u8> Trait for [(); N] {}
|
|
||||||
| ^ expected `usize`, found `u8`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
--> $DIR/generic_const_type_mismatch.rs:9:34
|
|
||||||
|
|
|
||||||
LL | impl<const N: i8> Trait for [(); N] {}
|
|
||||||
| ^ expected `usize`, found `i8`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0119, E0308.
|
|
||||||
For more information about an error, try `rustc --explain E0119`.
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ trait Q {
|
||||||
|
|
||||||
impl<const N: u64> Q for [u8; N] {
|
impl<const N: u64> Q for [u8; N] {
|
||||||
//~^ ERROR: the constant `N` is not of type `usize`
|
//~^ ERROR: the constant `N` is not of type `usize`
|
||||||
//~| ERROR: mismatched types
|
|
||||||
const ASSOC: usize = 1;
|
const ASSOC: usize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | impl<const N: u64> Q for [u8; N] {
|
||||||
| ^^^^^^^ expected `usize`, found `u64`
|
| ^^^^^^^ expected `usize`, found `u64`
|
||||||
|
|
||||||
error: the constant `13` is not of type `u64`
|
error: the constant `13` is not of type `u64`
|
||||||
--> $DIR/bad-subst-const-kind.rs:14:24
|
--> $DIR/bad-subst-const-kind.rs:13:24
|
||||||
|
|
|
|
||||||
LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] {
|
LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] {
|
||||||
| ^^^^^^^^ expected `u64`, found `usize`
|
| ^^^^^^^^ expected `u64`, found `usize`
|
||||||
|
@ -18,12 +18,5 @@ LL | impl<const N: u64> Q for [u8; N] {
|
||||||
| |
|
| |
|
||||||
| unsatisfied trait bound introduced here
|
| unsatisfied trait bound introduced here
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/bad-subst-const-kind.rs:8:31
|
|
||||||
|
|
|
||||||
LL | impl<const N: u64> Q for [u8; N] {
|
|
||||||
| ^ expected `usize`, found `u64`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ trait Q {
|
||||||
impl<const N: u64> Q for [u8; N] {}
|
impl<const N: u64> Q for [u8; N] {}
|
||||||
//~^ ERROR not all trait items implemented
|
//~^ ERROR not all trait items implemented
|
||||||
//~| ERROR the constant `N` is not of type `usize`
|
//~| ERROR the constant `N` is not of type `usize`
|
||||||
//~| ERROR mismatched types
|
|
||||||
|
|
||||||
pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
|
pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
|
||||||
//~^ ERROR the constant `13` is not of type `u64`
|
//~^ ERROR the constant `13` is not of type `u64`
|
||||||
|
|
|
@ -14,7 +14,7 @@ LL | impl<const N: u64> Q for [u8; N] {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation
|
||||||
|
|
||||||
error: the constant `13` is not of type `u64`
|
error: the constant `13` is not of type `u64`
|
||||||
--> $DIR/type_mismatch.rs:13:26
|
--> $DIR/type_mismatch.rs:12:26
|
||||||
|
|
|
|
||||||
LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
|
LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
|
||||||
| ^^^^^^^^ expected `u64`, found `usize`
|
| ^^^^^^^^ expected `u64`, found `usize`
|
||||||
|
@ -28,20 +28,14 @@ LL | impl<const N: u64> Q for [u8; N] {}
|
||||||
| unsatisfied trait bound introduced here
|
| unsatisfied trait bound introduced here
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/type_mismatch.rs:13:20
|
--> $DIR/type_mismatch.rs:12:20
|
||||||
|
|
|
|
||||||
LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
|
LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
|
||||||
| ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `[u8; <[u8; 13] as Q>::ASSOC]`, found `()`
|
| ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `[u8; <[u8; 13] as Q>::ASSOC]`, found `()`
|
||||||
| |
|
| |
|
||||||
| implicitly returns `()` as its body has no tail or `return` expression
|
| implicitly returns `()` as its body has no tail or `return` expression
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 4 previous errors
|
||||||
--> $DIR/type_mismatch.rs:8:31
|
|
||||||
|
|
|
||||||
LL | impl<const N: u64> Q for [u8; N] {}
|
|
||||||
| ^ expected `usize`, found `u64`
|
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0046, E0308.
|
Some errors have detailed explanations: E0046, E0308.
|
||||||
For more information about an error, try `rustc --explain E0046`.
|
For more information about an error, try `rustc --explain E0046`.
|
||||||
|
|
|
@ -25,8 +25,8 @@ mod v20 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const v10: usize> v17<v10, v2> {
|
impl<const v10: usize> v17<v10, v2> {
|
||||||
//~^ ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
|
//~^ ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
|
||||||
//~| ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
|
//~| ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
|
||||||
pub const fn v21() -> v18 {
|
pub const fn v21() -> v18 {
|
||||||
//~^ ERROR cannot find type `v18` in this scope
|
//~^ ERROR cannot find type `v18` in this scope
|
||||||
v18 { _p: () }
|
v18 { _p: () }
|
||||||
|
|
|
@ -72,13 +72,13 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
|
||||||
LL + #![feature(adt_const_params)]
|
LL + #![feature(adt_const_params)]
|
||||||
|
|
|
|
||||||
|
|
||||||
error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
|
error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
|
||||||
--> $DIR/unevaluated-const-ice-119731.rs:27:37
|
--> $DIR/unevaluated-const-ice-119731.rs:27:37
|
||||||
|
|
|
|
||||||
LL | impl<const v10: usize> v17<v10, v2> {
|
LL | impl<const v10: usize> v17<v10, v2> {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
|
error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
|
||||||
--> $DIR/unevaluated-const-ice-119731.rs:27:37
|
--> $DIR/unevaluated-const-ice-119731.rs:27:37
|
||||||
|
|
|
|
||||||
LL | impl<const v10: usize> v17<v10, v2> {
|
LL | impl<const v10: usize> v17<v10, v2> {
|
||||||
|
|
|
@ -11,8 +11,6 @@ fn foo<const W: usize, const H: usize>(v: [[u32; H + 1]; W]) -> [[u32; W + 1]; H
|
||||||
|
|
||||||
fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
|
fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
|
||||||
//~^ ERROR: the constant `W` is not of type `usize`
|
//~^ ERROR: the constant `W` is not of type `usize`
|
||||||
//~| ERROR: mismatched types
|
|
||||||
//~| ERROR: mismatched types
|
|
||||||
unsafe {
|
unsafe {
|
||||||
std::mem::transmute(v)
|
std::mem::transmute(v)
|
||||||
//~^ ERROR: the constant `W` is not of type `usize`
|
//~^ ERROR: the constant `W` is not of type `usize`
|
||||||
|
|
|
@ -14,13 +14,13 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[[u32; W + 1]; H]` (size can vary because of [u32; W + 1])
|
= note: target type: `[[u32; W + 1]; H]` (size can vary because of [u32; W + 1])
|
||||||
|
|
||||||
error: the constant `W` is not of type `usize`
|
error: the constant `W` is not of type `usize`
|
||||||
--> $DIR/transmute-fail.rs:17:9
|
--> $DIR/transmute-fail.rs:15:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool`
|
| ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool`
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:24:9
|
--> $DIR/transmute-fail.rs:22:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -29,7 +29,7 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[u32; W * H * H]` (this type does not have a fixed size)
|
= note: target type: `[u32; W * H * H]` (this type does not have a fixed size)
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:31:9
|
--> $DIR/transmute-fail.rs:29:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -38,7 +38,7 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type `[[u32; 9999999]; 777777777]` are too big for the current architecture)
|
= note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type `[[u32; 9999999]; 777777777]` are too big for the current architecture)
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:38:9
|
--> $DIR/transmute-fail.rs:36:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -47,7 +47,7 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
|
= note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:49:9
|
--> $DIR/transmute-fail.rs:47:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -56,7 +56,7 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[u32; W * H]` (this type does not have a fixed size)
|
= note: target type: `[u32; W * H]` (this type does not have a fixed size)
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:56:9
|
--> $DIR/transmute-fail.rs:54:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -65,7 +65,7 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
|
= note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:65:9
|
--> $DIR/transmute-fail.rs:63:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -74,7 +74,7 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[u32; D * W * H]` (this type does not have a fixed size)
|
= note: target type: `[u32; D * W * H]` (this type does not have a fixed size)
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:74:9
|
--> $DIR/transmute-fail.rs:72:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -83,7 +83,7 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[[u32; D * W]; H]` (size can vary because of [u32; D * W])
|
= note: target type: `[[u32; D * W]; H]` (size can vary because of [u32; D * W])
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:81:9
|
--> $DIR/transmute-fail.rs:79:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -92,7 +92,7 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[u8; L * 2]` (this type does not have a fixed size)
|
= note: target type: `[u8; L * 2]` (this type does not have a fixed size)
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:88:9
|
--> $DIR/transmute-fail.rs:86:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -101,7 +101,7 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[u16; L]` (this type does not have a fixed size)
|
= note: target type: `[u16; L]` (this type does not have a fixed size)
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:95:9
|
--> $DIR/transmute-fail.rs:93:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -110,7 +110,7 @@ LL | std::mem::transmute(v)
|
||||||
= note: target type: `[[u8; 1]; L]` (this type does not have a fixed size)
|
= note: target type: `[[u8; 1]; L]` (this type does not have a fixed size)
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:104:9
|
--> $DIR/transmute-fail.rs:102:9
|
||||||
|
|
|
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -118,19 +118,6 @@ LL | std::mem::transmute(v)
|
||||||
= note: source type: `[[u32; 2 * H]; W + W]` (size can vary because of [u32; 2 * H])
|
= note: source type: `[[u32; 2 * H]; W + W]` (size can vary because of [u32; 2 * H])
|
||||||
= note: target type: `[[u32; W + W]; 2 * H]` (size can vary because of [u32; W + W])
|
= note: target type: `[[u32; W + W]; 2 * H]` (size can vary because of [u32; W + W])
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 14 previous errors
|
||||||
--> $DIR/transmute-fail.rs:12:53
|
|
||||||
|
|
|
||||||
LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
|
|
||||||
| ^ expected `usize`, found `bool`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
For more information about this error, try `rustc --explain E0512`.
|
||||||
--> $DIR/transmute-fail.rs:12:67
|
|
||||||
|
|
|
||||||
LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
|
|
||||||
| ^ expected `usize`, found `bool`
|
|
||||||
|
|
||||||
error: aborting due to 16 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0512.
|
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
fn foo<const N: usize>() -> [u8; N] {
|
fn foo<const N: usize>() -> [u8; N] {
|
||||||
bar::<N>()
|
bar::<N>()
|
||||||
//~^ ERROR the constant `N` is not of type `u8`
|
//~^ ERROR the constant `N` is not of type `u8`
|
||||||
//~| ERROR: mismatched types
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bar<const N: u8>() -> [u8; N] {}
|
fn bar<const N: u8>() -> [u8; N] {}
|
||||||
//~^ ERROR the constant `N` is not of type `usize`
|
//~^ ERROR the constant `N` is not of type `usize`
|
||||||
//~| ERROR: mismatched types
|
|
||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: the constant `N` is not of type `usize`
|
error: the constant `N` is not of type `usize`
|
||||||
--> $DIR/type_mismatch.rs:7:26
|
--> $DIR/type_mismatch.rs:6:26
|
||||||
|
|
|
|
||||||
LL | fn bar<const N: u8>() -> [u8; N] {}
|
LL | fn bar<const N: u8>() -> [u8; N] {}
|
||||||
| ^^^^^^^ expected `usize`, found `u8`
|
| ^^^^^^^ expected `usize`, found `u8`
|
||||||
|
@ -11,31 +11,19 @@ LL | bar::<N>()
|
||||||
| ^ expected `u8`, found `usize`
|
| ^ expected `u8`, found `usize`
|
||||||
|
|
|
|
||||||
note: required by a const generic parameter in `bar`
|
note: required by a const generic parameter in `bar`
|
||||||
--> $DIR/type_mismatch.rs:7:8
|
--> $DIR/type_mismatch.rs:6:8
|
||||||
|
|
|
|
||||||
LL | fn bar<const N: u8>() -> [u8; N] {}
|
LL | fn bar<const N: u8>() -> [u8; N] {}
|
||||||
| ^^^^^^^^^^^ required by this const generic parameter in `bar`
|
| ^^^^^^^^^^^ required by this const generic parameter in `bar`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/type_mismatch.rs:7:26
|
--> $DIR/type_mismatch.rs:6:26
|
||||||
|
|
|
|
||||||
LL | fn bar<const N: u8>() -> [u8; N] {}
|
LL | fn bar<const N: u8>() -> [u8; N] {}
|
||||||
| --- ^^^^^^^ expected `[u8; N]`, found `()`
|
| --- ^^^^^^^ expected `[u8; N]`, found `()`
|
||||||
| |
|
| |
|
||||||
| implicitly returns `()` as its body has no tail or `return` expression
|
| implicitly returns `()` as its body has no tail or `return` expression
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 3 previous errors
|
||||||
--> $DIR/type_mismatch.rs:2:11
|
|
||||||
|
|
|
||||||
LL | bar::<N>()
|
|
||||||
| ^ expected `u8`, found `usize`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/type_mismatch.rs:7:31
|
|
||||||
|
|
|
||||||
LL | fn bar<const N: u8>() -> [u8; N] {}
|
|
||||||
| ^ expected `usize`, found `u8`
|
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error[E0391]: cycle detected when simplifying constant for the type system `Foo::B::{constant#0}`
|
error[E0391]: cycle detected when simplifying constant for the type system `Foo::{constant#0}`
|
||||||
--> $DIR/issue-36163.rs:4:9
|
--> $DIR/issue-36163.rs:4:9
|
||||||
|
|
|
|
||||||
LL | B = A,
|
LL | B = A,
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
note: ...which requires const-evaluating + checking `Foo::B::{constant#0}`...
|
note: ...which requires const-evaluating + checking `Foo::{constant#0}`...
|
||||||
--> $DIR/issue-36163.rs:4:9
|
--> $DIR/issue-36163.rs:4:9
|
||||||
|
|
|
|
||||||
LL | B = A,
|
LL | B = A,
|
||||||
|
@ -19,7 +19,7 @@ note: ...which requires const-evaluating + checking `A`...
|
||||||
|
|
|
|
||||||
LL | const A: isize = Foo::B as isize;
|
LL | const A: isize = Foo::B as isize;
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
= note: ...which again requires simplifying constant for the type system `Foo::B::{constant#0}`, completing the cycle
|
= note: ...which again requires simplifying constant for the type system `Foo::{constant#0}`, completing the cycle
|
||||||
note: cycle used when checking that `Foo` is well-formed
|
note: cycle used when checking that `Foo` is well-formed
|
||||||
--> $DIR/issue-36163.rs:3:1
|
--> $DIR/issue-36163.rs:3:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
// this doesn't really have any user facing impact....
|
|
||||||
|
|
||||||
fn main() {}
|
|
|
@ -9,6 +9,5 @@ impl Fn(&isize) for Error {
|
||||||
//~^ ERROR associated function in `impl` without body
|
//~^ ERROR associated function in `impl` without body
|
||||||
//~| ERROR method `foo` is not a member of trait `Fn` [E0407]
|
//~| ERROR method `foo` is not a member of trait `Fn` [E0407]
|
||||||
//~| ERROR associated type `B` not found for `Self` [E0220]
|
//~| ERROR associated type `B` not found for `Self` [E0220]
|
||||||
//~| ERROR: associated type `B` not found for `Self`
|
|
||||||
}
|
}
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -56,15 +56,7 @@ error[E0220]: associated type `B` not found for `Self`
|
||||||
LL | fn foo<const N: usize>(&self) -> Self::B<{ N }>;
|
LL | fn foo<const N: usize>(&self) -> Self::B<{ N }>;
|
||||||
| ^ help: `Self` has the following associated type: `Output`
|
| ^ help: `Self` has the following associated type: `Output`
|
||||||
|
|
||||||
error[E0220]: associated type `B` not found for `Self`
|
error: aborting due to 7 previous errors
|
||||||
--> $DIR/issue-95023.rs:8:44
|
|
||||||
|
|
|
||||||
LL | fn foo<const N: usize>(&self) -> Self::B<{ N }>;
|
|
||||||
| ^ help: `Self` has the following associated type: `Output`
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0046, E0183, E0220, E0229, E0277, E0407.
|
Some errors have detailed explanations: E0046, E0183, E0220, E0229, E0277, E0407.
|
||||||
For more information about an error, try `rustc --explain E0046`.
|
For more information about an error, try `rustc --explain E0046`.
|
||||||
|
|
|
@ -14,6 +14,5 @@ struct Wrapper<const C: <i32 as Trait>::Type> {}
|
||||||
|
|
||||||
impl<const C: usize> Wrapper<C> {}
|
impl<const C: usize> Wrapper<C> {}
|
||||||
//~^ ERROR the constant `C` is not of type `<i32 as Trait>::Type`
|
//~^ ERROR the constant `C` is not of type `<i32 as Trait>::Type`
|
||||||
//~| ERROR: mismatched types
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -20,17 +20,5 @@ note: required by a const generic parameter in `Wrapper`
|
||||||
LL | struct Wrapper<const C: <i32 as Trait>::Type> {}
|
LL | struct Wrapper<const C: <i32 as Trait>::Type> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `Wrapper`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `Wrapper`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:15:30
|
|
||||||
|
|
|
||||||
LL | impl<const C: usize> Wrapper<C> {}
|
|
||||||
| ^ expected associated type, found `usize`
|
|
||||||
|
|
|
||||||
= note: expected associated type `<i32 as Trait>::Type`
|
|
||||||
found type `usize`
|
|
||||||
= help: consider constraining the associated type `<i32 as Trait>::Type` to `usize`
|
|
||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
struct S<const L: usize>;
|
struct S<const L: usize>;
|
||||||
|
|
||||||
impl<const N: i32> Copy for S<N> {}
|
impl<const N: i32> Copy for S<N> {}
|
||||||
//~^ ERROR: mismatched types
|
|
||||||
impl<const M: usize> Copy for S<M> {}
|
impl<const M: usize> Copy for S<M> {}
|
||||||
//~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>`
|
//~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>`
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
error[E0119]: conflicting implementations of trait `Copy` for type `S<_>`
|
error[E0119]: conflicting implementations of trait `Copy` for type `S<_>`
|
||||||
--> $DIR/bad-const-wf-doesnt-specialize.rs:10:1
|
--> $DIR/bad-const-wf-doesnt-specialize.rs:9:1
|
||||||
|
|
|
|
||||||
LL | impl<const N: i32> Copy for S<N> {}
|
LL | impl<const N: i32> Copy for S<N> {}
|
||||||
| -------------------------------- first implementation here
|
| -------------------------------- first implementation here
|
||||||
LL |
|
|
||||||
LL | impl<const M: usize> Copy for S<M> {}
|
LL | impl<const M: usize> Copy for S<M> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:31
|
|
||||||
|
|
|
||||||
LL | impl<const N: i32> Copy for S<N> {}
|
|
||||||
| ^ expected `usize`, found `i32`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0119, E0308.
|
|
||||||
For more information about an error, try `rustc --explain E0119`.
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ mod assert {
|
||||||
where
|
where
|
||||||
Dst: TransmuteFrom<Src, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope
|
Dst: TransmuteFrom<Src, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope
|
||||||
//~| the constant `ASSUME_ALIGNMENT` is not of type `Assume`
|
//~| the constant `ASSUME_ALIGNMENT` is not of type `Assume`
|
||||||
//~| ERROR: mismatched types
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,6 @@ LL | Dst: TransmuteFrom<Src, ASSUME_ALIGNMENT>,
|
||||||
note: required by a const generic parameter in `TransmuteFrom`
|
note: required by a const generic parameter in `TransmuteFrom`
|
||||||
--> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
|
--> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/issue-101739-1.rs:8:33
|
|
||||||
|
|
|
||||||
LL | Dst: TransmuteFrom<Src, ASSUME_ALIGNMENT>,
|
|
||||||
| ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
For more information about this error, try `rustc --explain E0412`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0412.
|
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ mod assert {
|
||||||
Dst: TransmuteFrom<
|
Dst: TransmuteFrom<
|
||||||
//~^ ERROR trait takes at most 2 generic arguments but 5 generic arguments were supplied
|
//~^ ERROR trait takes at most 2 generic arguments but 5 generic arguments were supplied
|
||||||
Src,
|
Src,
|
||||||
ASSUME_ALIGNMENT, //~ ERROR: mismatched types
|
ASSUME_ALIGNMENT,
|
||||||
ASSUME_LIFETIMES,
|
ASSUME_LIFETIMES,
|
||||||
ASSUME_VALIDITY,
|
ASSUME_VALIDITY,
|
||||||
ASSUME_VISIBILITY,
|
ASSUME_VISIBILITY,
|
||||||
|
|
|
@ -11,13 +11,6 @@ LL | | ASSUME_VALIDITY,
|
||||||
LL | | ASSUME_VISIBILITY,
|
LL | | ASSUME_VISIBILITY,
|
||||||
| |_________________________________- help: remove the unnecessary generic arguments
|
| |_________________________________- help: remove the unnecessary generic arguments
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/issue-101739-2.rs:20:17
|
|
||||||
|
|
|
||||||
LL | ASSUME_ALIGNMENT,
|
|
||||||
| ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0107`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0107, E0308.
|
|
||||||
For more information about an error, try `rustc --explain E0107`.
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
trait Trait {
|
trait Trait {
|
||||||
fn func<const N: u32>() -> [(); N];
|
fn func<const N: u32>() -> [(); N];
|
||||||
//~^ ERROR: the constant `N` is not of type `usize`
|
//~^ ERROR: the constant `N` is not of type `usize`
|
||||||
//~| ERROR: mismatched types
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct S {}
|
struct S {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/const-in-impl-fn-return-type.rs:16:39
|
--> $DIR/const-in-impl-fn-return-type.rs:15:39
|
||||||
|
|
|
|
||||||
LL | fn func<const N: u32>() -> [(); { () }] {
|
LL | fn func<const N: u32>() -> [(); { () }] {
|
||||||
| ^^ expected `usize`, found `()`
|
| ^^ expected `usize`, found `()`
|
||||||
|
@ -10,12 +10,6 @@ error: the constant `N` is not of type `usize`
|
||||||
LL | fn func<const N: u32>() -> [(); N];
|
LL | fn func<const N: u32>() -> [(); N];
|
||||||
| ^^^^^^^ expected `usize`, found `u32`
|
| ^^^^^^^ expected `usize`, found `u32`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/const-in-impl-fn-return-type.rs:7:37
|
|
||||||
|
|
|
||||||
LL | fn func<const N: u32>() -> [(); N];
|
|
||||||
| ^ expected `usize`, found `u32`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue