Skip to content

Commit

Permalink
correctly handle const params in type_of
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Mar 22, 2020
1 parent 1902d1e commit 645fedd
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/librustc_hir/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ impl DefKind {
}
}

/// 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> {
Expand Down
32 changes: 17 additions & 15 deletions src/librustc_typeck/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,38 +235,40 @@ 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(..) | DefKind::AssocTy, def_id) => {
tcx.generics_of(tcx.parent(def_id).unwrap())
}
Res::Def(_, def_id) => tcx.generics_of(def_id),
res => {
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;
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ This API is completely unstable and subject to change.
#![feature(crate_visibility_modifier)]
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![feature(or_patterns)]
#![feature(try_blocks)]
#![feature(never_type)]
#![feature(slice_partition_dedup)]
Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
Original file line number Diff line number Diff line change
@@ -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();
}
8 changes: 8 additions & 0 deletions src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 21 additions & 0 deletions src/test/ui/const-generics/type_of_anon_const.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 8 additions & 0 deletions src/test/ui/const-generics/type_of_anon_const.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 645fedd

Please sign in to comment.