Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upimplement pattern-binding-modes RFC #44614
Conversation
rust-highfive
assigned
nikomatsakis
Sep 15, 2017
This comment has been minimized.
This comment has been minimized.
|
(rust_highfive has picked a reviewer for you, use r? to override) |
tbg
force-pushed the
tbg:pat_adjustments
branch
from
d8571a8
to
ded93d3
Sep 16, 2017
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis I updated the mem categorization code. Maybe I missed something, but your example borrowcks now (see |
tbg
force-pushed the
tbg:pat_adjustments
branch
2 times, most recently
from
30edb33
to
5c972f4
Sep 16, 2017
carols10cents
added
the
S-waiting-on-author
label
Sep 18, 2017
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@tschottdorf sorry for being slow. Start of the impl period has gotten me pretty slammed! |
This comment has been minimized.
This comment has been minimized.
|
No worries, if you're getting anything in before Friday that'll be enough
:-)
|
tbg
referenced this pull request
Sep 20, 2017
Closed
tracking issue for default binding modes in match (RFC 2005, match_default_bindings) #42640
nikomatsakis
requested changes
Sep 21, 2017
|
I left a few nits and suggestions. It seems like the major unknown is how to deal with the "patterns contain binding" test. I know that @arielb1 and I had some discussion about this at some point that I'd like to re-read. =) |
| @@ -1144,8 +1144,53 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { | |||
|
|
|||
| debug!("cat_pattern: {:?} cmt={:?}", pat, cmt); | |||
|
|
|||
| // FIXME(tschottdorf): I'm not clear on whether this should also see the adjusted `cmt`. | |||
| // I would assume so, but @nikomatsakis pointed me at just after this line to make the | |||
| // adjustments. | |||
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Sep 21, 2017
Contributor
I did point you to do the adjustment after, but I think I was wrong. I think we should move this callback to occur after. At first I thought we would do the callback both before and after each adjustment, but since we supply both the pattern and the cmt, I think it's better to just do a callback after the adjustments. We are therefore giving (a) the pattern that is being used and (b) the cmt that is being matched by this pattern. Looking at the use-sites of this function, all of them expect this and will work properly.
This comment has been minimized.
This comment has been minimized.
tbg
Sep 21, 2017
Author
Contributor
Ok, will give that a try. Do you have an example or another way of testing that would break the current code and works with the callback invoked at the right place?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Sep 26, 2017
Contributor
I cannot find a way that it makes any difference -- all the consumers of this except for an obscure one in clippy only care about binding patterns, and those are never adjusted. However, it still seems more correct. Right now, we are passing in the bare pattern paired with the cmt that corresponds to (logically) the adjusted pattern. This is also coherent but it seems a bit .. less expected. i.e., if I match on the pattern and get (e.g.) PatTuple, I would expect the cmt to have tuple type (but in this code, it may have reference type).
This comment has been minimized.
This comment has been minimized.
tbg
Sep 28, 2017
Author
Contributor
I just want to double check your comment above because the code that you commented on gives the cmt for the bare pattern and the bare pattern, whereas moving the callback gives the adjusted cmt and (still) the bare pattern. Your wording makes it sound like you'd actually prefer option 1, which is the current code (right?).
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Sep 28, 2017
Contributor
So, what I meant is this:
- Consider first
match &Some(3) { &Some(ref x) =>.- When
cat_patternis first invoked, we have the cmt C for the discriminant (&Some(3)) and the pattern&Some(ref x), and we invoke the callback with that - We then process the pattern, yielding the CMT for
*&Some(3)and the patternSome(ref x), and we invoke the callback with that. - Finally, we process the CMT one step further to
Downcast<Some>(*&Some(3)).0and invoke callback with with the patternref x.
- When
- Under the code as it is there now:
- When
cat_patternis first invoked, we still have the same cmt C for the discriminant (&Some(3)), but the pattern is forSome(x). We invoke the callback with that. - Then we adjust the CMT to
*&Some(3). No callback occurs after this. - Then we process the pattern, downcasting to
Downcast<Some>(*&Some(3)).0, and invoke callback with patternx, where the ref is implied.
- When
These don't quite match -- there aren't the same number of callbacks, to start, but also the cmt and patterns don't match up. If we move the callback to after the adjustment, we will get:
- Under the code as proposed:
- When
cat_patternis first invoked, we still have the same cmt C for the discriminant (&Some(3)), but the pattern is forSome(x). - Then we adjust the CMT to
*&Some(3). - Now we callback with CMT
*&Some(3)and patternSome(x), just as before. - Then we process the pattern, downcasting to
Downcast<Some>(*&Some(3)).0, and invoke callback with patternx, where the ref is implied.
- When
This comment has been minimized.
This comment has been minimized.
| ) | ||
| } | ||
|
|
||
| pub fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> { |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| } | ||
|
|
||
| /// The `is_arg` argument indicates whether this pattern is the | ||
| /// *outermost* pattern in an argument (e.g., in `fn foo(&x: | ||
| /// &u32)`, it is true for the `&x` pattern but not `x`). This is | ||
| /// used to tailor error reporting. | ||
| pub fn check_pat_arg(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>, is_arg: bool) { | ||
| pub fn check_pat_arg(&self, pat: &'gcx hir::Pat, mut expected: Ty<'tcx>, | ||
| mut def_bm: ty::BindingMode, is_arg: bool) { |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| PatKind::TupleStruct(..) | | ||
| PatKind::Tuple(..) | | ||
| PatKind::Box(_) | | ||
| // PatKind::Lit(_) | // FIXME(tschottdorf): causes lots of errors |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
tbg
Sep 21, 2017
Author
Contributor
Among possibly other things, we treat string literals incorrectly.
match s {
"inf" => T::INFINITY,
"NaN" => T::NAN,
_ => { return Err(pfe_invalid()); }
}
Compiling core v0.0.0 (file:///Users/tschottdorf/rust/binding-modes/src/libcore)
error[E0308]: mismatched types
--> src/libcore/num/dec2flt/mod.rs:219:13
|
219 | "inf" => T::INFINITY,
| ^^^^^ expected str, found reference
|
= note: expected type `str`
found type `&'static str`
error[E0308]: mismatched types
--> src/libcore/num/dec2flt/mod.rs:220:13
|
220 | "NaN" => T::NAN,
| ^^^^^ expected str, found reference
|
= note: expected type `str`
found type `&'static str`
error[E0308]: mismatched types
--> src/libcore/str/mod.rs:130:13
|
130 | "true" => Ok(true),
| ^^^^^^ expected str, found reference
|
= note: expected type `str`
found type `&'static str`
error[E0308]: mismatched types
--> src/libcore/str/mod.rs:131:13
|
131 | "false" => Ok(false),
| ^^^^^^^ expected str, found reference
|
= note: expected type `str`
found type `&'static str`
error: aborting due to 4 previous errors
error: Could not compile `core`.
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Sep 21, 2017
Contributor
Yeah it seems like string and byte literals (and maybe slices?) are the other places this would go wrong. But I guess more generally one can have a constant with references in it (e.g., const X: &'static u32 = &22 -- I forget if you can use such a constant in a match though.
This comment has been minimized.
This comment has been minimized.
tbg
Sep 24, 2017
Author
Contributor
I added a computation of the type and make the true/false depend on whether there's a TyRef. May not be the right thing to do, but at least it works somewhat.
| PatKind::Slice(..) => true, | ||
| PatKind::Path(ref qpath) => { | ||
| // FIXME(tschottdorf): is it OK to call this here? | ||
| let (def, _, _) = self.resolve_ty_and_def_ufcs(qpath, pat.id, pat.span); |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Sep 21, 2017
Contributor
Hmm. It's not great to call this here, in that it can report an error, which might then get reported again later on (by check_pat_path). Not sure how best to fix this though!
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Sep 21, 2017
Contributor
Hmm, we might be able to just modify resolve_ty_and_def_ufcs to cache the result. It already writes the final result into a table:
// Write back the new resolution.
let hir_id = self.tcx.hir.node_to_hir_id(node_id);
self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);seems like we can check that cache in the case that we get TypeRelative.
(cc @eddyb -- this seem ok to you?)
| @@ -0,0 +1,38 @@ | |||
| // Copyright 2017 The Rust Project Developers. See the COPYRIGHT | |||
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Sep 21, 2017
Contributor
So I've been advocating for us to organize the tests for new language features like this by putting them into a directory. So can we move this to ths directory:
src/test/compile-fail/rfc-XXX-default-binding-mode/
The idea is that we should be able to browse this directory (as well as corresponding directories in src/test/run-pass and src/test/ui) to get a good idea of how the feature behaves.
This comment has been minimized.
This comment has been minimized.
| @@ -0,0 +1,49 @@ | |||
| // Copyright 2017 The Rust Project Developers. See the COPYRIGHT | |||
| // file at the top-level directory of this distribution and at | |||
| // http://rust-lang.org/COPYRIGHT. | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| // | ||
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
| // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
| // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
| // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
| // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
| // option. This file may not be copied, modified, or distributed |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
| // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
| // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
| // option. This file may not be copied, modified, or distributed |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@tschottdorf
Was there some particular test that caught your eye? Most of them actually looked like improvements to me. |
tbg
reviewed
Sep 21, 2017
|
Thanks for the review @nikomatsakis! Haven't changed anything (will do tomorrow), just posted a few responses to comments to get you unstuck. |
| @@ -1144,8 +1144,53 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { | |||
|
|
|||
| debug!("cat_pattern: {:?} cmt={:?}", pat, cmt); | |||
|
|
|||
| // FIXME(tschottdorf): I'm not clear on whether this should also see the adjusted `cmt`. | |||
| // I would assume so, but @nikomatsakis pointed me at just after this line to make the | |||
| // adjustments. | |||
This comment has been minimized.
This comment has been minimized.
tbg
Sep 21, 2017
Author
Contributor
Ok, will give that a try. Do you have an example or another way of testing that would break the current code and works with the callback invoked at the right place?
| // FIXME(tschottdorf): don't call contains_explicit_ref_binding, which | ||
| // is problematic as the HIR is being scraped, but ref bindings may be | ||
| // implicit after #42640. We need to make sure that pat_adjustments | ||
| // (once introduced) is populated by the time we get here. |
This comment has been minimized.
This comment has been minimized.
| PatKind::TupleStruct(..) | | ||
| PatKind::Tuple(..) | | ||
| PatKind::Box(_) | | ||
| // PatKind::Lit(_) | // FIXME(tschottdorf): causes lots of errors |
This comment has been minimized.
This comment has been minimized.
tbg
Sep 21, 2017
Author
Contributor
Among possibly other things, we treat string literals incorrectly.
match s {
"inf" => T::INFINITY,
"NaN" => T::NAN,
_ => { return Err(pfe_invalid()); }
}
Compiling core v0.0.0 (file:///Users/tschottdorf/rust/binding-modes/src/libcore)
error[E0308]: mismatched types
--> src/libcore/num/dec2flt/mod.rs:219:13
|
219 | "inf" => T::INFINITY,
| ^^^^^ expected str, found reference
|
= note: expected type `str`
found type `&'static str`
error[E0308]: mismatched types
--> src/libcore/num/dec2flt/mod.rs:220:13
|
220 | "NaN" => T::NAN,
| ^^^^^ expected str, found reference
|
= note: expected type `str`
found type `&'static str`
error[E0308]: mismatched types
--> src/libcore/str/mod.rs:130:13
|
130 | "true" => Ok(true),
| ^^^^^^ expected str, found reference
|
= note: expected type `str`
found type `&'static str`
error[E0308]: mismatched types
--> src/libcore/str/mod.rs:131:13
|
131 | "false" => Ok(false),
| ^^^^^^^ expected str, found reference
|
= note: expected type `str`
found type `&'static str`
error: aborting due to 4 previous errors
error: Could not compile `core`.
tbg
force-pushed the
tbg:pat_adjustments
branch
from
5c972f4
to
7ad162e
Sep 22, 2017
This comment has been minimized.
This comment has been minimized.
|
OK, so, I was thinking some more about the problem of how to replace the code that scans (syntactically) for Let's focus on the case of a
What makes this complicated is that we sometimes need to coerce the result of evaluating
this is generally equivalent to So what we do TODAY is to say this, effectively:
However, in the new system, we now have to account for the possibility that there will be "type-based" ref-bindings in the pattern P that are not syntactically evident. However, we know that if such ref-bindings exist, they occur "beneath" a I think this means we don't have to worry about the big danger that we were afraid of. In particular, no coercion ever modifies the referent of a reference -- we don't know where that memory lives, and we don't know that we have the freedom to change it. In other words, if we coerce the result of E, it will only affect the owned content of that result, not its borrowed content -- and for their to be borrows of the owned content, they must be done with a (There is one exception of sorts: we do permit The other cases where we use this check, I think, can never perform coercion, and so are not as problematic. They only have to worry about subtyping, and in that case the same logic above applies -- we will only ever take a
|
This comment has been minimized.
This comment has been minimized.
|
Now that I'm reading this again: If we just wanted to be consistent with that, then the #23116 example: #![allow(dead_code)]
use std::fmt::Debug;
struct S(Box<Debug + 'static>);
impl S {
fn bar<'a>(&'a mut self)->&'a mut Box<Debug + 'a> {
match self.0 { ref mut x => x } // should not compile, but does
}
}
fn main() {}Would perform a lexpr->vexpr->lexpr conversion, and therefore a temporary, creating MIR as follows:
Which would of course cause a "borrow does not live long enough" when it catches you trying to return a borrow of the local Obviously, creating such coercion temporaries by default will annoy anyone who tries to use However, if all the An asideThe above description is not actually implementation-coherent with typeck - to satisfy closure inference, match bindings can't use subtyping, so rustc actually sometimes performs subtyping on immutable lexprs - see this comment: rust/src/librustc_typeck/check/_match.rs Lines 331 to 379 in dcb4378 Note that typeck's strategy is imperfect and leads to spurious errors in some situations fn foo<'x>(mut x: (&'x isize, ())) {
let a = 1;
let (mut _z, ref _y) = x;
_z = &a; //~ ERROR no subtyping for you!
}
fn main() {}We'll also have to solve the closure inference wonkyness when we get to MIR-based regionck, but hopefully the MIR-based regionck won't have wonky anyway. |
This comment has been minimized.
This comment has been minimized.
|
While this argument works today, it will put us in a somewhat sticky situation when we get struct Newtype<T>(T);
impl<T> Deref for Newtype<T> {
type Target = T;
fn deref(&self) -> &T { &self.0 }
}
impl<T> DerefMut for Newtype<T> {
fn deref_mut(&mut self) -> &mut T { &mut self.0 }
}
unsafe impl<T> DerefPure for Newtype<T> { /* ... */ }
fn main() {
let n = Newtype(("hello",));
{
let s = "hi there".to_string();
let (mut d,) = n;
*d = &s; // create a temporary? fail? both options are unsatisfying
}
} |
nikomatsakis
referenced this pull request
Sep 25, 2017
Closed
Resolve how to handle coercions and the like under default binding modes #44848
This comment has been minimized.
This comment has been minimized.
|
My take is that we can land this without fully resolving the "coercion chicken" question. I've filed #44848 to track that. |
nikomatsakis
approved these changes
Sep 25, 2017
This comment has been minimized.
This comment has been minimized.
|
|
xfix
reviewed
Sep 26, 2017
| match &&&&i { | ||
| 1 ... 3 => panic!(), | ||
| 3 ... 8 => {}, | ||
| _ => {}, |
This comment has been minimized.
This comment has been minimized.
xfix
Sep 26, 2017
•
Contributor
Shouldn't default variant panic too, considering it's unexpected result value?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@tschottdorf I wrote up a list of test cases here. Can you just check that you have tests covering those cases? |
tbg
force-pushed the
tbg:pat_adjustments
branch
from
346bd34
to
85cf6ed
Sep 28, 2017
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis confirmed, though one of your test cases doesn't compile (out of scope of this PR, see #42640 (comment)). I added a compile-fail test that documents this but you probably want to file an issue unless there's already one. Could you review the FIXMEs (just search for |
nikomatsakis
reviewed
Sep 28, 2017
| /// FIXME(tschottdorf): this is problematic as the HIR is being scraped, | ||
| /// but ref bindings may be implicit after #42640. | ||
| /// FIXME(tschottdorf): this is problematic as the HIR is being scraped, but | ||
| /// ref bindings may be implicit after #42640 (default match binding modes). |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
nikomatsakis
reviewed
Sep 28, 2017
| @@ -188,7 +188,7 @@ impl hir::Arm { | |||
| /// bindings, and if yes whether its containing mutable ones or just immutables ones. | |||
| pub fn contains_explicit_ref_binding(&self) -> Option<hir::Mutability> { | |||
| // FIXME(tschottdorf): contains_explicit_ref_binding() must be removed | |||
| // for #42640. | |||
| // for #42640 (default match binding modes). | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
nikomatsakis
reviewed
Sep 28, 2017
| @@ -1144,8 +1144,53 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { | |||
|
|
|||
| debug!("cat_pattern: {:?} cmt={:?}", pat, cmt); | |||
|
|
|||
| // FIXME(tschottdorf): I'm not clear on whether this should also see the adjusted `cmt`. | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
nikomatsakis
reviewed
Sep 28, 2017
| .get(pat.hir_id) | ||
| .map(|v| v.len()) | ||
| .unwrap_or(0) { | ||
| // FIXME(tschottdorf): is implicit==true correct? |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Sep 28, 2017
Contributor
It is correct. If you make it false, I think it would affect how the error in this example is printed.
This comment has been minimized.
This comment has been minimized.
nikomatsakis
reviewed
Sep 28, 2017
| // Ditto with byte strings. | ||
| fn with_bytes() { | ||
| let s: &'static [u8] = b"abc"; | ||
| let result = match s { |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
tbg
Sep 29, 2017
Author
Contributor
Yeah, this gives an error. What would you like me to do? Move to ui tests & file an issue? Try to fix?
let s: &'static str = "abc";
match &s {
"abc" => true,
_ => panic!(),
};
nikomatsakis
reviewed
Sep 28, 2017
| // option. This file may not be copied, modified, or distributed | ||
| // except according to those terms. | ||
|
|
||
| // FIXME(tschottdorf): what other noteworthy literals are there? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
tbg
Sep 29, 2017
Author
Contributor
Like this?
#[derive(PartialEq, Eq)]
struct Foo {
bar: i32,
}
const FOO: Foo = Foo{bar: 5};
fn main() {
let f = Foo{bar:6};
match &f {
FOO => {},
_ => panic!(),
}
}Doesn't compile (but should), added to ui tests for now.
This comment has been minimized.
This comment has been minimized.
|
@tschottdorf
Done |
tbg
referenced this pull request
Sep 29, 2017
Open
Make or (|) patterns work with match default binding modes #44912
tbg
reviewed
Sep 29, 2017
|
Thanks! Mostly done except for avoiding double type errors. Plus there may be some non-compiling tests that you'll want to advise me on/open follow-up issues for (all have comments in this review). |
| /// FIXME(tschottdorf): this is problematic as the HIR is being scraped, | ||
| /// but ref bindings may be implicit after #42640. | ||
| /// FIXME(tschottdorf): this is problematic as the HIR is being scraped, but | ||
| /// ref bindings may be implicit after #42640 (default match binding modes). |
This comment has been minimized.
This comment has been minimized.
| @@ -188,7 +188,7 @@ impl hir::Arm { | |||
| /// bindings, and if yes whether its containing mutable ones or just immutables ones. | |||
| pub fn contains_explicit_ref_binding(&self) -> Option<hir::Mutability> { | |||
| // FIXME(tschottdorf): contains_explicit_ref_binding() must be removed | |||
| // for #42640. | |||
| // for #42640 (default match binding modes). | |||
This comment has been minimized.
This comment has been minimized.
| @@ -1144,8 +1144,53 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { | |||
|
|
|||
| debug!("cat_pattern: {:?} cmt={:?}", pat, cmt); | |||
|
|
|||
| // FIXME(tschottdorf): I'm not clear on whether this should also see the adjusted `cmt`. | |||
This comment has been minimized.
This comment has been minimized.
| @@ -1144,8 +1144,53 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { | |||
|
|
|||
| debug!("cat_pattern: {:?} cmt={:?}", pat, cmt); | |||
|
|
|||
| // FIXME(tschottdorf): I'm not clear on whether this should also see the adjusted `cmt`. | |||
| // I would assume so, but @nikomatsakis pointed me at just after this line to make the | |||
| // adjustments. | |||
This comment has been minimized.
This comment has been minimized.
| .get(pat.hir_id) | ||
| .map(|v| v.len()) | ||
| .unwrap_or(0) { | ||
| // FIXME(tschottdorf): is implicit==true correct? |
This comment has been minimized.
This comment has been minimized.
| let _: &i32 = match x { | ||
| // Here, each of the patterns are treated independently | ||
| // | ||
| // FIXME(tschottdorf): make this compile without the actual `|`. |
This comment has been minimized.
This comment has been minimized.
| // option. This file may not be copied, modified, or distributed | ||
| // except according to those terms. | ||
|
|
||
| // FIXME(tschottdorf): what other noteworthy literals are there? |
This comment has been minimized.
This comment has been minimized.
tbg
Sep 29, 2017
Author
Contributor
Like this?
#[derive(PartialEq, Eq)]
struct Foo {
bar: i32,
}
const FOO: Foo = Foo{bar: 5};
fn main() {
let f = Foo{bar:6};
match &f {
FOO => {},
_ => panic!(),
}
}Doesn't compile (but should), added to ui tests for now.
| // Ditto with byte strings. | ||
| fn with_bytes() { | ||
| let s: &'static [u8] = b"abc"; | ||
| let result = match s { |
This comment has been minimized.
This comment has been minimized.
tbg
Sep 29, 2017
Author
Contributor
Yeah, this gives an error. What would you like me to do? Move to ui tests & file an issue? Try to fix?
let s: &'static str = "abc";
match &s {
"abc" => true,
_ => panic!(),
};| } | ||
| } | ||
| PatKind::Path(ref qpath) => { | ||
| // FIXME(tschottdorf): is it OK to call this here? |
This comment has been minimized.
This comment has been minimized.
| PatKind::Range(..) | | ||
| PatKind::Slice(..) => true, | ||
| PatKind::Lit(ref lt) => { | ||
| // FIXME(tschottdorf): is it OK to call this here? |
This comment has been minimized.
This comment has been minimized.
tbg
force-pushed the
tbg:pat_adjustments
branch
2 times, most recently
from
6e5d235
to
185a738
Sep 29, 2017
This comment has been minimized.
This comment has been minimized.
|
Added a feature gate and docs in the unstable book. Mod bikeshedding on the feature gate name and avoiding doubly reporting errors I think I'm done here. Anything else missing? |
tbg
force-pushed the
tbg:pat_adjustments
branch
2 times, most recently
from
af06651
to
bc651af
Sep 29, 2017
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis, re #44614 (comment): what's an example that would return an error twice? I'll need that to test that I fixed something, and wasn't able to put one together myself. I did add caching in |
This comment has been minimized.
This comment has been minimized.
|
Re: #44614 (comment) (same problem for |
This comment has been minimized.
This comment has been minimized.
|
Regarding the double errors: This is an example of a test-case that gives double errors without your fix, but no longer does. fn main() {
let foo = 22;
match foo {
u32::XXX => { }
_ => { }
}
} |
This comment has been minimized.
This comment has been minimized.
|
@tschottdorf
I imagine something like this, yes. Basically a pre-pass over all the patterns that finds literals and type-checks them -- this would probably happen when let ty = self.check_expr(<);but rather let ty = self.node_ty(lt.hir_id);which will read out the (previously computed) type . In other words, you don't need to add a new map, we already have the tables. In terms of a test that would go awry... hmm... that may be a bit harder. =) I am trying to think if it's possible to get an error while type-checking a literal! Maybe it's not. |
tbg
force-pushed the
tbg:pat_adjustments
branch
from
364c62a
to
78c4a9a
Oct 6, 2017
This comment has been minimized.
This comment has been minimized.
|
Squashed and ready for more review and merge. @nikomatsakis double-error worked fine. As for the literals, I realized I didn't have to add an extra walk -- we were always calling |
tbg
force-pushed the
tbg:pat_adjustments
branch
from
78c4a9a
to
de55b4f
Oct 6, 2017
nikomatsakis
approved these changes
Oct 6, 2017
This comment has been minimized.
This comment has been minimized.
|
@bors r+ |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Oct 7, 2017
This comment has been minimized.
This comment has been minimized.
|
|
bors
merged commit de55b4f
into
rust-lang:master
Oct 7, 2017
This was referenced Oct 7, 2017
carols10cents
referenced this pull request
Jan 12, 2018
Closed
Looks like the unstable book on doc.rust-lang.org isn't being rebuilt? #47394
csmoe
reviewed
Jun 1, 2018
| --> $DIR/explicit-mut.rs:19:13 | ||
| | | ||
| 18 | Some(n) => { | ||
| | - consider changing this to `n` |
tbg commentedSep 15, 2017
•
edited
See the RFC and tracking issue #42640