Auto merge of #87698 - camsteffen:rollup-yvjfc26, r=camsteffen

Rollup of 6 pull requests

Successful merges:

 - #86176 (Implement a `explicit_generic_args_with_impl_trait` feature gate)
 - #87654 (Add documentation for the order of Option and Result)
 - #87659 (Fix invalid suggestions for non-ASCII characters in byte constants)
 - #87673 (Tweak opaque type mismatch error)
 - #87687 (Inline some macros)
 - #87690 (Add missing "allocated object" doc link to `<*mut T>::add`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-08-02 15:54:11 +00:00
commit 6be8a06bcf
32 changed files with 437 additions and 170 deletions

View File

@ -442,18 +442,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
then: &Block,
else_opt: Option<&Expr>,
) -> hir::ExprKind<'hir> {
macro_rules! make_if {
($opt:expr) => {{
let cond = self.lower_expr(cond);
let then_expr = self.lower_block_expr(then);
hir::ExprKind::If(cond, self.arena.alloc(then_expr), $opt)
}};
}
if let Some(rslt) = else_opt {
make_if!(Some(self.lower_expr(rslt)))
} else {
make_if!(None)
}
let cond = self.lower_expr(cond);
let then = self.arena.alloc(self.lower_block_expr(then));
let els = else_opt.map(|els| self.lower_expr(els));
hir::ExprKind::If(cond, then, els)
}
fn lower_expr_if_let(

View File

@ -687,6 +687,9 @@ declare_features! (
/// Trait upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
(incomplete, trait_upcasting, "1.56.0", Some(65991), None),
/// Allows explicit generic arguments specification with `impl Trait` present.
(active, explicit_generic_args_with_impl_trait, "1.56.0", Some(83701), None),
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------

View File

@ -71,7 +71,7 @@ use rustc_middle::ty::{
subst::{GenericArgKind, Subst, SubstsRef},
Region, Ty, TyCtxt, TypeFoldable,
};
use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span};
use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span};
use rustc_target::spec::abi;
use std::ops::ControlFlow;
use std::{cmp, fmt, iter};
@ -1485,31 +1485,49 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let count = values.len();
let kind = key.descr();
let mut returned_async_output_error = false;
for sp in values {
err.span_label(
*sp,
format!(
"{}{}{} {}{}",
if sp.is_desugaring(DesugaringKind::Async)
&& !returned_async_output_error
{
"checked the `Output` of this `async fn`, "
} else if count == 1 {
"the "
} else {
""
},
if count > 1 { "one of the " } else { "" },
target,
kind,
pluralize!(count),
),
);
if sp.is_desugaring(DesugaringKind::Async)
&& returned_async_output_error == false
{
err.note("while checking the return type of the `async fn`");
for &sp in values {
if sp.is_desugaring(DesugaringKind::Async) && !returned_async_output_error {
if &[sp] != err.span.primary_spans() {
let mut span: MultiSpan = sp.into();
span.push_span_label(
sp,
format!(
"checked the `Output` of this `async fn`, {}{} {}{}",
if count > 1 { "one of the " } else { "" },
target,
kind,
pluralize!(count),
),
);
err.span_note(
span,
"while checking the return type of the `async fn`",
);
} else {
err.span_label(
sp,
format!(
"checked the `Output` of this `async fn`, {}{} {}{}",
if count > 1 { "one of the " } else { "" },
target,
kind,
pluralize!(count),
),
);
err.note("while checking the return type of the `async fn`");
}
returned_async_output_error = true;
} else {
err.span_label(
sp,
format!(
"{}{} {}{}",
if count == 1 { "the " } else { "one of the " },
target,
kind,
pluralize!(count),
),
);
}
}
}

View File

@ -769,7 +769,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// (#83606): Do not emit a suggestion if the parent has an `impl Trait`
// as an argument otherwise it will cause the E0282 error.
if !has_impl_trait {
if !has_impl_trait || self.tcx.features().explicit_generic_args_with_impl_trait {
err.span_suggestion_verbose(
span,
"consider specifying the const argument",

View File

@ -153,16 +153,37 @@ pub(crate) fn emit_unescape_error(
EscapeError::NonAsciiCharInByte => {
assert!(mode.is_bytes());
let (c, span) = last_char();
handler
.struct_span_err(span, "non-ASCII character in byte constant")
.span_label(span, "byte constant must be ASCII")
.span_suggestion(
let mut err = handler.struct_span_err(span, "non-ASCII character in byte constant");
err.span_label(span, "byte constant must be ASCII");
if (c as u32) <= 0xFF {
err.span_suggestion(
span,
"use a \\xHH escape for a non-ASCII byte",
&format!(
"if you meant to use the unicode code point for '{}', use a \\xHH escape",
c
),
format!("\\x{:X}", c as u32),
Applicability::MachineApplicable,
)
.emit();
Applicability::MaybeIncorrect,
);
} else if matches!(mode, Mode::Byte) {
err.span_label(span, "this multibyte character does not fit into a single byte");
} else if matches!(mode, Mode::ByteStr) {
let mut utf8 = String::new();
utf8.push(c);
err.span_suggestion(
span,
&format!(
"if you meant to use the UTF-8 encoding of '{}', use \\xHH escapes",
c
),
utf8.as_bytes()
.iter()
.map(|b: &u8| format!("\\x{:X}", *b))
.fold("".to_string(), |a, c| a + &c),
Applicability::MaybeIncorrect,
);
}
err.emit();
}
EscapeError::NonAsciiCharInByteString => {
assert!(mode.is_bytes());

View File

@ -554,6 +554,7 @@ symbols! {
expected,
expf32,
expf64,
explicit_generic_args_with_impl_trait,
export_name,
expr,
extended_key_value_attributes,

View File

@ -459,7 +459,32 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let default_counts = gen_params.own_defaults();
let param_counts = gen_params.own_counts();
let named_type_param_count = param_counts.types - has_self as usize;
// Subtracting from param count to ensure type params synthesized from `impl Trait`
// cannot be explictly specified even with `explicit_generic_args_with_impl_trait`
// feature enabled.
let synth_type_param_count = if tcx.features().explicit_generic_args_with_impl_trait {
gen_params
.params
.iter()
.filter(|param| {
matches!(
param.kind,
ty::GenericParamDefKind::Type {
synthetic: Some(
hir::SyntheticTyParamKind::ImplTrait
| hir::SyntheticTyParamKind::FromAttr
),
..
}
)
})
.count()
} else {
0
};
let named_type_param_count =
param_counts.types - has_self as usize - synth_type_param_count;
let infer_lifetimes =
gen_pos != GenericArgPosition::Type && !gen_args.has_lifetime_params();
@ -588,6 +613,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
param_counts.consts + named_type_param_count
- default_counts.types
- default_counts.consts
- synth_type_param_count
};
debug!("expected_min: {:?}", expected_min);
debug!("arg_counts.lifetimes: {:?}", gen_args.num_lifetime_params());
@ -617,7 +643,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
seg: &hir::PathSegment<'_>,
generics: &ty::Generics,
) -> bool {
let explicit = !seg.infer_args;
if seg.infer_args || tcx.features().explicit_generic_args_with_impl_trait {
return false;
}
let impl_trait = generics.params.iter().any(|param| {
matches!(
param.kind,
@ -630,7 +659,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
)
});
if explicit && impl_trait {
if impl_trait {
let spans = seg
.args()
.args

View File

@ -13,41 +13,6 @@ use rustc_trait_selection::traits::{
StatementAsExpression,
};
macro_rules! create_maybe_get_coercion_reason {
($fn_name:ident, $node:expr) => {
pub(crate) fn $fn_name(&self, hir_id: hir::HirId, sp: Span) -> Option<(Span, String)> {
let node = $node(self.tcx.hir(), hir_id);
if let hir::Node::Block(block) = node {
// check that the body's parent is an fn
let parent = self.tcx.hir().get(
self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(block.hir_id)),
);
if let (
Some(expr),
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. }),
) = (&block.expr, parent)
{
// check that the `if` expr without `else` is the fn body's expr
if expr.span == sp {
return self.get_fn_decl(hir_id).and_then(|(fn_decl, _)| {
let span = fn_decl.output.span();
let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?;
Some((
span,
format!("expected `{}` because of this return type", snippet),
))
});
}
}
}
if let hir::Node::Local(hir::Local { ty: Some(_), pat, .. }) = node {
return Some((pat.span, "expected because of this assignment".to_string()));
}
None
}
};
}
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn check_match(
&self,
@ -154,7 +119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr.span,
&arms[0].body,
&mut coercion,
|hir_id, span| self.maybe_get_coercion_reason(hir_id, span),
|hir_id, span| self.coercion_reason_match(hir_id, span),
) {
tcx.ty_error()
} else {
@ -373,23 +338,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error
}
create_maybe_get_coercion_reason!(
maybe_get_coercion_reason,
|hir: rustc_middle::hir::map::Map<'a>, id| {
let arm_id = hir.get_parent_node(id);
let match_id = hir.get_parent_node(arm_id);
let containing_id = hir.get_parent_node(match_id);
hir.get(containing_id)
}
);
pub(crate) fn coercion_reason_if(
&self,
hir_id: hir::HirId,
span: Span,
) -> Option<(Span, String)> {
self.coercion_reason_inner(hir_id, span, 1)
}
create_maybe_get_coercion_reason!(
maybe_get_coercion_reason_if,
|hir: rustc_middle::hir::map::Map<'a>, id| {
let rslt = hir.get_parent_node(hir.get_parent_node(id));
hir.get(rslt)
pub(crate) fn coercion_reason_match(
&self,
hir_id: hir::HirId,
span: Span,
) -> Option<(Span, String)> {
self.coercion_reason_inner(hir_id, span, 2)
}
fn coercion_reason_inner(
&self,
hir_id: hir::HirId,
span: Span,
parent_index: usize,
) -> Option<(Span, String)> {
let hir = self.tcx.hir();
let mut parent_iter = hir.parent_iter(hir_id);
let (_, node) = parent_iter.nth(parent_index)?;
match node {
hir::Node::Block(block) => {
let expr = block.expr?;
// check that the body's parent is an fn
let (_, parent) = parent_iter.nth(1)?;
if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. }) = parent {
// check that the `if` expr without `else` is the fn body's expr
if expr.span == span {
let (fn_decl, _) = self.get_fn_decl(hir_id)?;
let span = fn_decl.output.span();
let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?;
return Some((
span,
format!("expected `{}` because of this return type", snippet),
));
}
}
None
}
hir::Node::Local(hir::Local { ty: Some(_), pat, .. }) => {
Some((pat.span, "expected because of this assignment".to_string()))
}
_ => None,
}
);
}
pub(crate) fn if_cause(
&self,

View File

@ -838,7 +838,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.diverges.set(cond_diverges | then_diverges & else_diverges);
} else {
self.if_fallback_coercion(sp, then_expr, &mut coerce, |hir_id, span| {
self.maybe_get_coercion_reason_if(hir_id, span)
self.coercion_reason_if(hir_id, span)
});
// If the condition is false we can't diverge.

View File

@ -285,6 +285,19 @@
//! assert_eq!(res, ["error!", "error!", "foo", "error!", "bar"]);
//! ```
//!
//! ## Comparison operators
//!
//! If `T` implements [`PartialOrd`] then [`Option<T>`] will derive its
//! [`PartialOrd`] implementation. With this order, [`None`] compares as
//! less than any [`Some`], and two [`Some`] compare the same way as their
//! contained values would in `T`. If `T` also implements
//! [`Ord`], then so does [`Option<T>`].
//!
//! ```
//! assert!(None < Some(0));
//! assert!(Some(0) < Some(1));
//! ```
//!
//! ## Iterating over `Option`
//!
//! An [`Option`] can be iterated over. This can be helpful if you need an

View File

@ -596,6 +596,7 @@ impl<T: ?Sized> *mut T {
/// enables more aggressive compiler optimizations.
///
/// [`wrapping_add`]: #method.wrapping_add
/// [allocated object]: crate::ptr#allocated-object
///
/// # Examples
///

View File

@ -379,6 +379,24 @@
//! [`and_then`]: Result::and_then
//! [`or_else`]: Result::or_else
//!
//! ## Comparison operators
//!
//! If `T` and `E` both implement [`PartialOrd`] then [`Result<T, E>`] will
//! derive its [`PartialOrd`] implementation. With this order, an [`Ok`]
//! compares as less than any [`Err`], while two [`Ok`] or two [`Err`]
//! compare as their contained values would in `T` or `E` respectively. If `T`
//! and `E` both also implement [`Ord`], then so does [`Result<T, E>`].
//!
//! ```
//! assert!(Ok(1) < Err(0));
//! let x: Result<i32, ()> = Ok(0);
//! let y = Ok(1);
//! assert!(x < y);
//! let x: Result<(), i32> = Err(0);
//! let y = Err(1);
//! assert!(x < y);
//! ```
//!
//! ## Iterating over `Result`
//!
//! A [`Result`] can be iterated over. This can be helpful if you need an

View File

@ -0,0 +1,53 @@
# `explicit_generic_args_with_impl_trait`
The tracking issue for this feature is: [#83701]
[#83701]: https://github.com/rust-lang/rust/issues/83701
------------------------
The `explicit_generic_args_with_impl_trait` feature gate lets you specify generic arguments even
when `impl Trait` is used in argument position.
A simple example is:
```rust
#![feature(explicit_generic_args_with_impl_trait)]
fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
fn main() {
foo::<str>("".to_string());
}
```
This is currently rejected:
```text
error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
--> src/main.rs:6:11
|
6 | foo::<str>("".to_string());
| ^^^ explicit generic argument not allowed
```
However it would compile if `explicit_generic_args_with_impl_trait` is enabled.
Note that the synthetic type parameters from `impl Trait` are still implicit and you
cannot explicitly specify these:
```rust,compile_fail
#![feature(explicit_generic_args_with_impl_trait)]
fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
fn bar<T: ?Sized, F: AsRef<T>>(_f: F) {}
fn main() {
bar::<str, _>("".to_string()); // Okay
bar::<str, String>("".to_string()); // Okay
foo::<str>("".to_string()); // Okay
foo::<str, String>("".to_string()); // Error, you cannot specify `impl Trait` explicitly
}
```

View File

@ -1,13 +1,14 @@
error[E0308]: mismatched types
--> $DIR/dont-suggest-missing-await.rs:14:18
|
LL | async fn make_u32() -> u32 {
| --- checked the `Output` of this `async fn`, found opaque type
...
LL | take_u32(x)
| ^ expected `u32`, found opaque type
|
= note: while checking the return type of the `async fn`
note: while checking the return type of the `async fn`
--> $DIR/dont-suggest-missing-await.rs:7:24
|
LL | async fn make_u32() -> u32 {
| ^^^ checked the `Output` of this `async fn`, found opaque type
= note: expected type `u32`
found opaque type `impl Future`
help: consider `await`ing on the `Future`

View File

@ -12,16 +12,19 @@ LL | fun(async {}, async {});
error[E0308]: mismatched types
--> $DIR/generator-desc.rs:12:16
|
LL | async fn one() {}
| - checked the `Output` of this `async fn`, expected opaque type
LL | async fn two() {}
| - checked the `Output` of this `async fn`, found opaque type
...
LL | fun(one(), two());
| ^^^^^ expected opaque type, found a different opaque type
|
= note: while checking the return type of the `async fn`
= note: while checking the return type of the `async fn`
note: while checking the return type of the `async fn`
--> $DIR/generator-desc.rs:5:16
|
LL | async fn one() {}
| ^ checked the `Output` of this `async fn`, expected opaque type
note: while checking the return type of the `async fn`
--> $DIR/generator-desc.rs:6:16
|
LL | async fn two() {}
| ^ checked the `Output` of this `async fn`, found opaque type
= note: expected opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:5:16>)
found opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:6:16>)
= help: consider `await`ing on both `Future`s

View File

@ -57,6 +57,8 @@ async fn struct_() -> Struct {
async fn tuple() -> Tuple {
//~^ NOTE checked the `Output` of this `async fn`, expected opaque type
//~| NOTE while checking the return type of the `async fn`
//~| NOTE in this expansion of desugaring of `async` block or function
Tuple(1i32)
}
@ -92,7 +94,6 @@ async fn match_() {
Tuple(_) => {} //~ ERROR mismatched types
//~^ NOTE expected opaque type, found struct `Tuple`
//~| NOTE expected opaque type `impl Future`
//~| NOTE while checking the return type of the `async fn`
}
}

View File

@ -16,7 +16,7 @@ LL | foo().await?;
| ^^^^^^
error[E0277]: the `?` operator can only be applied to values that implement `Try`
--> $DIR/issue-61076.rs:65:5
--> $DIR/issue-61076.rs:67:5
|
LL | t?;
| ^^ the `?` operator cannot be applied to type `T`
@ -33,7 +33,7 @@ LL | t.await?;
| ^^^^^^
error[E0609]: no field `0` on type `impl Future`
--> $DIR/issue-61076.rs:76:26
--> $DIR/issue-61076.rs:78:26
|
LL | let _: i32 = tuple().0;
| ^ field not available in `impl Future`, but it is available in its `Output`
@ -44,7 +44,7 @@ LL | let _: i32 = tuple().await.0;
| ^^^^^^
error[E0609]: no field `a` on type `impl Future`
--> $DIR/issue-61076.rs:80:28
--> $DIR/issue-61076.rs:82:28
|
LL | let _: i32 = struct_().a;
| ^ field not available in `impl Future`, but it is available in its `Output`
@ -55,7 +55,7 @@ LL | let _: i32 = struct_().await.a;
| ^^^^^^
error[E0599]: no method named `method` found for opaque type `impl Future` in the current scope
--> $DIR/issue-61076.rs:84:15
--> $DIR/issue-61076.rs:86:15
|
LL | struct_().method();
| ^^^^^^ method not found in `impl Future`
@ -66,15 +66,16 @@ LL | struct_().await.method();
| ^^^^^^
error[E0308]: mismatched types
--> $DIR/issue-61076.rs:92:9
--> $DIR/issue-61076.rs:94:9
|
LL | async fn tuple() -> Tuple {
| ----- checked the `Output` of this `async fn`, expected opaque type
...
LL | Tuple(_) => {}
| ^^^^^^^^ expected opaque type, found struct `Tuple`
|
= note: while checking the return type of the `async fn`
note: while checking the return type of the `async fn`
--> $DIR/issue-61076.rs:58:21
|
LL | async fn tuple() -> Tuple {
| ^^^^^ checked the `Output` of this `async fn`, expected opaque type
= note: expected opaque type `impl Future`
found struct `Tuple`
help: consider `await`ing on the `Future`

View File

@ -1,13 +1,14 @@
error[E0308]: mismatched types
--> $DIR/suggest-missing-await-closure.rs:16:18
|
LL | async fn make_u32() -> u32 {
| --- checked the `Output` of this `async fn`, found opaque type
...
LL | take_u32(x)
| ^ expected `u32`, found opaque type
|
= note: while checking the return type of the `async fn`
note: while checking the return type of the `async fn`
--> $DIR/suggest-missing-await-closure.rs:8:24
|
LL | async fn make_u32() -> u32 {
| ^^^ checked the `Output` of this `async fn`, found opaque type
= note: expected type `u32`
found opaque type `impl Future`
help: consider `await`ing on the `Future`

View File

@ -1,13 +1,14 @@
error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:12:14
|
LL | async fn make_u32() -> u32 {
| --- checked the `Output` of this `async fn`, found opaque type
...
LL | take_u32(x)
| ^ expected `u32`, found opaque type
|
= note: while checking the return type of the `async fn`
note: while checking the return type of the `async fn`
--> $DIR/suggest-missing-await.rs:5:24
|
LL | async fn make_u32() -> u32 {
| ^^^ checked the `Output` of this `async fn`, found opaque type
= note: expected type `u32`
found opaque type `impl Future`
help: consider `await`ing on the `Future`
@ -18,13 +19,14 @@ LL | take_u32(x.await)
error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:22:5
|
LL | async fn dummy() {}
| - checked the `Output` of this `async fn`, found opaque type
...
LL | dummy()
| ^^^^^^^ expected `()`, found opaque type
|
= note: while checking the return type of the `async fn`
note: while checking the return type of the `async fn`
--> $DIR/suggest-missing-await.rs:18:18
|
LL | async fn dummy() {}
| ^ checked the `Output` of this `async fn`, found opaque type
= note: expected unit type `()`
found opaque type `impl Future`
help: consider `await`ing on the `Future`

View File

@ -2,10 +2,12 @@ error: non-ASCII character in byte constant
--> $DIR/key-value-non-ascii.rs:3:19
|
LL | #[rustc_dummy = b"ffi.rs"]
| ^
| |
| byte constant must be ASCII
| help: use a \xHH escape for a non-ASCII byte: `\xFB03`
| ^ byte constant must be ASCII
|
help: if you meant to use the UTF-8 encoding of 'ffi', use \xHH escapes
|
LL | #[rustc_dummy = b"/xEF/xAC/x83.rs"]
| ^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,7 @@
#![feature(explicit_generic_args_with_impl_trait)]
fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
fn main() {
foo::<str, String>("".to_string()); //~ ERROR E0107
}

View File

@ -0,0 +1,17 @@
error[E0107]: this function takes at most 1 generic argument but 2 generic arguments were supplied
--> $DIR/explicit-generic-args-for-impl.rs:6:5
|
LL | foo::<str, String>("".to_string());
| ^^^ ------ help: remove this generic argument
| |
| expected at most 1 generic argument
|
note: function defined here, with at most 1 generic parameter: `T`
--> $DIR/explicit-generic-args-for-impl.rs:3:4
|
LL | fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
| ^^^ -
error: aborting due to previous error
For more information about this error, try `rustc --explain E0107`.

View File

@ -0,0 +1,9 @@
// check-pass
#![feature(explicit_generic_args_with_impl_trait)]
fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
fn main() {
foo::<str>("".to_string());
}

View File

@ -0,0 +1,7 @@
// gate-test-explicit_generic_args_with_impl_trait
fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
fn main() {
foo::<str>("".to_string()); //~ ERROR E0632
}

View File

@ -0,0 +1,9 @@
error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
--> $DIR/feature-gate.rs:6:11
|
LL | foo::<str>("".to_string());
| ^^^ explicit generic argument not allowed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0632`.

View File

@ -36,10 +36,12 @@ error: non-ASCII character in byte constant
--> $DIR/byte-literals.rs:10:7
|
LL | b'é';
| ^
| |
| byte constant must be ASCII
| help: use a \xHH escape for a non-ASCII byte: `\xE9`
| ^ byte constant must be ASCII
|
help: if you meant to use the unicode code point for 'é', use a \xHH escape
|
LL | b'\xE9';
| ^^^^
error[E0763]: unterminated byte constant
--> $DIR/byte-literals.rs:11:6

View File

@ -24,10 +24,12 @@ error: non-ASCII character in byte constant
--> $DIR/byte-string-literals.rs:6:7
|
LL | b"é";
| ^
| |
| byte constant must be ASCII
| help: use a \xHH escape for a non-ASCII byte: `\xE9`
| ^ byte constant must be ASCII
|
help: if you meant to use the unicode code point for 'é', use a \xHH escape
|
LL | b"\xE9";
| ^^^^
error: raw byte string must be ASCII
--> $DIR/byte-string-literals.rs:7:10

View File

@ -13,13 +13,12 @@ LL | | _ => cx.answer_str("hi"),
| | ^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type
LL | | }
| |_____- `match` arms have incompatible types
|
::: $DIR/auxiliary/issue-81839.rs:6:49
|
LL | pub async fn answer_str(&self, _s: &str) -> Test {
| ---- checked the `Output` of this `async fn`, found opaque type
note: while checking the return type of the `async fn`
--> $DIR/auxiliary/issue-81839.rs:6:49
|
= note: while checking the return type of the `async fn`
LL | pub async fn answer_str(&self, _s: &str) -> Test {
| ^^^^ checked the `Output` of this `async fn`, found opaque type
= note: expected type `()`
found opaque type `impl Future`

View File

@ -14,8 +14,14 @@ fn extra_semicolon() {
}
async fn async_dummy() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type
//~| NOTE while checking the return type of the `async fn`
//~| NOTE in this expansion of desugaring of `async` block or function
async fn async_dummy2() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type
//~| NOTE checked the `Output` of this `async fn`, found opaque type
//~| NOTE while checking the return type of the `async fn`
//~| NOTE in this expansion of desugaring of `async` block or function
//~| NOTE while checking the return type of the `async fn`
//~| NOTE in this expansion of desugaring of `async` block or function
async fn async_extra_semicolon_same() {
let _ = match true { //~ NOTE `match` arms have incompatible types
@ -26,7 +32,6 @@ async fn async_extra_semicolon_same() {
false => async_dummy(), //~ ERROR `match` arms have incompatible types
//~^ NOTE expected `()`, found opaque type
//~| NOTE expected type `()`
//~| NOTE while checking the return type of the `async fn`
//~| HELP consider `await`ing on the `Future`
};
}
@ -40,7 +45,6 @@ async fn async_extra_semicolon_different() {
false => async_dummy2(), //~ ERROR `match` arms have incompatible types
//~^ NOTE expected `()`, found opaque type
//~| NOTE expected type `()`
//~| NOTE while checking the return type of the `async fn`
//~| HELP consider `await`ing on the `Future`
};
}
@ -53,7 +57,6 @@ async fn async_different_futures() {
//~^ NOTE expected opaque type, found a different opaque type
//~| NOTE expected type `impl Future`
//~| NOTE distinct uses of `impl Trait` result in different opaque types
//~| NOTE while checking the return type of the `async fn`
};
}

View File

@ -1,9 +1,6 @@
error[E0308]: `match` arms have incompatible types
--> $DIR/match-prev-arm-needing-semi.rs:26:18
--> $DIR/match-prev-arm-needing-semi.rs:32:18
|
LL | async fn async_dummy() {}
| - checked the `Output` of this `async fn`, found opaque type
...
LL | let _ = match true {
| _____________-
LL | | true => {
@ -18,7 +15,11 @@ LL | |
LL | | };
| |_____- `match` arms have incompatible types
|
= note: while checking the return type of the `async fn`
note: while checking the return type of the `async fn`
--> $DIR/match-prev-arm-needing-semi.rs:16:24
|
LL | async fn async_dummy() {}
| ^ checked the `Output` of this `async fn`, found opaque type
= note: expected type `()`
found opaque type `impl Future`
help: consider `await`ing on the `Future`
@ -31,11 +32,8 @@ LL | async_dummy()
| --
error[E0308]: `match` arms have incompatible types
--> $DIR/match-prev-arm-needing-semi.rs:40:18
--> $DIR/match-prev-arm-needing-semi.rs:45:18
|
LL | async fn async_dummy2() {}
| - checked the `Output` of this `async fn`, found opaque type
...
LL | let _ = match true {
| _____________-
LL | | true => {
@ -50,7 +48,11 @@ LL | |
LL | | };
| |_____- `match` arms have incompatible types
|
= note: while checking the return type of the `async fn`
note: while checking the return type of the `async fn`
--> $DIR/match-prev-arm-needing-semi.rs:19:25
|
LL | async fn async_dummy2() {}
| ^ checked the `Output` of this `async fn`, found opaque type
= note: expected type `()`
found opaque type `impl Future`
help: consider `await`ing on the `Future`
@ -66,11 +68,8 @@ LL | false => Box::new(async_dummy2()),
|
error[E0308]: `match` arms have incompatible types
--> $DIR/match-prev-arm-needing-semi.rs:52:18
--> $DIR/match-prev-arm-needing-semi.rs:56:18
|
LL | async fn async_dummy2() {}
| - checked the `Output` of this `async fn`, found opaque type
...
LL | let _ = match true {
| _____________-
LL | | true => async_dummy(),
@ -83,9 +82,13 @@ LL | |
LL | | };
| |_____- `match` arms have incompatible types
|
= note: while checking the return type of the `async fn`
note: while checking the return type of the `async fn`
--> $DIR/match-prev-arm-needing-semi.rs:19:25
|
LL | async fn async_dummy2() {}
| ^ checked the `Output` of this `async fn`, found opaque type
= note: expected type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>)
found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:17:25>)
found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:19:25>)
= note: distinct uses of `impl Trait` result in different opaque types
help: consider `await`ing on both `Future`s
|

View File

@ -0,0 +1,18 @@
// Regression test for #87397.
fn main() {
b'µ';
//~^ ERROR: non-ASCII character in byte constant
//~| HELP: if you meant to use the unicode code point for 'µ', use a \xHH escape
//~| NOTE: byte constant must be ASCII
b'字';
//~^ ERROR: non-ASCII character in byte constant
//~| NOTE: this multibyte character does not fit into a single byte
//~| NOTE: byte constant must be ASCII
b"";
//~^ ERROR: non-ASCII character in byte constant
//~| HELP: if you meant to use the UTF-8 encoding of '字', use \xHH escapes
//~| NOTE: byte constant must be ASCII
}

View File

@ -0,0 +1,33 @@
error: non-ASCII character in byte constant
--> $DIR/multibyte-escapes.rs:4:7
|
LL | b'µ';
| ^ byte constant must be ASCII
|
help: if you meant to use the unicode code point for 'µ', use a \xHH escape
|
LL | b'\xB5';
| ^^^^
error: non-ASCII character in byte constant
--> $DIR/multibyte-escapes.rs:9:7
|
LL | b'字';
| ^^
| |
| byte constant must be ASCII
| this multibyte character does not fit into a single byte
error: non-ASCII character in byte constant
--> $DIR/multibyte-escapes.rs:14:7
|
LL | b"字";
| ^^ byte constant must be ASCII
|
help: if you meant to use the UTF-8 encoding of '字', use \xHH escapes
|
LL | b"\xE5\xAD\x97";
| ^^^^^^^^^^^^
error: aborting due to 3 previous errors