Skip to content

Commit 4be7214

Browse files
committed
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

+24-2
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

+12-10
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

+2
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

+1-1
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

+15
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

+18
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

+14
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)