don't supply generics to AnonConsts in param lists
This commit is contained in:
parent
3f55840243
commit
6f5d8bf5c8
4 changed files with 68 additions and 37 deletions
|
@ -29,7 +29,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
|
||||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
use rustc_hir::weak_lang_items;
|
use rustc_hir::weak_lang_items;
|
||||||
use rustc_hir::{GenericParamKind, Node};
|
use rustc_hir::{GenericParamKind, HirId, Node};
|
||||||
use rustc_middle::hir::map::blocks::FnLikeNode;
|
use rustc_middle::hir::map::blocks::FnLikeNode;
|
||||||
use rustc_middle::hir::map::Map;
|
use rustc_middle::hir::map::Map;
|
||||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
||||||
|
@ -1155,6 +1155,35 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AnonConstInParamListDetector {
|
||||||
|
in_param_list: bool,
|
||||||
|
found_anon_const_in_list: bool,
|
||||||
|
ct: HirId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'v> Visitor<'v> for AnonConstInParamListDetector {
|
||||||
|
type Map = intravisit::ErasedMap<'v>;
|
||||||
|
|
||||||
|
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
||||||
|
NestedVisitorMap::None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) {
|
||||||
|
let prev = self.in_param_list;
|
||||||
|
self.in_param_list = true;
|
||||||
|
intravisit::walk_generic_param(self, p);
|
||||||
|
self.in_param_list = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_anon_const(&mut self, c: &'v hir::AnonConst) {
|
||||||
|
if self.in_param_list && self.ct == c.hir_id {
|
||||||
|
self.found_anon_const_in_list = true;
|
||||||
|
} else {
|
||||||
|
intravisit::walk_anon_const(self, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
|
|
||||||
|
@ -1176,10 +1205,32 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
||||||
let parent_id = tcx.hir().get_parent_item(hir_id);
|
let parent_id = tcx.hir().get_parent_item(hir_id);
|
||||||
let parent_def_id = tcx.hir().local_def_id(parent_id);
|
let parent_def_id = tcx.hir().local_def_id(parent_id);
|
||||||
|
|
||||||
// HACK(eddyb) this provides the correct generics when
|
let mut in_param_list = false;
|
||||||
// `feature(const_generics)` is enabled, so that const expressions
|
for (_parent, node) in tcx.hir().parent_iter(hir_id) {
|
||||||
// used with const generics, e.g. `Foo<{N+1}>`, can work at all.
|
if let Some(generics) = node.generics() {
|
||||||
if tcx.lazy_normalization() {
|
let mut visitor = AnonConstInParamListDetector {
|
||||||
|
in_param_list: false,
|
||||||
|
found_anon_const_in_list: false,
|
||||||
|
ct: hir_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
visitor.visit_generics(generics);
|
||||||
|
in_param_list = visitor.found_anon_const_in_list;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if in_param_list {
|
||||||
|
// We do not allow generic parameters in anon consts if we are inside
|
||||||
|
// of a param list.
|
||||||
|
//
|
||||||
|
// This affects both default type bindings, e.g. `struct<T, U = [u8; std::mem::size_of::<T>()]>(T, U)`,
|
||||||
|
// and the types of const parameters, e.g. `struct V<const N: usize, const M: [u8; N]>();`.
|
||||||
|
None
|
||||||
|
} else if tcx.lazy_normalization() {
|
||||||
|
// HACK(eddyb) this provides the correct generics when
|
||||||
|
// `feature(const_generics)` is enabled, so that const expressions
|
||||||
|
// used with const generics, e.g. `Foo<{N+1}>`, can work at all.
|
||||||
Some(parent_def_id.to_def_id())
|
Some(parent_def_id.to_def_id())
|
||||||
} else {
|
} else {
|
||||||
let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
|
let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
|
||||||
|
|
|
@ -8,10 +8,8 @@
|
||||||
|
|
||||||
pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||||
//~| ERROR: cycle detected when computing type of `Dependent::X`
|
|
||||||
|
|
||||||
pub struct SelfDependent<const N: [u8; N]>;
|
pub struct SelfDependent<const N: [u8; N]>;
|
||||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||||
//~| ERROR: cycle detected when computing type of `SelfDependent::N`
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -4,8 +4,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||||
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||||
| ^ const parameters must have a concrete type
|
| ^ const parameters must have a concrete type
|
||||||
|
|
||||||
error[E0769]: the type of const parameters must not depend on other generic parameters
|
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||||
--> $DIR/const-param-type-depends-on-const-param.rs:13:40
|
--> $DIR/const-param-type-depends-on-const-param.rs:12:40
|
||||||
|
|
|
|
||||||
LL | pub struct SelfDependent<const N: [u8; N]>;
|
LL | pub struct SelfDependent<const N: [u8; N]>;
|
||||||
| ^ const parameters must have a concrete type
|
| ^ const parameters must have a concrete type
|
||||||
|
@ -19,32 +19,5 @@ LL | #![feature(const_generics)]
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `Dependent::X`
|
error: aborting due to 2 previous errors; 1 warning emitted
|
||||||
--> $DIR/const-param-type-depends-on-const-param.rs:9:44
|
|
||||||
|
|
|
||||||
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
|
||||||
| ^
|
|
||||||
|
|
|
||||||
= note: ...which again requires computing type of `Dependent::X`, completing the cycle
|
|
||||||
note: cycle used when computing type of `Dependent`
|
|
||||||
--> $DIR/const-param-type-depends-on-const-param.rs:9:1
|
|
||||||
|
|
|
||||||
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `SelfDependent::N`
|
|
||||||
--> $DIR/const-param-type-depends-on-const-param.rs:13:32
|
|
||||||
|
|
|
||||||
LL | pub struct SelfDependent<const N: [u8; N]>;
|
|
||||||
| ^
|
|
||||||
|
|
|
||||||
= note: ...which again requires computing type of `SelfDependent::N`, completing the cycle
|
|
||||||
note: cycle used when computing type of `SelfDependent`
|
|
||||||
--> $DIR/const-param-type-depends-on-const-param.rs:13:1
|
|
||||||
|
|
|
||||||
LL | pub struct SelfDependent<const N: [u8; N]>;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors; 1 warning emitted
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0391`.
|
|
||||||
|
|
9
src/test/ui/const-generics/issues/issue-74101.rs
Normal file
9
src/test/ui/const-generics/issues/issue-74101.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// check-pass
|
||||||
|
#![feature(const_generics)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
fn test<const N: [u8; 1 + 2]>() {}
|
||||||
|
|
||||||
|
struct Foo<const N: [u8; 1 + 2]>;
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue