Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4be7214

Browse files
committedDec 30, 2018
Type annotations in associated constant patterns.
This commit adds support for respecting user type annotations with associated constants in patterns.
1 parent b182a21 commit 4be7214

File tree

7 files changed

+86
-13
lines changed

7 files changed

+86
-13
lines changed
 

‎src/librustc_mir/hair/pattern/mod.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,28 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
848848
};
849849
match self.tcx.at(span).const_eval(self.param_env.and(cid)) {
850850
Ok(value) => {
851-
return self.const_to_pat(instance, value, id, span)
851+
let pattern = self.const_to_pat(instance, value, id, span);
852+
if !is_associated_const {
853+
return pattern;
854+
}
855+
856+
let user_provided_types = self.tables().user_provided_types();
857+
return if let Some(u_ty) = user_provided_types.get(id) {
858+
let user_ty = PatternTypeProjection::from_user_type(*u_ty);
859+
Pattern {
860+
span,
861+
kind: Box::new(
862+
PatternKind::AscribeUserType {
863+
subpattern: pattern,
864+
user_ty,
865+
user_ty_span: span,
866+
}
867+
),
868+
ty: value.ty,
869+
}
870+
} else {
871+
pattern
872+
}
852873
},
853874
Err(_) => {
854875
self.tcx.sess.span_err(
@@ -938,7 +959,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
938959
id: hir::HirId,
939960
span: Span,
940961
) -> Pattern<'tcx> {
941-
debug!("const_to_pat: cv={:#?}", cv);
962+
debug!("const_to_pat: cv={:#?} id={:?}", cv, id);
942963
let adt_subpattern = |i, variant_opt| {
943964
let field = Field::new(i);
944965
let val = const_field(
@@ -956,6 +977,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
956977
}
957978
}).collect::<Vec<_>>()
958979
};
980+
debug!("const_to_pat: cv.ty={:?} span={:?}", cv.ty, span);
959981
let kind = match cv.ty.sty {
960982
ty::Float(_) => {
961983
let id = self.tcx.hir().hir_to_node_id(id);

‎src/librustc_typeck/check/method/mod.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -357,16 +357,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
357357
})
358358
}
359359

360-
pub fn resolve_ufcs(&self,
361-
span: Span,
362-
method_name: ast::Ident,
363-
self_ty: Ty<'tcx>,
364-
expr_id: ast::NodeId)
365-
-> Result<Def, MethodError<'tcx>> {
366-
debug!("resolve_ufcs: method_name={:?} self_ty={:?} expr_id={:?}",
367-
method_name,
368-
self_ty,
369-
expr_id
360+
pub fn resolve_ufcs(
361+
&self,
362+
span: Span,
363+
method_name: ast::Ident,
364+
self_ty: Ty<'tcx>,
365+
expr_id: ast::NodeId
366+
) -> Result<Def, MethodError<'tcx>> {
367+
debug!(
368+
"resolve_ufcs: method_name={:?} self_ty={:?} expr_id={:?}",
369+
method_name, self_ty, expr_id,
370370
);
371371

372372
let tcx = self.tcx;
@@ -375,6 +375,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
375375
match self.probe_for_name(span, mode, method_name, IsSuggestion(false),
376376
self_ty, expr_id, ProbeScope::TraitsInScope) {
377377
Ok(pick) => {
378+
debug!("resolve_ufcs: pick={:?}", pick);
378379
if let Some(import_id) = pick.import_id {
379380
let import_def_id = tcx.hir().local_def_id(import_id);
380381
debug!("resolve_ufcs: used_trait_import: {:?}", import_def_id);
@@ -383,6 +384,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
383384
}
384385

385386
let def = pick.item.def();
387+
debug!("resolve_ufcs: def={:?}", def);
386388
tcx.check_stability(def.def_id(), Some(expr_id), span);
387389

388390
Ok(def)

‎src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4584,6 +4584,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
45844584
span: Span)
45854585
-> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
45864586
{
4587+
debug!("resolve_ty_and_def_ufcs: qpath={:?} node_id={:?} span={:?}", qpath, node_id, span);
45874588
let (ty, qself, item_segment) = match *qpath {
45884589
QPath::Resolved(ref opt_qself, ref path) => {
45894590
return (path.def,
@@ -5104,6 +5105,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
51045105
Def::Method(def_id) |
51055106
Def::AssociatedConst(def_id) => {
51065107
let container = tcx.associated_item(def_id).container;
5108+
debug!("instantiate_value_path: def={:?} container={:?}", def, container);
51075109
match container {
51085110
ty::TraitContainer(trait_did) => {
51095111
callee::check_legal_trait_for_method_call(tcx, span, trait_did)

‎src/test/run-pass/associated-consts/associated-const-range-match-patterns.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// run-pass
2-
#![allow(dead_code)]
2+
#![allow(dead_code, unreachable_patterns)]
33

44
struct Foo;
55

‎src/test/ui/issue-55511.nll.stderr

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0597]: `a` does not live long enough
2+
--> $DIR/issue-55511.rs:13:28
3+
|
4+
LL | let b = Some(Cell::new(&a));
5+
| ^^ borrowed value does not live long enough
6+
LL | match b {
7+
LL | <() as Foo<'static>>::C => { }
8+
| ----------------------- type annotation requires that `a` is borrowed for `'static`
9+
...
10+
LL | }
11+
| - `a` dropped here while still borrowed
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0597`.

‎src/test/ui/issue-55511.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use std::cell::Cell;
2+
3+
trait Foo<'a> {
4+
const C: Option<Cell<&'a u32>>;
5+
}
6+
7+
impl<'a, T> Foo<'a> for T {
8+
const C: Option<Cell<&'a u32>> = None;
9+
}
10+
11+
fn main() {
12+
let a = 22;
13+
let b = Some(Cell::new(&a));
14+
match b {
15+
<() as Foo<'static>>::C => { }
16+
_ => { }
17+
}
18+
}

‎src/test/ui/issue-55511.stderr

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0597]: `a` does not live long enough
2+
--> $DIR/issue-55511.rs:13:29
3+
|
4+
LL | let b = Some(Cell::new(&a));
5+
| ^ borrowed value does not live long enough
6+
...
7+
LL | }
8+
| - borrowed value only lives until here
9+
|
10+
= note: borrowed value must be valid for the static lifetime...
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0597`.

0 commit comments

Comments
 (0)
Please sign in to comment.