1
Fork 0

Rollup merge of #61409 - varkor:condition-trait-param-ice, r=oli-obk

Fix an ICE with a const argument in a trait

This goes some way towards fixing https://github.com/rust-lang/rust/issues/61383 (the reduced test case is fixed).
This commit is contained in:
Mazdak Farrokhzad 2019-06-04 04:48:08 +02:00 committed by GitHub
commit 1563514196
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 106 additions and 75 deletions

View file

@ -1335,20 +1335,31 @@ pub fn checked_type_of<'a, 'tcx>(
Node::Ty(&hir::Ty { node: hir::TyKind::Path(_), .. }) | Node::Ty(&hir::Ty { node: hir::TyKind::Path(_), .. }) |
Node::Expr(&hir::Expr { node: ExprKind::Struct(..), .. }) | Node::Expr(&hir::Expr { node: ExprKind::Struct(..), .. }) |
Node::Expr(&hir::Expr { node: ExprKind::Path(_), .. }) => { Node::Expr(&hir::Expr { node: ExprKind::Path(_), .. }) |
Node::TraitRef(..) => {
let path = match parent_node { let path = match parent_node {
Node::Ty(&hir::Ty { node: hir::TyKind::Path(ref path), .. }) | Node::Ty(&hir::Ty {
Node::Expr(&hir::Expr { node: ExprKind::Path(ref path), .. }) => { node: hir::TyKind::Path(QPath::Resolved(_, ref path)),
path ..
})
| Node::Expr(&hir::Expr {
node: ExprKind::Path(QPath::Resolved(_, ref path)),
..
}) => {
Some(&**path)
} }
Node::Expr(&hir::Expr { node: ExprKind::Struct(ref path, ..), .. }) => { Node::Expr(&hir::Expr { node: ExprKind::Struct(ref path, ..), .. }) => {
&*path if let QPath::Resolved(_, ref path) = **path {
Some(&**path)
} else {
None
} }
_ => unreachable!(), }
Node::TraitRef(&hir::TraitRef { ref path, .. }) => Some(path),
_ => None,
}; };
match path { if let Some(path) = path {
QPath::Resolved(_, ref path) => {
let arg_index = path.segments.iter() let arg_index = path.segments.iter()
.filter_map(|seg| seg.args.as_ref()) .filter_map(|seg| seg.args.as_ref())
.map(|generic_args| generic_args.args.as_ref()) .map(|generic_args| generic_args.args.as_ref())
@ -1372,19 +1383,18 @@ pub fn checked_type_of<'a, 'tcx>(
// figure out which generic parameter it corresponds to and return // figure out which generic parameter it corresponds to and return
// the relevant type. // the relevant type.
let generics = match path.res { let generics = match path.res {
Res::Def(DefKind::Ctor(..), def_id) => Res::Def(DefKind::Ctor(..), def_id) => {
tcx.generics_of(tcx.parent(def_id).unwrap()), tcx.generics_of(tcx.parent(def_id).unwrap())
Res::Def(_, def_id) => }
tcx.generics_of(def_id), Res::Def(_, def_id) => tcx.generics_of(def_id),
Res::Err => Res::Err => return Some(tcx.types.err),
return Some(tcx.types.err), _ if !fail => return None,
_ if !fail => res => {
return None,
x => {
tcx.sess.delay_span_bug( tcx.sess.delay_span_bug(
DUMMY_SP, DUMMY_SP,
&format!( &format!(
"unexpected const parent path def {:?}", x "unexpected const parent path def {:?}",
res,
), ),
); );
return Some(tcx.types.err); return Some(tcx.types.err);
@ -1404,19 +1414,18 @@ pub fn checked_type_of<'a, 'tcx>(
// This is no generic parameter associated with the arg. This is // This is no generic parameter associated with the arg. This is
// probably from an extra arg where one is not needed. // probably from an extra arg where one is not needed.
.unwrap_or(tcx.types.err) .unwrap_or(tcx.types.err)
} } else {
x => {
if !fail { if !fail {
return None; return None;
} }
tcx.sess.delay_span_bug( tcx.sess.delay_span_bug(
DUMMY_SP, DUMMY_SP,
&format!( &format!(
"unexpected const parent path {:?}", x "unexpected const parent path {:?}",
parent_node,
), ),
); );
tcx.types.err return Some(tcx.types.err);
}
} }
} }

View file

@ -5244,9 +5244,13 @@ impl<'a> Parser<'a> {
// FIXME(const_generics): to distinguish between idents for types and consts, // FIXME(const_generics): to distinguish between idents for types and consts,
// we should introduce a GenericArg::Ident in the AST and distinguish when // we should introduce a GenericArg::Ident in the AST and distinguish when
// lowering to the HIR. For now, idents for const args are not permitted. // lowering to the HIR. For now, idents for const args are not permitted.
if self.token.is_keyword(kw::True) || self.token.is_keyword(kw::False) {
self.parse_literal_maybe_minus()?
} else {
return Err( return Err(
self.fatal("identifiers may currently not be used for const generics") self.fatal("identifiers may currently not be used for const generics")
); );
}
} else { } else {
self.parse_literal_maybe_minus()? self.parse_literal_maybe_minus()?
}; };

View file

@ -0,0 +1,12 @@
// run-pass
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
trait IsZeroTrait<const IS_ZERO: bool>{}
impl IsZeroTrait<{0u8 == 0u8}> for () {}
impl IsZeroTrait<true> for ((),) {}
fn main() {}

View file

@ -0,0 +1,6 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/condition-in-trait-const-arg.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^