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:
Mazdak Farrokhzad 2020-03-24 07:13:40 +01:00 committed by GitHub
commit d309058101
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 15 deletions

View File

@ -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> {

View File

@ -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

View File

@ -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)]

View 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();
}

View File

@ -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

View 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>());
}

View 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