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:
commit
6be8a06bcf
@ -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(
|
||||
|
@ -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
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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());
|
||||
|
@ -554,6 +554,7 @@ symbols! {
|
||||
expected,
|
||||
expf32,
|
||||
expf64,
|
||||
explicit_generic_args_with_impl_trait,
|
||||
export_name,
|
||||
expr,
|
||||
extended_key_value_attributes,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
///
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
```
|
@ -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`
|
||||
|
@ -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
|
||||
|
@ -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`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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`
|
||||
|
@ -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`
|
||||
|
@ -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`
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
@ -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`.
|
@ -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());
|
||||
}
|
@ -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
|
||||
}
|
@ -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`.
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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`
|
||||
|
||||
|
@ -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`
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
|
18
src/test/ui/suggestions/multibyte-escapes.rs
Normal file
18
src/test/ui/suggestions/multibyte-escapes.rs
Normal 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
|
||||
}
|
33
src/test/ui/suggestions/multibyte-escapes.stderr
Normal file
33
src/test/ui/suggestions/multibyte-escapes.stderr
Normal 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user