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

Browse files
committedOct 8, 2019
Auto merge of #65196 - Centril:rollup-q06lcxm, r=Centril
Rollup of 8 pull requests Successful merges: - #64726 (rewrite documentation for unimplemented! to clarify use) - #65040 (syntax: more cleanups in item and function signature parsing) - #65046 (Make `Cell::new` method come first in documentation) - #65098 (Add long error explanation for E0561) - #65150 (Suggest dereferencing boolean reference when used in 'if' or 'while') - #65154 (Fix const generic arguments not displaying in types mismatch diagnostic) - #65181 (fix bug in folding for constants) - #65187 (use 'invalid argument' for vxWorks) Failed merges: - #65179 (Add long error explanation for E0567) r? @ghost
2 parents d304f5c + bc7df81 commit 1e1f25e

File tree

24 files changed

+469
-309
lines changed

24 files changed

+469
-309
lines changed
 

‎src/libcore/cell.rs

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -229,52 +229,6 @@ pub struct Cell<T: ?Sized> {
229229
value: UnsafeCell<T>,
230230
}
231231

232-
impl<T:Copy> Cell<T> {
233-
/// Returns a copy of the contained value.
234-
///
235-
/// # Examples
236-
///
237-
/// ```
238-
/// use std::cell::Cell;
239-
///
240-
/// let c = Cell::new(5);
241-
///
242-
/// let five = c.get();
243-
/// ```
244-
#[inline]
245-
#[stable(feature = "rust1", since = "1.0.0")]
246-
pub fn get(&self) -> T {
247-
unsafe{ *self.value.get() }
248-
}
249-
250-
/// Updates the contained value using a function and returns the new value.
251-
///
252-
/// # Examples
253-
///
254-
/// ```
255-
/// #![feature(cell_update)]
256-
///
257-
/// use std::cell::Cell;
258-
///
259-
/// let c = Cell::new(5);
260-
/// let new = c.update(|x| x + 1);
261-
///
262-
/// assert_eq!(new, 6);
263-
/// assert_eq!(c.get(), 6);
264-
/// ```
265-
#[inline]
266-
#[unstable(feature = "cell_update", issue = "50186")]
267-
pub fn update<F>(&self, f: F) -> T
268-
where
269-
F: FnOnce(T) -> T,
270-
{
271-
let old = self.get();
272-
let new = f(old);
273-
self.set(new);
274-
new
275-
}
276-
}
277-
278232
#[stable(feature = "rust1", since = "1.0.0")]
279233
unsafe impl<T: ?Sized> Send for Cell<T> where T: Send {}
280234

@@ -448,6 +402,52 @@ impl<T> Cell<T> {
448402
}
449403
}
450404

405+
impl<T:Copy> Cell<T> {
406+
/// Returns a copy of the contained value.
407+
///
408+
/// # Examples
409+
///
410+
/// ```
411+
/// use std::cell::Cell;
412+
///
413+
/// let c = Cell::new(5);
414+
///
415+
/// let five = c.get();
416+
/// ```
417+
#[inline]
418+
#[stable(feature = "rust1", since = "1.0.0")]
419+
pub fn get(&self) -> T {
420+
unsafe{ *self.value.get() }
421+
}
422+
423+
/// Updates the contained value using a function and returns the new value.
424+
///
425+
/// # Examples
426+
///
427+
/// ```
428+
/// #![feature(cell_update)]
429+
///
430+
/// use std::cell::Cell;
431+
///
432+
/// let c = Cell::new(5);
433+
/// let new = c.update(|x| x + 1);
434+
///
435+
/// assert_eq!(new, 6);
436+
/// assert_eq!(c.get(), 6);
437+
/// ```
438+
#[inline]
439+
#[unstable(feature = "cell_update", issue = "50186")]
440+
pub fn update<F>(&self, f: F) -> T
441+
where
442+
F: FnOnce(T) -> T,
443+
{
444+
let old = self.get();
445+
let new = f(old);
446+
self.set(new);
447+
new
448+
}
449+
}
450+
451451
impl<T: ?Sized> Cell<T> {
452452
/// Returns a raw pointer to the underlying data in this cell.
453453
///

‎src/libcore/macros.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -520,57 +520,74 @@ macro_rules! unreachable {
520520
});
521521
}
522522

