Skip to content

Commit e94959b

Browse files
committed
propagate user-type annotation for constants in expressions
1 parent ebdfda6 commit e94959b

7 files changed

+91
-13
lines changed

src/librustc_mir/hair/cx/expr.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -771,13 +771,11 @@ fn user_substs_applied_to_def(
771771
Def::Fn(_) |
772772
Def::Method(_) |
773773
Def::StructCtor(_, CtorKind::Fn) |
774-
Def::VariantCtor(_, CtorKind::Fn) =>
774+
Def::VariantCtor(_, CtorKind::Fn) |
775+
Def::Const(_) |
776+
Def::AssociatedConst(_) =>
775777
Some(UserTypeAnnotation::TypeOf(def.def_id(), cx.tables().user_substs(hir_id)?)),
776778

777-
Def::Const(_def_id) |
778-
Def::AssociatedConst(_def_id) =>
779-
bug!("unimplemented"),
780-
781779
// A unit struct/variant which is used as a value (e.g.,
782780
// `None`). This has the type of the enum/struct that defines
783781
// this variant -- but with the substitutions given by the
@@ -889,14 +887,17 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
889887
},
890888

891889
Def::Const(def_id) |
892-
Def::AssociatedConst(def_id) => ExprKind::Literal {
893-
literal: ty::Const::unevaluated(
894-
cx.tcx,
895-
def_id,
896-
substs,
897-
cx.tables().node_id_to_type(expr.hir_id),
898-
),
899-
user_ty: None, // FIXME(#47184) -- user given type annot on constants
890+
Def::AssociatedConst(def_id) => {
891+
let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
892+
ExprKind::Literal {
893+
literal: ty::Const::unevaluated(
894+
cx.tcx,
895+
def_id,
896+
substs,
897+
cx.tables().node_id_to_type(expr.hir_id),
898+
),
899+
user_ty,
900+
}
900901
},
901902

902903
Def::StructCtor(def_id, CtorKind::Const) |
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(nll)]
2+
3+
struct Foo<'a> { x: &'a u32 }
4+
5+
impl<'a> Foo<'a> {
6+
const C: &'a u32 = &22;
7+
}
8+
9+
fn foo<'a>(_: &'a u32) -> &'static u32 {
10+
<Foo<'a>>::C //~ ERROR
11+
}
12+
13+
fn main() {
14+
}
15+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: unsatisfied lifetime constraints
2+
--> $DIR/constant-in-expr-inherent-1.rs:10:5
3+
|
4+
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
5+
| -- lifetime `'a` defined here
6+
LL | <Foo<'a>>::C //~ ERROR
7+
| ^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
8+
9+
error: aborting due to previous error
10+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(nll)]
2+
3+
trait Foo<'a> {
4+
const C: &'a u32;
5+
}
6+
7+
impl<'a, T> Foo<'a> for T {
8+
const C: &'a u32 = &22;
9+
}
10+
11+
fn foo<'a>(_: &'a u32) -> &'static u32 {
12+
<() as Foo<'a>>::C //~ ERROR
13+
}
14+
15+
fn main() {
16+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: unsatisfied lifetime constraints
2+
--> $DIR/constant-in-expr-trait-item-1.rs:12:5
3+
|
4+
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
5+
| -- lifetime `'a` defined here
6+
LL | <() as Foo<'a>>::C //~ ERROR
7+
| ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
8+
9+
error: aborting due to previous error
10+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(nll)]
2+
3+
trait Foo<'a> {
4+
const C: &'a u32;
5+
}
6+
7+
impl<'a, T> Foo<'a> for T {
8+
const C: &'a u32 = &22;
9+
}
10+
11+
fn foo<'a, T: Foo<'a>>() -> &'static u32 {
12+
<T as Foo<'a>>::C //~ ERROR
13+
}
14+
15+
fn main() {
16+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: unsatisfied lifetime constraints
2+
--> $DIR/constant-in-expr-trait-item-2.rs:12:5
3+
|
4+
LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {
5+
| -- lifetime `'a` defined here
6+
LL | <T as Foo<'a>>::C //~ ERROR
7+
| ^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)