diff options
| author | David Wood <david@davidtw.co> | 2018-11-24 12:56:24 +0100 |
|---|---|---|
| committer | David Wood <david@davidtw.co> | 2018-12-30 14:30:58 +0100 |
| commit | 4be7214d30b121762c8675c3e732083da262b136 (patch) | |
| tree | 760abdaa2343eb58aab7b004ef8a2f305083d869 | |
| parent | b182a21163c673034a89acf01cd8797a8313ed11 (diff) | |
| download | rust-4be7214d30b121762c8675c3e732083da262b136.tar.gz rust-4be7214d30b121762c8675c3e732083da262b136.zip | |
Type annotations in associated constant patterns.
This commit adds support for respecting user type annotations with associated constants in patterns.
| -rw-r--r-- | src/librustc_mir/hair/pattern/mod.rs | 26 | ||||
| -rw-r--r-- | src/librustc_typeck/check/method/mod.rs | 22 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/associated-consts/associated-const-range-match-patterns.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/issue-55511.nll.stderr | 15 | ||||
| -rw-r--r-- | src/test/ui/issue-55511.rs | 18 | ||||
| -rw-r--r-- | src/test/ui/issue-55511.stderr | 14 |
7 files changed, 86 insertions, 13 deletions
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index fd3b07c0357..00de40d8cff 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -848,7 +848,28 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { }; match self.tcx.at(span).const_eval(self.param_env.and(cid)) { Ok(value) => { - return self.const_to_pat(instance, value, id, span) + let pattern = self.const_to_pat(instance, value, id, span); + if !is_associated_const { + return pattern; + } + + let user_provided_types = self.tables().user_provided_types(); + return if let Some(u_ty) = user_provided_types.get(id) { + let user_ty = PatternTypeProjection::from_user_type(*u_ty); + Pattern { + span, + kind: Box::new( + PatternKind::AscribeUserType { + subpattern: pattern, + user_ty, + user_ty_span: span, + } + ), + ty: value.ty, + } + } else { + pattern + } }, Err(_) => { self.tcx.sess.span_err( @@ -938,7 +959,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { id: hir::HirId, span: Span, ) -> Pattern<'tcx> { - debug!("const_to_pat: cv={:#?}", cv); + debug!("const_to_pat: cv={:#?} id={:?}", cv, id); let adt_subpattern = |i, variant_opt| { let field = Field::new(i); let val = const_field( @@ -956,6 +977,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } }).collect::<Vec<_>>() }; + debug!("const_to_pat: cv.ty={:?} span={:?}", cv.ty, span); let kind = match cv.ty.sty { ty::Float(_) => { let id = self.tcx.hir().hir_to_node_id(id); diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index fe5f43e3c01..1758f762524 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -357,16 +357,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }) } - pub fn resolve_ufcs(&self, - span: Span, - method_name: ast::Ident, - self_ty: Ty<'tcx>, - expr_id: ast::NodeId) - -> Result<Def, MethodError<'tcx>> { - debug!("resolve_ufcs: method_name={:?} self_ty={:?} expr_id={:?}", - method_name, - self_ty, - expr_id + pub fn resolve_ufcs( + &self, + span: Span, + method_name: ast::Ident, + self_ty: Ty<'tcx>, + expr_id: ast::NodeId + ) -> Result<Def, MethodError<'tcx>> { + debug!( + "resolve_ufcs: method_name={:?} self_ty={:?} expr_id={:?}", + method_name, self_ty, expr_id, ); let tcx = self.tcx; @@ -375,6 +375,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match self.probe_for_name(span, mode, method_name, IsSuggestion(false), self_ty, expr_id, ProbeScope::TraitsInScope) { Ok(pick) => { + debug!("resolve_ufcs: pick={:?}", pick); if let Some(import_id) = pick.import_id { let import_def_id = tcx.hir().local_def_id(import_id); debug!("resolve_ufcs: used_trait_import: {:?}", import_def_id); @@ -383,6 +384,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } let def = pick.item.def(); + debug!("resolve_ufcs: def={:?}", def); tcx.check_stability(def.def_id(), Some(expr_id), span); Ok(def) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index acb873206d5..ff4574eb283 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4584,6 +4584,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span) -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment]) { + debug!("resolve_ty_and_def_ufcs: qpath={:?} node_id={:?} span={:?}", qpath, node_id, span); let (ty, qself, item_segment) = match *qpath { QPath::Resolved(ref opt_qself, ref path) => { return (path.def, @@ -5104,6 +5105,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Def::Method(def_id) | Def::AssociatedConst(def_id) => { let container = tcx.associated_item(def_id).container; + debug!("instantiate_value_path: def={:?} container={:?}", def, container); match container { ty::TraitContainer(trait_did) => { callee::check_legal_trait_for_method_call(tcx, span, trait_did) diff --git a/src/test/run-pass/associated-consts/associated-const-range-match-patterns.rs b/src/test/run-pass/associated-consts/associated-const-range-match-patterns.rs index 647652d0273..4801369cfd1 100644 --- a/src/test/run-pass/associated-consts/associated-const-range-match-patterns.rs +++ b/src/test/run-pass/associated-consts/associated-const-range-match-patterns.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(dead_code)] +#![allow(dead_code, unreachable_patterns)] struct Foo; diff --git a/src/test/ui/issue-55511.nll.stderr b/src/test/ui/issue-55511.nll.stderr new file mode 100644 index 00000000000..97f8015dfc1 --- /dev/null +++ b/src/test/ui/issue-55511.nll.stderr @@ -0,0 +1,15 @@ +error[E0597]: `a` does not live long enough + --> $DIR/issue-55511.rs:13:28 + | +LL | let b = Some(Cell::new(&a)); + | ^^ borrowed value does not live long enough +LL | match b { +LL | <() as Foo<'static>>::C => { } + | ----------------------- type annotation requires that `a` is borrowed for `'static` +... +LL | } + | - `a` dropped here while still borrowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/issue-55511.rs b/src/test/ui/issue-55511.rs new file mode 100644 index 00000000000..93bd78c44d9 --- /dev/null +++ b/src/test/ui/issue-55511.rs @@ -0,0 +1,18 @@ +use std::cell::Cell; + +trait Foo<'a> { + const C: Option<Cell<&'a u32>>; +} + +impl<'a, T> Foo<'a> for T { + const C: Option<Cell<&'a u32>> = None; +} + +fn main() { + let a = 22; + let b = Some(Cell::new(&a)); + match b { + <() as Foo<'static>>::C => { } + _ => { } + } +} diff --git a/src/test/ui/issue-55511.stderr b/src/test/ui/issue-55511.stderr new file mode 100644 index 00000000000..24668f04551 --- /dev/null +++ b/src/test/ui/issue-55511.stderr @@ -0,0 +1,14 @@ +error[E0597]: `a` does not live long enough + --> $DIR/issue-55511.rs:13:29 + | +LL | let b = Some(Cell::new(&a)); + | ^ borrowed value does not live long enough +... +LL | } + | - borrowed value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. |
