Auto merge of #112805 - matthiaskrgr:rollup-r5yrefu, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #109970 ([doc] `poll_fn`: explain how to `pin` captured state safely) - #112705 (Simplify `Span::source_callee` impl) - #112757 (Use BorrowFlag instead of explicit isize) - #112768 (Rewrite various resolve/diagnostics errors as translatable diagnostics) - #112777 (Continue folding in query normalizer on weak aliases) - #112780 (Treat TAIT equation as always ambiguous in coherence) - #112783 (Don't ICE on bound var in `reject_fn_ptr_impls`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
fe7454bf43
@ -124,13 +124,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
}
|
||||
|
||||
// During coherence, opaque types should be treated as *possibly*
|
||||
// equal to each other, even if their generic params differ, as
|
||||
// they could resolve to the same hidden type, even for different
|
||||
// generic params.
|
||||
(
|
||||
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
|
||||
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
|
||||
) if self.intercrate && a_def_id == b_def_id => {
|
||||
// equal to any other type (except for possibly itself). This is an
|
||||
// extremely heavy hammer, but can be relaxed in a fowards-compatible
|
||||
// way later.
|
||||
(&ty::Alias(ty::Opaque, _), _) | (_, &ty::Alias(ty::Opaque, _)) if self.intercrate => {
|
||||
relation.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]);
|
||||
Ok(a)
|
||||
}
|
||||
|
@ -5,6 +5,9 @@ resolve_add_as_non_derive =
|
||||
add as non-Derive macro
|
||||
`#[{$macro_path}]`
|
||||
|
||||
resolve_added_macro_use =
|
||||
have you added the `#[macro_use]` on the module/import?
|
||||
|
||||
resolve_ampersand_used_without_explicit_lifetime_name =
|
||||
`&` without an explicit lifetime name cannot be used here
|
||||
.note = explicit lifetime name needed here
|
||||
@ -45,9 +48,18 @@ resolve_cannot_capture_dynamic_environment_in_fn_item =
|
||||
can't capture dynamic environment in a fn item
|
||||
.help = use the `|| {"{"} ... {"}"}` closure form instead
|
||||
|
||||
resolve_cannot_find_ident_in_this_scope =
|
||||
cannot find {$expected} `{$ident}` in this scope
|
||||
|
||||
resolve_cannot_use_self_type_here =
|
||||
can't use `Self` here
|
||||
|
||||
resolve_change_import_binding =
|
||||
you can use `as` to change the binding name of the import
|
||||
|
||||
resolve_consider_adding_a_derive =
|
||||
consider adding a derive
|
||||
|
||||
resolve_const_not_member_of_trait =
|
||||
const `{$const_}` is not a member of trait `{$trait_}`
|
||||
.label = not a member of trait `{$trait_}`
|
||||
@ -74,6 +86,9 @@ resolve_expected_found =
|
||||
expected module, found {$res} `{$path_str}`
|
||||
.label = not a module
|
||||
|
||||
resolve_explicit_unsafe_traits =
|
||||
unsafe traits like `{$ident}` should be implemented explicitly
|
||||
|
||||
resolve_forward_declared_generic_param =
|
||||
generic parameters with a default cannot use forward declared identifiers
|
||||
.label = defaulted generic parameters cannot be forward declared
|
||||
@ -96,6 +111,9 @@ resolve_ident_bound_more_than_once_in_same_pattern =
|
||||
|
||||
resolve_imported_crate = `$crate` may not be imported
|
||||
|
||||
resolve_imports_cannot_refer_to =
|
||||
imports cannot refer to {$what}
|
||||
|
||||
resolve_indeterminate =
|
||||
cannot determine resolution for the visibility
|
||||
|
||||
|
@ -30,6 +30,10 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, Span, SyntaxContext};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::errors::{
|
||||
AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion, ConsiderAddingADerive,
|
||||
ExplicitUnsafeTraits,
|
||||
};
|
||||
use crate::imports::{Import, ImportKind};
|
||||
use crate::late::{PatternSource, Rib};
|
||||
use crate::path_names_to_string;
|
||||
@ -376,16 +380,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
let rename_msg = "you can use `as` to change the binding name of the import";
|
||||
if let Some(suggestion) = suggestion {
|
||||
err.span_suggestion(
|
||||
binding_span,
|
||||
rename_msg,
|
||||
suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.subdiagnostic(ChangeImportBindingSuggestion { span: binding_span, suggestion });
|
||||
} else {
|
||||
err.span_label(binding_span, rename_msg);
|
||||
err.subdiagnostic(ChangeImportBinding { span: binding_span });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1382,12 +1380,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
);
|
||||
|
||||
if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
|
||||
let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident);
|
||||
err.span_note(ident.span, msg);
|
||||
err.subdiagnostic(ExplicitUnsafeTraits { span: ident.span, ident });
|
||||
return;
|
||||
}
|
||||
if self.macro_names.contains(&ident.normalize_to_macros_2_0()) {
|
||||
err.help("have you added the `#[macro_use]` on the module/import?");
|
||||
err.subdiagnostic(AddedMacroUse);
|
||||
return;
|
||||
}
|
||||
if ident.name == kw::Default
|
||||
@ -1396,14 +1393,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
let span = self.def_span(def_id);
|
||||
let source_map = self.tcx.sess.source_map();
|
||||
let head_span = source_map.guess_head_span(span);
|
||||
if let Ok(head) = source_map.span_to_snippet(head_span) {
|
||||
err.span_suggestion(head_span, "consider adding a derive", format!("#[derive(Default)]\n{head}"), Applicability::MaybeIncorrect);
|
||||
} else {
|
||||
err.span_help(
|
||||
head_span,
|
||||
"consider adding `#[derive(Default)]` to this enum",
|
||||
);
|
||||
}
|
||||
err.subdiagnostic(ConsiderAddingADerive {
|
||||
span: head_span.shrink_to_lo(),
|
||||
suggestion: format!("#[derive(Default)]\n")
|
||||
});
|
||||
}
|
||||
for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] {
|
||||
if let Ok(binding) = self.early_resolve_ident_in_lexical_scope(
|
||||
|
@ -586,3 +586,63 @@ pub(crate) enum ParamKindInEnumDiscriminant {
|
||||
#[note(resolve_lifetime_param_in_enum_discriminant)]
|
||||
Lifetime,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(resolve_change_import_binding)]
|
||||
pub(crate) struct ChangeImportBinding {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
resolve_change_import_binding,
|
||||
code = "{suggestion}",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct ChangeImportBindingSuggestion {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) suggestion: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_imports_cannot_refer_to)]
|
||||
pub(crate) struct ImportsCannotReferTo<'a> {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) what: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_cannot_find_ident_in_this_scope)]
|
||||
pub(crate) struct CannotFindIdentInThisScope<'a> {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) expected: &'a str,
|
||||
pub(crate) ident: Ident,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[note(resolve_explicit_unsafe_traits)]
|
||||
pub(crate) struct ExplicitUnsafeTraits {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) ident: Ident,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[help(resolve_added_macro_use)]
|
||||
pub(crate) struct AddedMacroUse;
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
resolve_consider_adding_a_derive,
|
||||
code = "{suggestion}",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct ConsiderAddingADerive {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) suggestion: String,
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
//! If you wonder why there's no `early.rs`, that's because it's split into three files -
|
||||
//! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`.
|
||||
|
||||
use crate::errors::ImportsCannotReferTo;
|
||||
use crate::BindingKey;
|
||||
use crate::{path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding};
|
||||
use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
|
||||
@ -2244,12 +2245,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
_ => &[TypeNS],
|
||||
};
|
||||
let report_error = |this: &Self, ns| {
|
||||
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
|
||||
if this.should_report_errs() {
|
||||
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
|
||||
this.r
|
||||
.tcx
|
||||
.sess
|
||||
.span_err(ident.span, format!("imports cannot refer to {}", what));
|
||||
.create_err(ImportsCannotReferTo { span: ident.span, what })
|
||||
.emit();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
//! A bunch of methods and structures more or less related to resolving macros and
|
||||
//! interface provided by `Resolver` to macro expander.
|
||||
|
||||
use crate::errors::{self, AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive};
|
||||
use crate::errors::{
|
||||
self, AddAsNonDerive, CannotFindIdentInThisScope, MacroExpectedFound, RemoveSurroundingDerive,
|
||||
};
|
||||
use crate::Namespace::*;
|
||||
use crate::{BuiltinMacroState, Determinacy};
|
||||
use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
|
||||
@ -793,8 +795,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
Err(..) => {
|
||||
let expected = kind.descr_expected();
|
||||
let msg = format!("cannot find {} `{}` in this scope", expected, ident);
|
||||
let mut err = self.tcx.sess.struct_span_err(ident.span, msg);
|
||||
|
||||
let mut err = self.tcx.sess.create_err(CannotFindIdentInThisScope {
|
||||
span: ident.span,
|
||||
expected,
|
||||
ident,
|
||||
});
|
||||
|
||||
self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident, krate);
|
||||
err.emit();
|
||||
}
|
||||
|
@ -65,11 +65,11 @@ use rustc_data_structures::sync::{Lock, Lrc};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::{self, Ordering};
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
use std::ops::{Add, Range, Sub};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::{fmt, iter};
|
||||
|
||||
use md5::Digest;
|
||||
use md5::Md5;
|
||||
@ -733,12 +733,15 @@ impl Span {
|
||||
/// else returns the `ExpnData` for the macro definition
|
||||
/// corresponding to the source callsite.
|
||||
pub fn source_callee(self) -> Option<ExpnData> {
|
||||
fn source_callee(expn_data: ExpnData) -> ExpnData {
|
||||
let next_expn_data = expn_data.call_site.ctxt().outer_expn_data();
|
||||
if !next_expn_data.is_root() { source_callee(next_expn_data) } else { expn_data }
|
||||
}
|
||||
let expn_data = self.ctxt().outer_expn_data();
|
||||
if !expn_data.is_root() { Some(source_callee(expn_data)) } else { None }
|
||||
|
||||
// Create an iterator of call site expansions
|
||||
iter::successors(Some(expn_data), |expn_data| {
|
||||
Some(expn_data.call_site.ctxt().outer_expn_data())
|
||||
})
|
||||
// Find the last expansion which is not root
|
||||
.take_while(|expn_data| !expn_data.is_root())
|
||||
.last()
|
||||
}
|
||||
|
||||
/// Checks if a span is "internal" to a macro in which `#[unstable]`
|
||||
@ -777,7 +780,7 @@ impl Span {
|
||||
|
||||
pub fn macro_backtrace(mut self) -> impl Iterator<Item = ExpnData> {
|
||||
let mut prev_span = DUMMY_SP;
|
||||
std::iter::from_fn(move || {
|
||||
iter::from_fn(move || {
|
||||
loop {
|
||||
let expn_data = self.ctxt().outer_expn_data();
|
||||
if expn_data.is_root() {
|
||||
|
@ -322,8 +322,12 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
|
||||
};
|
||||
// `tcx.normalize_projection_ty` may normalize to a type that still has
|
||||
// unevaluated consts, so keep normalizing here if that's the case.
|
||||
if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
|
||||
res.try_super_fold_with(self)?
|
||||
// Similarly, `tcx.normalize_weak_ty` will only unwrap one layer of type
|
||||
// and we need to continue folding it to reveal the TAIT behind it.
|
||||
if res != ty
|
||||
&& (res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) || kind == ty::Weak)
|
||||
{
|
||||
res.try_fold_with(self)?
|
||||
} else {
|
||||
res
|
||||
}
|
||||
|
@ -417,17 +417,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// Fast path to avoid evaluating an obligation that trivially holds.
|
||||
// There may be more bounds, but these are checked by the regular path.
|
||||
ty::FnPtr(..) => return false,
|
||||
|
||||
// These may potentially implement `FnPtr`
|
||||
ty::Placeholder(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Alias(_, _)
|
||||
| ty::Infer(_)
|
||||
| ty::Param(..) => {}
|
||||
| ty::Param(..)
|
||||
| ty::Bound(_, _) => {}
|
||||
|
||||
ty::Bound(_, _) => span_bug!(
|
||||
obligation.cause.span(),
|
||||
"cannot have escaping bound var in self type of {obligation:#?}"
|
||||
),
|
||||
// These can't possibly implement `FnPtr` as they are concrete types
|
||||
// and not `FnPtr`
|
||||
ty::Bool
|
||||
|
@ -1374,7 +1374,7 @@ impl Clone for BorrowRef<'_> {
|
||||
debug_assert!(is_reading(borrow));
|
||||
// Prevent the borrow counter from overflowing into
|
||||
// a writing borrow.
|
||||
assert!(borrow != isize::MAX);
|
||||
assert!(borrow != BorrowFlag::MAX);
|
||||
self.borrow.set(borrow + 1);
|
||||
BorrowRef { borrow: self.borrow }
|
||||
}
|
||||
@ -1756,7 +1756,7 @@ impl<'b> BorrowRefMut<'b> {
|
||||
let borrow = self.borrow.get();
|
||||
debug_assert!(is_writing(borrow));
|
||||
// Prevent the borrow counter from underflowing.
|
||||
assert!(borrow != isize::MIN);
|
||||
assert!(borrow != BorrowFlag::MIN);
|
||||
self.borrow.set(borrow - 1);
|
||||
BorrowRefMut { borrow: self.borrow }
|
||||
}
|
||||
|
@ -24,6 +24,93 @@ use crate::task::{Context, Poll};
|
||||
/// assert_eq!(read_future.await, "Hello, World!".to_owned());
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// ## Capturing a pinned state
|
||||
///
|
||||
/// Example of a closure wrapping inner futures:
|
||||
///
|
||||
/// ```
|
||||
/// # async fn run() {
|
||||
/// use core::future::{self, Future};
|
||||
/// use core::task::Poll;
|
||||
///
|
||||
/// /// Resolves to the first future that completes. In the event of a tie, `a` wins.
|
||||
/// fn naive_select<T>(
|
||||
/// a: impl Future<Output = T>,
|
||||
/// b: impl Future<Output = T>,
|
||||
/// ) -> impl Future<Output = T>
|
||||
/// {
|
||||
/// let (mut a, mut b) = (Box::pin(a), Box::pin(b));
|
||||
/// future::poll_fn(move |cx| {
|
||||
/// if let Poll::Ready(r) = a.as_mut().poll(cx) {
|
||||
/// Poll::Ready(r)
|
||||
/// } else if let Poll::Ready(r) = b.as_mut().poll(cx) {
|
||||
/// Poll::Ready(r)
|
||||
/// } else {
|
||||
/// Poll::Pending
|
||||
/// }
|
||||
/// })
|
||||
/// }
|
||||
///
|
||||
/// let a = async { 42 };
|
||||
/// let b = future::pending();
|
||||
/// let v = naive_select(a, b).await;
|
||||
/// assert_eq!(v, 42);
|
||||
///
|
||||
/// let a = future::pending();
|
||||
/// let b = async { 27 };
|
||||
/// let v = naive_select(a, b).await;
|
||||
/// assert_eq!(v, 27);
|
||||
///
|
||||
/// let a = async { 42 };
|
||||
/// let b = async { 27 };
|
||||
/// let v = naive_select(a, b).await;
|
||||
/// assert_eq!(v, 42); // biased towards `a` in case of tie!
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// This time without [`Box::pin`]ning:
|
||||
///
|
||||
/// [`Box::pin`]: ../../std/boxed/struct.Box.html#method.pin
|
||||
///
|
||||
/// ```
|
||||
/// # async fn run() {
|
||||
/// use core::future::{self, Future};
|
||||
/// use core::pin::pin;
|
||||
/// use core::task::Poll;
|
||||
///
|
||||
/// /// Resolves to the first future that completes. In the event of a tie, `a` wins.
|
||||
/// fn naive_select<T>(
|
||||
/// a: impl Future<Output = T>,
|
||||
/// b: impl Future<Output = T>,
|
||||
/// ) -> impl Future<Output = T>
|
||||
/// {
|
||||
/// async {
|
||||
/// let (mut a, mut b) = (pin!(a), pin!(b));
|
||||
/// future::poll_fn(move |cx| {
|
||||
/// if let Poll::Ready(r) = a.as_mut().poll(cx) {
|
||||
/// Poll::Ready(r)
|
||||
/// } else if let Poll::Ready(r) = b.as_mut().poll(cx) {
|
||||
/// Poll::Ready(r)
|
||||
/// } else {
|
||||
/// Poll::Pending
|
||||
/// }
|
||||
/// }).await
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let a = async { 42 };
|
||||
/// let b = future::pending();
|
||||
/// let v = naive_select(a, b).await;
|
||||
/// assert_eq!(v, 42);
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// - Notice how, by virtue of being in an `async` context, we have been able to make the [`pin!`]
|
||||
/// macro work, thereby avoiding any need for the `unsafe`
|
||||
/// <code>[Pin::new_unchecked](&mut fut)</code> constructor.
|
||||
///
|
||||
/// [`pin!`]: crate::pin::pin!
|
||||
#[stable(feature = "future_poll_fn", since = "1.64.0")]
|
||||
pub fn poll_fn<T, F>(f: F) -> PollFn<F>
|
||||
where
|
||||
|
@ -32,10 +32,4 @@ impl Into<u8> for ContainsVal {
|
||||
}
|
||||
}
|
||||
|
||||
type Opaque = impl Sized;
|
||||
struct IntoOpaque;
|
||||
impl Into<Opaque> for IntoOpaque {
|
||||
fn into(self) -> Opaque {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,12 +1,29 @@
|
||||
error[E0658]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/from_over_into_unfixable.rs:35:15
|
||||
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
|
||||
--> $DIR/from_over_into_unfixable.rs:11:1
|
||||
|
|
||||
LL | type Opaque = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
LL | impl Into<InMacro> for String {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
|
||||
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
|
||||
= help: replace the `Into` implementation with `From<std::string::String>`
|
||||
= note: `-D clippy::from-over-into` implied by `-D warnings`
|
||||
|
||||
error: aborting due to previous error
|
||||
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
|
||||
--> $DIR/from_over_into_unfixable.rs:19:1
|
||||
|
|
||||
LL | impl Into<WeirdUpperSelf> for &'static [u8] {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: replace the `Into` implementation with `From<&'static [u8]>`
|
||||
|
||||
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
|
||||
--> $DIR/from_over_into_unfixable.rs:28:1
|
||||
|
|
||||
LL | impl Into<u8> for ContainsVal {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see
|
||||
https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence
|
||||
= help: replace the `Into` implementation with `From<ContainsVal>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -7,7 +7,7 @@ LL | #[default]
|
||||
help: consider adding a derive
|
||||
|
|
||||
LL + #[derive(Default)]
|
||||
LL ~ pub enum Test {
|
||||
LL | pub enum Test {
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -0,0 +1,13 @@
|
||||
error[E0119]: conflicting implementations of trait `Into<T>` for type `Foo`
|
||||
--> $DIR/coherence-treats-tait-ambig.rs:10:1
|
||||
|
|
||||
LL | impl Into<T> for Foo {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: conflicting implementation in crate `core`:
|
||||
- impl<T, U> Into<U> for T
|
||||
where U: From<T>;
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
13
tests/ui/impl-trait/coherence-treats-tait-ambig.next.stderr
Normal file
13
tests/ui/impl-trait/coherence-treats-tait-ambig.next.stderr
Normal file
@ -0,0 +1,13 @@
|
||||
error[E0119]: conflicting implementations of trait `Into<T>` for type `Foo`
|
||||
--> $DIR/coherence-treats-tait-ambig.rs:10:1
|
||||
|
|
||||
LL | impl Into<T> for Foo {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: conflicting implementation in crate `core`:
|
||||
- impl<T, U> Into<U> for T
|
||||
where U: From<T>;
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
19
tests/ui/impl-trait/coherence-treats-tait-ambig.rs
Normal file
19
tests/ui/impl-trait/coherence-treats-tait-ambig.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// revisions: current next
|
||||
//[next] compile-flags: -Ztrait-solver=next
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type T = impl Sized;
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Into<T> for Foo {
|
||||
//~^ ERROR conflicting implementations of trait `Into<T>` for type `Foo`
|
||||
fn into(self) -> T {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: T = Foo.into();
|
||||
}
|
12
tests/ui/traits/non_lifetime_binders/foreach-partial-eq.rs
Normal file
12
tests/ui/traits/non_lifetime_binders/foreach-partial-eq.rs
Normal file
@ -0,0 +1,12 @@
|
||||
#![feature(non_lifetime_binders)]
|
||||
//~^ WARN the feature `non_lifetime_binders` is incomplete
|
||||
|
||||
fn auto_trait()
|
||||
where
|
||||
for<T> T: PartialEq + PartialOrd,
|
||||
{}
|
||||
|
||||
fn main() {
|
||||
auto_trait();
|
||||
//~^ ERROR can't compare `T` with `T`
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/foreach-partial-eq.rs:1:12
|
||||
|
|
||||
LL | #![feature(non_lifetime_binders)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error[E0277]: can't compare `T` with `T`
|
||||
--> $DIR/foreach-partial-eq.rs:10:5
|
||||
|
|
||||
LL | auto_trait();
|
||||
| ^^^^^^^^^^ no implementation for `T < T` and `T > T`
|
||||
|
|
||||
= help: the trait `PartialOrd` is not implemented for `T`
|
||||
note: required by a bound in `auto_trait`
|
||||
--> $DIR/foreach-partial-eq.rs:6:27
|
||||
|
|
||||
LL | fn auto_trait()
|
||||
| ---------- required by a bound in this function
|
||||
LL | where
|
||||
LL | for<T> T: PartialEq + PartialOrd,
|
||||
| ^^^^^^^^^^ required by this bound in `auto_trait`
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
12
tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs
Normal file
12
tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// compile-flags: --crate-type=lib -Cdebuginfo=2
|
||||
// build-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Debuggable = impl core::fmt::Debug;
|
||||
|
||||
static mut TEST: Option<Debuggable> = None;
|
||||
|
||||
fn foo() -> Debuggable {
|
||||
0u32
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user