523-
/// Indicates unfinished code.
523+
/// Indicates unfinished code by panicking with a message of "not yet implemented".
524524
///
525-
/// This can be useful if you are prototyping and are just looking to have your
526-
/// code type-check, or if you're implementing a trait that requires multiple
527-
/// methods, and you're only planning on using one of them.
525+
/// This allows the your code to type-check, which is useful if you are prototyping or
526+
/// implementing a trait that requires multiple methods which you don't plan of using all of.
528527
///
529528
/// There is no difference between `unimplemented!` and `todo!` apart from the
530529
/// name.
531530
///
532531
/// # Panics
533532
///
534-
/// This will always [panic!](macro.panic.html)
533+
/// This will always [panic!](macro.panic.html) because `unimplemented!` is just a
534+
/// shorthand for `panic!` with a fixed, specific message.
535+
///
536+
/// Like `panic!`, this macro has a second form for displaying custom values.
535537
///
536538
/// # Examples
537539
///
538540
/// Here's an example of some in-progress code. We have a trait `Foo`:
539541
///
540542
/// ```
541543
/// trait Foo {
542-
/// fn bar(&self);
544+
/// fn bar(&self) -> u8;
543545
/// fn baz(&self);
546+
/// fn qux(&self) -> Result<u64, ()>;
544547
/// }
545548
/// ```
546549
///
547-
/// We want to implement `Foo` on one of our types, but we also want to work on
548-
/// just `bar()` first. In order for our code to compile, we need to implement
549-
/// `baz()`, so we can use `unimplemented!`:
550+
/// We want to implement `Foo` for 'MyStruct', but so far we only know how to
551+
/// implement the `bar()` function. `baz()` and `qux()` will still need to be defined
552+
/// in our implementation of `Foo`, but we can use `unimplemented!` in their definitions
553+
/// to allow our code to compile.
554+
///
555+
/// In the meantime, we want to have our program stop running once these
556+
/// unimplemented functions are reached.
550557
///
551558
/// ```
552559
/// # trait Foo {
553-
/// # fn bar(&self);
560+
/// # fn bar(&self) -> u8;
554561
/// # fn baz(&self);
562+
/// # fn qux(&self) -> Result<u64, ()>;
555563
/// # }
556564
/// struct MyStruct;
557565
///
558566
/// impl Foo for MyStruct {
559-
/// fn bar(&self) {
560-
/// // implementation goes here
567+
/// fn bar(&self) -> u8 {
568+
/// 1 + 1
561569
/// }
562570
///
563571
/// fn baz(&self) {
564-
/// // let's not worry about implementing baz() for now
572+
/// // We aren't sure how to even start writing baz yet,
573+
/// // so we have no logic here at all.
574+
/// // This will display "thread 'main' panicked at 'not yet implemented'".
565575
/// unimplemented!();
566576
/// }
577+
///
578+
/// fn qux(&self) -> Result<u64, ()> {
579+
/// let n = self.bar();
580+
/// // We have some logic here,
581+
/// // so we can use unimplemented! to display what we have so far.
582+
/// // This will display:
583+
/// // "thread 'main' panicked at 'not yet implemented: we need to divide by 2'".
584+
/// unimplemented!("we need to divide by {}", n);
585+
/// }
567586
/// }
568587
///
569588
/// fn main() {
570589
/// let s = MyStruct;
571590
/// s.bar();
572-
///
573-
/// // we aren't even using baz() yet, so this is fine.
574591
/// }
575592
/// ```
576593
#[macro_export]

‎src/librustc/infer/error_reporting/mod.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
935935
.filter(|(a, b)| a == b)
936936
.count();
937937
let len = sub1.len() - common_default_params;
938+
let consts_offset = len - sub1.consts().count();
938939

