Rollup merge of #70284 - lcnr:issue70273-what-the-heck-git, r=eddyb
correctly handle const params in type_of extends #70223, retry of #70276 fixes #70273 r? @eddyb cc @varkor
This commit is contained in:
commit
d309058101
@ -159,6 +159,7 @@ pub fn matches_ns(&self, ns: Namespace) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
/// The resolution of a path or export.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
#[derive(HashStable_Generic)]
|
||||
pub enum Res<Id = hir::HirId> {
|
||||
|
@ -235,29 +235,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
};
|
||||
|
||||
if let Some(path) = path {
|
||||
let arg_index = path
|
||||
// We've encountered an `AnonConst` in some path, so we need to
|
||||
// figure out which generic parameter it corresponds to and return
|
||||
// the relevant type.
|
||||
|
||||
let (arg_index, segment) = path
|
||||
.segments
|
||||
.iter()
|
||||
.filter_map(|seg| seg.args.as_ref())
|
||||
.map(|generic_args| generic_args.args)
|
||||
.find_map(|args| {
|
||||
.filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg)))
|
||||
.find_map(|(args, seg)| {
|
||||
args.iter()
|
||||
.filter(|arg| arg.is_const())
|
||||
.enumerate()
|
||||
.filter(|(_, arg)| arg.id() == hir_id)
|
||||
.map(|(index, _)| index)
|
||||
.map(|(index, _)| (index, seg))
|
||||
.next()
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
bug!("no arg matching AnonConst in path");
|
||||
});
|
||||
|
||||
// We've encountered an `AnonConst` in some path, so we need to
|
||||
// figure out which generic parameter it corresponds to and return
|
||||
// the relevant type.
|
||||
let generics = match path.res {
|
||||
Res::Def(DefKind::Ctor(..), def_id)
|
||||
| Res::Def(DefKind::AssocTy, def_id) => {
|
||||
// Try to use the segment resolution if it is valid, otherwise we
|
||||
// default to the path resolution.
|
||||
let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
|
||||
let generics = match res {
|
||||
Res::Def(DefKind::Ctor(..), def_id) => {
|
||||
tcx.generics_of(tcx.parent(def_id).unwrap())
|
||||
}
|
||||
Res::Def(_, def_id) => tcx.generics_of(def_id),
|
||||
@ -265,8 +267,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
tcx.sess.delay_span_bug(
|
||||
DUMMY_SP,
|
||||
&format!(
|
||||
"unexpected const parent path def, parent: {:?}, def: {:?}",
|
||||
parent_node, res
|
||||
"unexpected anon const res {:?} in path: {:?}",
|
||||
res, path,
|
||||
),
|
||||
);
|
||||
return tcx.types.err;
|
||||
@ -291,8 +293,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
tcx.sess.delay_span_bug(
|
||||
DUMMY_SP,
|
||||
&format!(
|
||||
"missing generic parameter for `AnonConst`, parent {:?}",
|
||||
parent_node
|
||||
"missing generic parameter for `AnonConst`, parent: {:?}, res: {:?}",
|
||||
parent_node, res
|
||||
),
|
||||
);
|
||||
tcx.types.err
|
||||
|
@ -62,6 +62,7 @@
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(never_type)]
|
||||
#![feature(slice_partition_dedup)]
|
||||
|
17
src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
Normal file
17
src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
trait T<const A: usize> {
|
||||
fn f();
|
||||
}
|
||||
struct S;
|
||||
|
||||
impl T<0usize> for S {
|
||||
fn f() {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _err = <S as T<0usize>>::f();
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/issue70273-assoc-fn.rs:3:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
21
src/test/ui/const-generics/type_of_anon_const.rs
Normal file
21
src/test/ui/const-generics/type_of_anon_const.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
trait T<const A: usize> {
|
||||
fn l<const N: bool>() -> usize;
|
||||
fn r<const N: bool>() -> bool;
|
||||
}
|
||||
|
||||
struct S;
|
||||
|
||||
impl<const N: usize> T<N> for S {
|
||||
fn l<const M: bool>() -> usize { N }
|
||||
fn r<const M: bool>() -> bool { M }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(<S as T<123>>::l::<true>(), 123);
|
||||
assert!(<S as T<123>>::r::<true>());
|
||||
}
|
8
src/test/ui/const-generics/type_of_anon_const.stderr
Normal file
8
src/test/ui/const-generics/type_of_anon_const.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/type_of_anon_const.rs:3:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
Loading…
Reference in New Issue
Block a user