939940
// Only draw `<...>` if there're lifetime/type arguments.
940941
if len > 0 {
@@ -981,7 +982,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
981982
// ^ elided type as this type argument was the same in both sides
982983
let type_arguments = sub1.types().zip(sub2.types());
983984
let regions_len = sub1.regions().count();
984-
for (i, (ta1, ta2)) in type_arguments.take(len).enumerate() {
985+
let num_display_types = consts_offset - regions_len;
986+
for (i, (ta1, ta2)) in type_arguments.take(num_display_types).enumerate() {
985987
let i = i + regions_len;
986988
if ta1 == ta2 {
987989
values.0.push_normal("_");
@@ -994,6 +996,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
994996
self.push_comma(&mut values.0, &mut values.1, len, i);
995997
}
996998

999+
// Do the same for const arguments, if they are equal, do not highlight and
1000+
// elide them from the output.
1001+
let const_arguments = sub1.consts().zip(sub2.consts());
1002+
for (i, (ca1, ca2)) in const_arguments.enumerate() {
1003+
let i = i + consts_offset;
1004+
if ca1 == ca2 {
1005+
values.0.push_normal("_");
1006+
values.1.push_normal("_");
1007+
} else {
1008+
values.0.push_highlighted(ca1.to_string());
1009+
values.1.push_highlighted(ca2.to_string());
1010+
}
1011+
self.push_comma(&mut values.0, &mut values.1, len, i);
1012+
}
1013+
9971014
// Close the type argument bracket.
9981015
// Only draw `<...>` if there're lifetime/type arguments.
9991016
if len > 0 {

‎src/librustc/ty/flags.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,9 @@ impl FlagComputation {
250250
ConstValue::Placeholder(_) => {
251251
self.add_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_CT_PLACEHOLDER);
252252
}
253-
_ => {},
253+
ConstValue::Scalar(_) => { }
254+
ConstValue::Slice { data: _, start: _, end: _ } => { }
255+
ConstValue::ByRef { alloc: _, offset: _ } => { }
254256
}
255257
}
256258

‎src/librustc/ty/fold.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -911,13 +911,15 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
911911
}
912912

913913
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> bool {
914-
if let ty::Const {
915-
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, _)),
916-
..
917-
} = *ct {
918-
debruijn >= self.outer_index
919-
} else {
920-
false
914+
// we don't have a `visit_infer_const` callback, so we have to
915+
// hook in here to catch this case (annoying...), but
916+
// otherwise we do want to remember to visit the rest of the
917+
// const, as it has types/regions embedded in a lot of other
918+
// places.
919+
match ct.val {
920+
ConstValue::Infer(ty::InferConst::Canonical(debruijn, _))
921+
if debruijn >= self.outer_index => true,
922+
_ => ct.super_visit_with(self),
921923
}
922924
}
923925
}

‎src/librustc/ty/print/pretty.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ pub trait PrettyPrinter<'tcx>:
689689
if self.tcx().sess.verbose() {
690690
p!(write(
691691
" closure_kind_ty={:?} closure_sig_ty={:?}",
692-
substs.as_closure().kind(did, self.tcx()),
692+
substs.as_closure().kind_ty(did, self.tcx()),
693693
substs.as_closure().sig_ty(did, self.tcx())
694694
));
695695
}
@@ -698,7 +698,9 @@ pub trait PrettyPrinter<'tcx>:
698698
},
699699
ty::Array(ty, sz) => {
700700
p!(write("["), print(ty), write("; "));
701-
if let ConstValue::Unevaluated(..) = sz.val {
701+
if self.tcx().sess.verbose() {
702+
p!(write("{:?}", sz));
703+
} else if let ConstValue::Unevaluated(..) = sz.val {
702704
// do not try to evalute unevaluated constants. If we are const evaluating an
703705
// array length anon const, rustc will (with debug assertions) print the
704706
// constant's path. Which will end up here again.
@@ -855,6 +857,11 @@ pub trait PrettyPrinter<'tcx>:
855857
) -> Result<Self::Const, Self::Error> {
856858
define_scoped_cx!(self);
857859

860+
if self.tcx().sess.verbose() {
861+
p!(write("Const({:?}: {:?})", ct.val, ct.ty));
862+
return Ok(self);
863+
}
864+
858865
let u8 = self.tcx().types.u8;
859866
if let ty::FnDef(did, substs) = ct.ty.kind {
860867
p!(print_value_path(did, substs));

‎src/librustc/ty/sty.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2203,7 +2203,9 @@ impl<'tcx> TyS<'tcx> {
22032203
_ => bug!("cannot convert type `{:?}` to a closure kind", self),
22042204
},
22052205

2206-
Infer(_) => None,
2206+
// "Bound" types appear in canonical queries when the
2207+
// closure type is not yet known
2208+
Bound(..) | Infer(_) => None,
22072209

22082210
Error => Some(ty::ClosureKind::Fn),
22092211

‎src/librustc_passes/error_codes.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,34 @@ fn main() {
286286
```
287287
"##,
288288

289+
E0561: r##"
290+
A non-ident or non-wildcard pattern has been used as a parameter of a function
291+
pointer type.
292+
293+
Erroneous code example:
294+
295+
```compile_fail,E0561
296+
type A1 = fn(mut param: u8); // error!
297+
type A2 = fn(&param: u32); // error!
298+
```
299+
300+
When using an alias over a function type, you cannot e.g. denote a parameter as
301+
being mutable.
302+
303+
To fix the issue, remove patterns (`_` is allowed though). Example:
304+
305+
```
306+
type A1 = fn(param: u8); // ok!
307+
type A2 = fn(_: u32); // ok!
308+
```
309+
310+
You can also omit the parameter name:
311+
312+
```
313+
type A3 = fn(i16); // ok!
314+
```
315+
"##,
316+
289317
E0571: r##"
290318
A `break` statement with an argument appeared in a non-`loop` loop.
291319
@@ -503,7 +531,6 @@ Switch to the Rust 2018 edition to use `async fn`.
503531
;
504532
E0226, // only a single explicit lifetime bound is permitted
505533
E0472, // asm! is unsupported on this target
506-
E0561, // patterns aren't allowed in function pointer types
507534
E0567, // auto traits can not have generic parameters
508535
E0568, // auto traits can not have super traits
509536
E0666, // nested `impl Trait` is illegal

‎src/librustc_traits/evaluate_obligation.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ fn evaluate_obligation<'tcx>(
1717
tcx: TyCtxt<'tcx>,
1818
canonical_goal: CanonicalPredicateGoal<'tcx>,
1919
) -> Result<EvaluationResult, OverflowError> {
20+
debug!("evaluate_obligation(canonical_goal={:#?})", canonical_goal);
2021
tcx.infer_ctxt().enter_with_canonical(
2122
DUMMY_SP,
2223
&canonical_goal,
2324
|ref infcx, goal, _canonical_inference_vars| {
25+
debug!("evaluate_obligation: goal={:#?}", goal);
2426
let ParamEnvAnd {
2527
param_env,
2628
value: predicate,

‎src/librustc_typeck/check/demand.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
349349

350350
// If the span is from a macro, then it's hard to extract the text
351351
// and make a good suggestion, so don't bother.
352-
let is_macro = sp.from_expansion();
352+
let is_desugaring = match sp.desugaring_kind() {
353+
Some(k) => sp.is_desugaring(k),
354+
None => false
355+
};
356+
let is_macro = sp.from_expansion() && !is_desugaring;
353357

354358
match (&expr.kind, &expected.kind, &checked_ty.kind) {
355359
(_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.kind, &check.kind) {

‎src/librustc_typeck/check/expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8787
}
8888

8989
if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
90+
self.suggest_ref_or_into(&mut err, expr, expected_ty, ty);
91+
9092
let expr = match &expr.kind {
9193
ExprKind::DropTemps(expr) => expr,
9294
_ => expr,

‎src/libstd/fs.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3112,8 +3112,10 @@ mod tests {
31123112

31133113
#[cfg(windows)]
31143114
let invalid_options = 87; // ERROR_INVALID_PARAMETER
3115-
#[cfg(unix)]
3115+
#[cfg(all(unix, not(target_os = "vxworks")))]
31163116
let invalid_options = "Invalid argument";
3117+
#[cfg(target_os = "vxworks")]
3118+
let invalid_options = "invalid argument";
31173119

31183120
// Test various combinations of creation modes and access modes.
31193121
//

‎src/libsyntax/parse/parser.rs

Lines changed: 38 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ mod stmt;
1111
mod generics;
1212

1313
use crate::ast::{
14-
self, DUMMY_NODE_ID, AttrStyle, Attribute, BindingMode, CrateSugar, FnDecl, Ident,
14+
self, DUMMY_NODE_ID, AttrStyle, Attribute, BindingMode, CrateSugar, Ident,
1515
IsAsync, MacDelimiter, Mutability, Param, StrStyle, SelfKind, TyKind, Visibility,
1616
VisibilityKind, Unsafety,
1717
};
@@ -56,6 +56,17 @@ crate enum BlockMode {
5656
Ignore,
5757
}
5858

59+
/// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
60+
struct ParamCfg {
61+
/// Is `self` is allowed as the first parameter?
62+
is_self_allowed: bool,
63+
/// Is `...` allowed as the tail of the parameter list?
64+
allow_c_variadic: bool,
65+
/// `is_name_required` decides if, per-parameter,
66+
/// the parameter must have a pattern or just a type.
67+
is_name_required: fn(&token::Token) -> bool,
68+
}
69+
5970
/// Like `maybe_whole_expr`, but for things other than expressions.
6071
#[macro_export]
6172
macro_rules! maybe_whole {
@@ -1094,26 +1105,18 @@ impl<'a> Parser<'a> {
10941105
res
10951106
}
10961107

1097-
fn parse_fn_params(
1098-
&mut self,
1099-
named_params: bool,
1100-
allow_c_variadic: bool,
1101-
) -> PResult<'a, Vec<Param>> {
1108+
/// Parses the parameter list of a function, including the `(` and `)` delimiters.
1109+
fn parse_fn_params(&mut self, mut cfg: ParamCfg) -> PResult<'a, Vec<Param>> {
11021110
let sp = self.token.span;
1103-
let do_not_enforce_named_params_for_c_variadic = |token: &token::Token| {
1104-
match token.kind {
1105-
token::DotDotDot => false,
1106-
_ => named_params,
1107-
}
1108-
};
1111+
let is_trait_item = cfg.is_self_allowed;
11091112
let mut c_variadic = false;
1113+
// Parse the arguments, starting out with `self` being possibly allowed...
11101114
let (params, _) = self.parse_paren_comma_seq(|p| {
1111-
match p.parse_param_general(
1112-
false,
1113-
false,
1114-
allow_c_variadic,
1115-
do_not_enforce_named_params_for_c_variadic,
1116-
) {
1115+
let param = p.parse_param_general(&cfg, is_trait_item);
1116+
// ...now that we've parsed the first argument, `self` is no longer allowed.
1117+
cfg.is_self_allowed = false;
1118+
1119+
match param {
11171120
Ok(param) => Ok(
11181121
if let TyKind::CVarArgs = param.ty.kind {
11191122
c_variadic = true;
@@ -1144,7 +1147,10 @@ impl<'a> Parser<'a> {
11441147
}
11451148
})?;
11461149

1147-
let params: Vec<_> = params.into_iter().filter_map(|x| x).collect();
1150+
let mut params: Vec<_> = params.into_iter().filter_map(|x| x).collect();
1151+
1152+
// Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
1153+
self.deduplicate_recovered_params_names(&mut params);
11481154

11491155
if c_variadic && params.len() <= 1 {
11501156
self.span_err(
@@ -1156,79 +1162,53 @@ impl<'a> Parser<'a> {
11561162
Ok(params)
11571163
}
11581164

1159-
/// Parses the parameter list and result type of a function that may have a `self` parameter.
1160-
fn parse_fn_decl_with_self(
1161-
&mut self,
1162-
is_name_required: impl Copy + Fn(&token::Token) -> bool,
1163-
) -> PResult<'a, P<FnDecl>> {
1164-
// Parse the arguments, starting out with `self` being allowed...
1165-
let mut is_self_allowed = true;
1166-
let (mut inputs, _): (Vec<_>, _) = self.parse_paren_comma_seq(|p| {
1167-
let res = p.parse_param_general(is_self_allowed, true, false, is_name_required);
1168-
// ...but now that we've parsed the first argument, `self` is no longer allowed.
1169-
is_self_allowed = false;
1170-
res
1171-
})?;
1172-
1173-
// Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
1174-
self.deduplicate_recovered_params_names(&mut inputs);
1175-
1176-
Ok(P(FnDecl {
1177-
inputs,
1178-
output: self.parse_ret_ty(true)?,
1179-
}))
1180-
}
1181-
11821165
/// Skips unexpected attributes and doc comments in this position and emits an appropriate
11831166
/// error.
11841167
/// This version of parse param doesn't necessarily require identifier names.
1185-
fn parse_param_general(
1186-
&mut self,
1187-
is_self_allowed: bool,
1188-
is_trait_item: bool,
1189-
allow_c_variadic: bool,
1190-
is_name_required: impl Fn(&token::Token) -> bool,
1191-
) -> PResult<'a, Param> {
1168+
fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> {
11921169
let lo = self.token.span;
11931170
let attrs = self.parse_outer_attributes()?;
11941171

11951172
// Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
11961173
if let Some(mut param) = self.parse_self_param()? {
11971174
param.attrs = attrs.into();
1198-
return if is_self_allowed {
1175+
return if cfg.is_self_allowed {
11991176
Ok(param)
12001177
} else {
12011178
self.recover_bad_self_param(param, is_trait_item)
12021179
};
12031180
}
12041181

1205-
let is_name_required = is_name_required(&self.token);
1182+
let is_name_required = match self.token.kind {
1183+
token::DotDotDot => false,
1184+
_ => (cfg.is_name_required)(&self.token),
1185+
};
12061186
let (pat, ty) = if is_name_required || self.is_named_param() {
12071187
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
12081188

12091189
let pat = self.parse_fn_param_pat()?;
12101190
if let Err(mut err) = self.expect(&token::Colon) {
1211-
if let Some(ident) = self.parameter_without_type(
1191+
return if let Some(ident) = self.parameter_without_type(
12121192
&mut err,
12131193
pat,
12141194
is_name_required,
1215-
is_self_allowed,
1195+
cfg.is_self_allowed,
12161196
is_trait_item,
12171197
) {
12181198
err.emit();
1219-
return Ok(dummy_arg(ident));
1199+
Ok(dummy_arg(ident))
12201200
} else {
1221-
return Err(err);
1222-
}
1201+
Err(err)
1202+
};
12231203
}
12241204

12251205
self.eat_incorrect_doc_comment_for_param_type();
1226-
(pat, self.parse_ty_common(true, true, allow_c_variadic)?)
1206+
(pat, self.parse_ty_common(true, true, cfg.allow_c_variadic)?)
12271207
} else {
12281208
debug!("parse_param_general ident_to_pat");
12291209
let parser_snapshot_before_ty = self.clone();
12301210
self.eat_incorrect_doc_comment_for_param_type();
1231-
let mut ty = self.parse_ty_common(true, true, allow_c_variadic);
1211+
let mut ty = self.parse_ty_common(true, true, cfg.allow_c_variadic);
12321212
if ty.is_ok() && self.token != token::Comma &&
12331213
self.token != token::CloseDelim(token::Paren) {
12341214
// This wasn't actually a type, but a pattern looking like a type,

‎src/libsyntax/parse/parser/item.rs

Lines changed: 152 additions & 141 deletions
Large diffs are not rendered by default.

‎src/libsyntax/parse/parser/ty.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@ use crate::{maybe_whole, maybe_recover_from_interpolated_ty_qpath};
44
use crate::ptr::P;
55
use crate::ast::{self, Ty, TyKind, MutTy, BareFnTy, FunctionRetTy, GenericParam, Lifetime, Ident};
66
use crate::ast::{TraitBoundModifier, TraitObjectSyntax, GenericBound, GenericBounds, PolyTraitRef};
7-
use crate::ast::{Mutability, AnonConst, FnDecl, Mac};
7+
use crate::ast::{Mutability, AnonConst, Mac};
88
use crate::parse::token::{self, Token};
99
use crate::source_map::Span;
1010
use crate::symbol::{kw};
1111

12-
use rustc_target::spec::abi::Abi;
13-
1412
use errors::{Applicability, pluralise};
1513

1614
/// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
@@ -281,19 +279,14 @@ impl<'a> Parser<'a> {
281279
*/
282280

283281
let unsafety = self.parse_unsafety();
284-
let abi = if self.eat_keyword(kw::Extern) {
285-
self.parse_opt_abi()?.unwrap_or(Abi::C)
286-
} else {
287-
Abi::Rust
288-
};
289-
282+
let abi = self.parse_extern_abi()?;
290283
self.expect_keyword(kw::Fn)?;
291-
let inputs = self.parse_fn_params(false, true)?;
292-
let ret_ty = self.parse_ret_ty(false)?;
293-
let decl = P(FnDecl {
294-
inputs,
295-
output: ret_ty,
296-
});
284+
let cfg = super::ParamCfg {
285+
is_self_allowed: false,
286+
allow_c_variadic: true,
287+
is_name_required: |_| false,
288+
};
289+
let decl = self.parse_fn_decl(cfg, false)?;
297290
Ok(TyKind::BareFn(P(BareFnTy {
298291
abi,
299292
unsafety,

‎src/test/ui/const-generics/slice-const-param-mismatch.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,26 @@ error[E0308]: mismatched types
1212
LL | let _: ConstString<"Hello"> = ConstString::<"World">;
1313
| ^^^^^^^^^^^^^^^^^^^^^^ expected `"Hello"`, found `"World"`
1414
|
15-
= note: expected type `ConstString<>`
16-
found type `ConstString<>`
15+
= note: expected type `ConstString<"Hello">`
16+
found type `ConstString<"World">`
1717

1818
error[E0308]: mismatched types
1919
--> $DIR/slice-const-param-mismatch.rs:11:33
2020
|
2121
LL | let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">;
2222
| ^^^^^^^^^^^^^^^^^^^^^ expected `"ℇ㇈↦"`, found `"ℇ㇈↥"`
2323
|
24-
= note: expected type `ConstString<>`
25-
found type `ConstString<>`
24+
= note: expected type `ConstString<"ℇ㇈↦">`
25+
found type `ConstString<"ℇ㇈↥">`
2626

2727
error[E0308]: mismatched types
2828
--> $DIR/slice-const-param-mismatch.rs:13:33
2929
|
3030
LL | let _: ConstBytes<b"AAA"> = ConstBytes::<b"BBB">;
3131
| ^^^^^^^^^^^^^^^^^^^^ expected `b"AAA"`, found `b"BBB"`
3232
|
33-
= note: expected type `ConstBytes<>`
34-
found type `ConstBytes<>`
33+
= note: expected type `ConstBytes<b"AAA">`
34+
found type `ConstBytes<b"BBB">`
3535

3636
error: aborting due to 3 previous errors
3737

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![feature(const_generics)]
2+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
3+
4+
// tests the diagnostic output of type mismatches for types that have const generics arguments.
5+
6+
use std::marker::PhantomData;
7+
8+
struct A<'a, T, const X: u32, const Y: u32> {
9+
data: PhantomData<&'a T>
10+
}
11+
12+
fn a<'a, 'b>() {
13+
let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data: PhantomData };
14+
//~^ ERROR mismatched types
15+
let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData };
16+
//~^ ERROR mismatched types
17+
}
18+
19+
pub fn main() {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/types-mismatch-const-args.rs:1:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
9+
error[E0308]: mismatched types
10+
--> $DIR/types-mismatch-const-args.rs:13:41
11+
|
12+
LL | let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data: PhantomData };
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2u32`, found `4u32`
14+
|
15+
= note: expected type `A<'_, _, 2u32, _>`
16+
found type `A<'_, _, 4u32, _>`
17+
18+
error[E0308]: mismatched types
19+
--> $DIR/types-mismatch-const-args.rs:15:41
20+
|
21+
LL | let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData };
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u16, found u32
23+
|
24+
= note: expected type `A<'a, u16, _, _>`
25+
found type `A<'b, u32, _, _>`
26+
27+
error: aborting due to 2 previous errors
28+
29+
For more information about this error, try `rustc --explain E0308`.

‎src/test/ui/if/if-no-match-bindings.stderr

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ error[E0308]: mismatched types
22
--> $DIR/if-no-match-bindings.rs:18:8
33
|
44
LL | if b_ref() {}
5-
| ^^^^^^^ expected bool, found &bool
5+
| ^^^^^^^
6+
| |
7+
| expected bool, found &bool
8+
| help: consider dereferencing the borrow: `*b_ref()`
69
|
710
= note: expected type `bool`
811
found type `&bool`
@@ -11,7 +14,10 @@ error[E0308]: mismatched types
1114
--> $DIR/if-no-match-bindings.rs:19:8
1215
|
1316
LL | if b_mut_ref() {}
14-
| ^^^^^^^^^^^ expected bool, found &mut bool
17+
| ^^^^^^^^^^^
18+
| |
19+
| expected bool, found &mut bool
20+
| help: consider dereferencing the borrow: `*b_mut_ref()`
1521
|
1622
= note: expected type `bool`
1723
found type `&mut bool`
@@ -20,7 +26,10 @@ error[E0308]: mismatched types
2026
--> $DIR/if-no-match-bindings.rs:20:8
2127
|
2228
LL | if &true {}
23-
| ^^^^^ expected bool, found &bool
29+
| ^^^^^
30+
| |
31+
| expected bool, found &bool
32+
| help: consider dereferencing the borrow: `*&true`
2433
|
2534
= note: expected type `bool`
2635
found type `&bool`
@@ -29,7 +38,10 @@ error[E0308]: mismatched types
2938
--> $DIR/if-no-match-bindings.rs:21:8
3039
|
3140
LL | if &mut true {}
32-
| ^^^^^^^^^ expected bool, found &mut bool
41+
| ^^^^^^^^^
42+
| |
43+
| expected bool, found &mut bool
44+
| help: consider dereferencing the borrow: `*&mut true`
3345
|
3446
= note: expected type `bool`
3547
found type `&mut bool`
@@ -38,7 +50,10 @@ error[E0308]: mismatched types
3850
--> $DIR/if-no-match-bindings.rs:24:11
3951
|
4052
LL | while b_ref() {}
41-
| ^^^^^^^ expected bool, found &bool
53+
| ^^^^^^^
54+
| |
55+
| expected bool, found &bool
56+
| help: consider dereferencing the borrow: `*b_ref()`
4257
|
4358
= note: expected type `bool`
4459
found type `&bool`
@@ -47,7 +62,10 @@ error[E0308]: mismatched types
4762
--> $DIR/if-no-match-bindings.rs:25:11
4863
|
4964
LL | while b_mut_ref() {}
50-
| ^^^^^^^^^^^ expected bool, found &mut bool
65+
| ^^^^^^^^^^^
66+
| |
67+
| expected bool, found &mut bool
68+
| help: consider dereferencing the borrow: `*b_mut_ref()`
5169
|
5270
= note: expected type `bool`
5371
found type `&mut bool`
@@ -56,7 +74,10 @@ error[E0308]: mismatched types
5674
--> $DIR/if-no-match-bindings.rs:26:11
5775
|
5876
LL | while &true {}
59-
| ^^^^^ expected bool, found &bool
77+
| ^^^^^
78+
| |
79+
| expected bool, found &bool
80+
| help: consider dereferencing the borrow: `*&true`
6081
|
6182
= note: expected type `bool`
6283
found type `&bool`
@@ -65,7 +86,10 @@ error[E0308]: mismatched types
6586
--> $DIR/if-no-match-bindings.rs:27:11
6687
|
6788
LL | while &mut true {}
68-
| ^^^^^^^^^ expected bool, found &mut bool
89+
| ^^^^^^^^^
90+
| |
91+
| expected bool, found &mut bool
92+
| help: consider dereferencing the borrow: `*&mut true`
6993
|
7094
= note: expected type `bool`
7195
found type `&mut bool`

‎src/test/ui/no-patterns-in-args-macro.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ LL | m!((bad, pat));
1818

1919
error: aborting due to 3 previous errors
2020

21-
Some errors have detailed explanations: E0130, E0642.
21+
Some errors have detailed explanations: E0130, E0561, E0642.
2222
For more information about an error, try `rustc --explain E0130`.

‎src/test/ui/no-patterns-in-args.stderr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,5 @@ LL | type A2 = fn(&arg: u8);
3030

3131
error: aborting due to 5 previous errors
3232

33-
For more information about this error, try `rustc --explain E0130`.
33+
Some errors have detailed explanations: E0130, E0561.
34+
For more information about an error, try `rustc --explain E0130`.

‎src/test/ui/parser/issue-33413.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ struct S;
33
impl S {
44
fn f(*, a: u8) -> u8 {}
55
//~^ ERROR expected parameter name, found `*`
6+
//~| ERROR mismatched types
67
}
78

89
fn main() {}

‎src/test/ui/parser/issue-33413.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,17 @@ error: expected parameter name, found `*`
44
LL | fn f(*, a: u8) -> u8 {}
55
| ^ expected parameter name
66

7-
error: aborting due to previous error
7+
error[E0308]: mismatched types
8+
--> $DIR/issue-33413.rs:4:23
9+
|
10+
LL | fn f(*, a: u8) -> u8 {}
11+
| - ^^ expected u8, found ()
12+
| |
13+
| implicitly returns `()` as its body has no tail or `return` expression
14+
|
15+
= note: expected type `u8`
16+
found type `()`
17+
18+
error: aborting due to 2 previous errors
819

20+
For more information about this error, try `rustc --explain E0308`.

‎src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,10 @@ error[E0308]: mismatched types
517517
--> $DIR/disallowed-positions.rs:32:8
518518
|
519519
LL | if &let 0 = 0 {}
520-
| ^^^^^^^^^^ expected bool, found &bool
520+
| ^^^^^^^^^^
521+
| |
522+
| expected bool, found &bool
523+
| help: consider dereferencing the borrow: `*&let 0 = 0`
521524
|
522525
= note: expected type `bool`
523526
found type `&bool`
@@ -702,7 +705,10 @@ error[E0308]: mismatched types
702705
--> $DIR/disallowed-positions.rs:96:11
703706
|
704707
LL | while &let 0 = 0 {}
705-
| ^^^^^^^^^^ expected bool, found &bool
708+
| ^^^^^^^^^^
709+
| |
710+
| expected bool, found &bool
711+
| help: consider dereferencing the borrow: `*&let 0 = 0`
706712
|
707713
= note: expected type `bool`
708714
found type `&bool`

0 commit comments

Comments
 (0)
Please sign in to comment.