diff --git a/Cargo.lock b/Cargo.lock index 7a6e88f0b8b00..1dfe710eceec5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4405,6 +4405,7 @@ dependencies = [ "rustc_hir_pretty", "rustc_index", "rustc_infer", + "rustc_lint", "rustc_macros", "rustc_middle", "rustc_session", diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 2e8022d9880b2..6d5f47aceeb91 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -635,7 +635,7 @@ pub macro which_arena_for_type { } #[rustc_macro_transparency = "semitransparent"] -pub macro declare_arena([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { +pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { #[derive(Default)] pub struct Arena<$tcx> { pub dropless: $crate::DroplessArena, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b71fcb7a349cc..0133acfee1008 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -84,7 +84,7 @@ mod path; const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF; -rustc_hir::arena_types!(rustc_arena::declare_arena, [], 'tcx); +rustc_hir::arena_types!(rustc_arena::declare_arena, 'tcx); struct LoweringContext<'a, 'hir: 'a> { /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes. diff --git a/compiler/rustc_data_structures/src/functor.rs b/compiler/rustc_data_structures/src/functor.rs index fe7a256d2100f..5b83ae3124766 100644 --- a/compiler/rustc_data_structures/src/functor.rs +++ b/compiler/rustc_data_structures/src/functor.rs @@ -26,7 +26,7 @@ impl IdFunctor for Box { // inverse of `Box::assume_init()` and should be safe. let mut raw: Box> = Box::from_raw(raw.cast()); // SAFETY: Write the mapped value back into the `Box`. - ptr::write(raw.as_mut_ptr(), f(value)); + raw.write(f(value)); // SAFETY: We just initialized `raw`. raw.assume_init() } diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 0801a1bde2264..3e8b98e9f5493 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -9,8 +9,8 @@ /// where `T` is the type listed. These impls will appear in the implement_ty_decoder! macro. #[macro_export] macro_rules! arena_types { - ($macro:path, $args:tt, $tcx:lifetime) => ( - $macro!($args, [ + ($macro:path, $tcx:lifetime) => ( + $macro!([ // HIR types [few] hir_krate: rustc_hir::Crate<$tcx>, [] arm: rustc_hir::Arm<$tcx>, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 24ac723f2c913..ef4bda666ba06 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -62,6 +62,8 @@ mod traits; mod types; mod unused; +pub use array_into_iter::ARRAY_INTO_ITER; + use rustc_ast as ast; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index a89d00e26ac19..59db2c6636ff9 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -9,8 +9,8 @@ /// listed. These impls will appear in the implement_ty_decoder! macro. #[macro_export] macro_rules! arena_types { - ($macro:path, $args:tt, $tcx:lifetime) => ( - $macro!($args, [ + ($macro:path, $tcx:lifetime) => ( + $macro!([ [] layouts: rustc_target::abi::Layout, // AdtDef are interned and compared by address [] adt_def: rustc_middle::ty::AdtDef, @@ -109,4 +109,4 @@ macro_rules! arena_types { ) } -arena_types!(rustc_arena::declare_arena, [], 'tcx); +arena_types!(rustc_arena::declare_arena, 'tcx); diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 36db258e92d20..4edb6a327b035 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -437,15 +437,15 @@ macro_rules! impl_arena_allocatable_decoder { } macro_rules! impl_arena_allocatable_decoders { - ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { + ([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { $( impl_arena_allocatable_decoder!($a [[$name: $ty], $tcx]); )* } } -rustc_hir::arena_types!(impl_arena_allocatable_decoders, [], 'tcx); -arena_types!(impl_arena_allocatable_decoders, [], 'tcx); +rustc_hir::arena_types!(impl_arena_allocatable_decoders, 'tcx); +arena_types!(impl_arena_allocatable_decoders, 'tcx); #[macro_export] macro_rules! implement_ty_decoder { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e71edbc861ad9..a1d3e9adba013 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -41,7 +41,7 @@ macro_rules! maybe_whole_expr { let path = path.clone(); $p.bump(); return Ok($p.mk_expr( - $p.token.span, + $p.prev_token.span, ExprKind::Path(None, path), AttrVec::new(), )); @@ -50,7 +50,7 @@ macro_rules! maybe_whole_expr { let block = block.clone(); $p.bump(); return Ok($p.mk_expr( - $p.token.span, + $p.prev_token.span, ExprKind::Block(block, None), AttrVec::new(), )); diff --git a/compiler/rustc_typeck/Cargo.toml b/compiler/rustc_typeck/Cargo.toml index fa5ef63f5c52e..dd76a5e4b99b2 100644 --- a/compiler/rustc_typeck/Cargo.toml +++ b/compiler/rustc_typeck/Cargo.toml @@ -26,3 +26,4 @@ rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_ty_utils = { path = "../rustc_ty_utils" } +rustc_lint = { path = "../rustc_lint" } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 25d1c8706e874..17e0c42440c21 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -914,7 +914,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); if result.is_ok() { - self.maybe_lint_bare_trait(qpath, hir_id); + self.maybe_lint_bare_trait(qpath, hir_id, span); self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None)); } @@ -927,7 +927,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } - fn maybe_lint_bare_trait(&self, qpath: &QPath<'_>, hir_id: hir::HirId) { + fn maybe_lint_bare_trait(&self, qpath: &QPath<'_>, hir_id: hir::HirId, span: Span) { if let QPath::TypeRelative(self_ty, _) = qpath { if let TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) = self_ty.kind @@ -935,10 +935,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let msg = "trait objects without an explicit `dyn` are deprecated"; let (sugg, app) = match self.tcx.sess.source_map().span_to_snippet(self_ty.span) { Ok(s) if poly_trait_ref.trait_ref.path.is_global() => { - (format!("", s), Applicability::MachineApplicable) + (format!("dyn ({})", s), Applicability::MachineApplicable) } - Ok(s) => (format!("", s), Applicability::MachineApplicable), - Err(_) => (">".to_string(), Applicability::HasPlaceholders), + Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable), + Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders), + }; + // Wrap in `<..>` if it isn't already. + let sugg = match self.tcx.sess.source_map().span_to_snippet(span) { + Ok(s) if s.starts_with('<') => sugg, + _ => format!("<{}>", sugg), }; let replace = String::from("use `dyn`"); if self.sess().edition() >= Edition::Edition2021 { diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index b5bc9d3599acb..1347f56258ea1 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -5,9 +5,9 @@ use rustc_ast::Mutability; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{Adt, Ref, Ty}; +use rustc_middle::ty::{Adt, Array, Ref, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; -use rustc_span::symbol::kw::Underscore; +use rustc_span::symbol::kw::{Empty, Underscore}; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_trait_selection::infer::InferCtxtExt; @@ -38,10 +38,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - // These are the method names that were added to prelude in Rust 2021 - if !matches!(segment.ident.name, sym::try_into) { - return; - } + let prelude_or_array_lint = match segment.ident.name { + // `try_into` was added to the prelude in Rust 2021. + sym::try_into => RUST_2021_PRELUDE_COLLISIONS, + // `into_iter` wasn't added to the prelude, + // but `[T; N].into_iter()` doesn't resolve to IntoIterator::into_iter + // before Rust 2021, which results in the same problem. + // It is only a problem for arrays. + sym::into_iter if let Array(..) = self_ty.kind() => { + // In this case, it wasn't really a prelude addition that was the problem. + // Instead, the problem is that the array-into_iter hack will no longer apply in Rust 2021. + rustc_lint::ARRAY_INTO_ITER + } + _ => return, + }; // No need to lint if method came from std/core, as that will now be in the prelude if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { @@ -69,7 +79,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Inherent impls only require not relying on autoref and autoderef in order to // ensure that the trait implementation won't be used self.tcx.struct_span_lint_hir( - RUST_2021_PRELUDE_COLLISIONS, + prelude_or_array_lint, self_expr.hir_id, self_expr.span, |lint| { @@ -130,7 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // trait implementations require full disambiguation to not clash with the new prelude // additions (i.e. convert from dot-call to fully-qualified call) self.tcx.struct_span_lint_hir( - RUST_2021_PRELUDE_COLLISIONS, + prelude_or_array_lint, call_expr.hir_id, call_expr.span, |lint| { @@ -239,47 +249,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_path = self.trait_path_or_bare_name(span, expr_id, pick.item.container.id()); let trait_generics = self.tcx.generics_of(pick.item.container.id()); - let parameter_count = trait_generics.count() - (trait_generics.has_self as usize); - let trait_name = if parameter_count == 0 { - trait_path - } else { - format!( - "{}<{}>", - trait_path, - std::iter::repeat("_").take(parameter_count).collect::>().join(", ") - ) - }; + let trait_name = + if trait_generics.params.len() <= trait_generics.has_self as usize { + trait_path + } else { + let counts = trait_generics.own_counts(); + format!( + "{}<{}>", + trait_path, + std::iter::repeat("'_") + .take(counts.lifetimes) + .chain(std::iter::repeat("_").take( + counts.types + counts.consts - trait_generics.has_self as usize + )) + .collect::>() + .join(", ") + ) + }; let mut lint = lint.build(&format!( "trait-associated function `{}` will become ambiguous in Rust 2021", method_name.name )); - let self_ty_name = self + let mut self_ty_name = self .sess() .source_map() .span_to_snippet(self_ty_span) .unwrap_or_else(|_| self_ty.to_string()); - let self_ty_generics_count = match self_ty.kind() { - // Get the number of generics the self type has (if an Adt) unless we can determine that - // the user has written the self type with generics already which we (naively) do by looking - // for a "<" in `self_ty_name`. - Adt(def, _) if !self_ty_name.contains('<') => self.tcx.generics_of(def.did).count(), - _ => 0, - }; - let self_ty_generics = if self_ty_generics_count > 0 { - format!("<{}>", vec!["_"; self_ty_generics_count].join(", ")) - } else { - String::new() - }; + // Get the number of generics the self type has (if an Adt) unless we can determine that + // the user has written the self type with generics already which we (naively) do by looking + // for a "<" in `self_ty_name`. + if !self_ty_name.contains('<') { + if let Adt(def, _) = self_ty.kind() { + let generics = self.tcx.generics_of(def.did); + if !generics.params.is_empty() { + let counts = generics.own_counts(); + self_ty_name += &format!( + "<{}>", + std::iter::repeat("'_") + .take(counts.lifetimes) + .chain(std::iter::repeat("_").take(counts.types + counts.consts)) + .collect::>() + .join(", ") + ); + } + } + } lint.span_suggestion( span, "disambiguate the associated function", - format!( - "<{}{} as {}>::{}", - self_ty_name, self_ty_generics, trait_name, method_name.name, - ), + format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), Applicability::MachineApplicable, ); @@ -322,7 +343,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .filter_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None }) .next(); if let Some(any_id) = any_id { - return Some(format!("{}", any_id)); + if any_id.name == Empty { + // Glob import, so just use its name. + return None; + } else { + return Some(format!("{}", any_id)); + } } // All that is left is `_`! We need to use the full path. It doesn't matter which one we pick, diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 2d8a1cb1ab016..35b740cd74372 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -2,14 +2,21 @@ //! Temporal quantification. //! -//! Example: +//! # Examples: +//! +//! There are multiple ways to create a new [`Duration`]: //! //! ``` -//! use std::time::Duration; +//! # use std::time::Duration; +//! let five_seconds = Duration::from_secs(5); +//! assert_eq!(five_seconds, Duration::from_millis(5_000)); +//! assert_eq!(five_seconds, Duration::from_micros(5_000_000)); +//! assert_eq!(five_seconds, Duration::from_nanos(5_000_000_000)); //! -//! let five_seconds = Duration::new(5, 0); -//! // both declarations are equivalent -//! assert_eq!(Duration::new(5, 0), Duration::from_secs(5)); +//! let ten_seconds = Duration::from_secs(10); +//! let seven_nanos = Duration::from_nanos(7); +//! let total = ten_seconds + seven_nanos; +//! assert_eq!(total, Duration::new(10, 7)); //! ``` use crate::fmt; diff --git a/library/std/src/env.rs b/library/std/src/env.rs index a746520095559..e343073d21508 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -616,6 +616,9 @@ pub fn temp_dir() -> PathBuf { /// return the path of the symbolic link and other platforms will return the /// path of the symbolic link’s target. /// +/// If the executable is renamed while it is running, platforms may return the +/// path at the time it was loaded instead of the new path. +/// /// # Errors /// /// Acquiring the path of the current executable is a platform-specific operation diff --git a/library/std/src/time.rs b/library/std/src/time.rs index ec105f231e5a7..e9207ee36171b 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -1,13 +1,32 @@ //! Temporal quantification. //! -//! Example: +//! # Examples: //! +//! There are multiple ways to create a new [`Duration`]: +//! +//! ``` +//! # use std::time::Duration; +//! let five_seconds = Duration::from_secs(5); +//! assert_eq!(five_seconds, Duration::from_millis(5_000)); +//! assert_eq!(five_seconds, Duration::from_micros(5_000_000)); +//! assert_eq!(five_seconds, Duration::from_nanos(5_000_000_000)); +//! +//! let ten_seconds = Duration::from_secs(10); +//! let seven_nanos = Duration::from_nanos(7); +//! let total = ten_seconds + seven_nanos; +//! assert_eq!(total, Duration::new(10, 7)); //! ``` -//! use std::time::Duration; //! -//! let five_seconds = Duration::new(5, 0); -//! // both declarations are equivalent -//! assert_eq!(Duration::new(5, 0), Duration::from_secs(5)); +//! Using [`Instant`] to calculate how long a function took to run: +//! +//! ```ignore (incomplete) +//! let now = Instant::now(); +//! +//! // Calling a slow function, it may take a while +//! slow_function(); +//! +//! let elapsed_time = now.elapsed(); +//! println!("Running slow_function() took {} seconds.", elapsed_time.as_secs()); //! ``` #![stable(feature = "time", since = "1.3.0")] @@ -26,7 +45,7 @@ use crate::sys_common::FromInner; pub use core::time::Duration; /// A measurement of a monotonically nondecreasing clock. -/// Opaque and useful only with `Duration`. +/// Opaque and useful only with [`Duration`]. /// /// Instants are always guaranteed to be no less than any previously measured /// instant when created, and are often useful for tasks such as measuring diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index fa29b54264948..0c81a55843013 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -9,7 +9,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::Mutability; -use rustc_metadata::creader::LoadedMacro; +use rustc_metadata::creader::{CStore, LoadedMacro}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; @@ -179,7 +179,7 @@ crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType) let fqn = if let ItemType::Macro = kind { // Check to see if it is a macro 2.0 or built-in macro if matches!( - cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())), + CStore::from_tcx(cx.tcx).load_macro_untracked(did, cx.sess()), LoadedMacro::MacroDef(def, _) if matches!(&def.kind, ast::ItemKind::MacroDef(ast_def) if !ast_def.macro_rules) @@ -558,7 +558,7 @@ fn build_macro( import_def_id: Option, ) -> clean::ItemKind { let imported_from = cx.tcx.crate_name(def_id.krate); - match cx.enter_resolver(|r| r.cstore().load_macro_untracked(def_id, cx.sess())) { + match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) { LoadedMacro::MacroDef(item_def, _) => { if let ast::ItemKind::MacroDef(ref def) = item_def.kind { clean::MacroItem(clean::Macro { diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed b/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed new file mode 100644 index 0000000000000..25caa6a8030ff --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed @@ -0,0 +1,23 @@ +// See https://github.com/rust-lang/rust/issues/88508 +// run-rustfix +// edition:2018 +#![deny(bare_trait_objects)] +#![allow(dead_code)] +#![allow(unused_imports)] + +use std::fmt; + +#[derive(Debug)] +pub struct Foo; + +impl fmt::Display for Foo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::fmt(self, f) + //~^ ERROR trait objects without an explicit `dyn` are deprecated + //~| WARNING this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated + //~| WARNING this is accepted in the current edition + } +} + +fn main() {} diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.rs b/src/test/ui/dyn-keyword/dyn-angle-brackets.rs new file mode 100644 index 0000000000000..cf72da2b61ec2 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.rs @@ -0,0 +1,23 @@ +// See https://github.com/rust-lang/rust/issues/88508 +// run-rustfix +// edition:2018 +#![deny(bare_trait_objects)] +#![allow(dead_code)] +#![allow(unused_imports)] + +use std::fmt; + +#[derive(Debug)] +pub struct Foo; + +impl fmt::Display for Foo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::fmt(self, f) + //~^ ERROR trait objects without an explicit `dyn` are deprecated + //~| WARNING this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated + //~| WARNING this is accepted in the current edition + } +} + +fn main() {} diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr new file mode 100644 index 0000000000000..ef0f5b7f59db9 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr @@ -0,0 +1,25 @@ +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-angle-brackets.rs:15:10 + | +LL | ::fmt(self, f) + | ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Debug` + | +note: the lint level is defined here + --> $DIR/dyn-angle-brackets.rs:4:9 + | +LL | #![deny(bare_trait_objects)] + | ^^^^^^^^^^^^^^^^^^ + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see + +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-angle-brackets.rs:15:10 + | +LL | ::fmt(self, f) + | ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Debug` + | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issue-87812-path.rs b/src/test/ui/parser/issue-87812-path.rs new file mode 100644 index 0000000000000..b88780876db06 --- /dev/null +++ b/src/test/ui/parser/issue-87812-path.rs @@ -0,0 +1,11 @@ +macro_rules! foo { + ( $f:path ) => {{ + let _: usize = $f; //~ERROR + }}; +} + +struct Baz; + +fn main() { + foo!(Baz); +} diff --git a/src/test/ui/parser/issue-87812-path.stderr b/src/test/ui/parser/issue-87812-path.stderr new file mode 100644 index 0000000000000..0c8e6fdd3076a --- /dev/null +++ b/src/test/ui/parser/issue-87812-path.stderr @@ -0,0 +1,16 @@ +error[E0308]: mismatched types + --> $DIR/issue-87812-path.rs:3:24 + | +LL | let _: usize = $f; + | ----- ^^ expected `usize`, found struct `Baz` + | | + | expected due to this +... +LL | foo!(Baz); + | ---------- in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issue-87812.rs b/src/test/ui/parser/issue-87812.rs new file mode 100644 index 0000000000000..0ba87b995443f --- /dev/null +++ b/src/test/ui/parser/issue-87812.rs @@ -0,0 +1,13 @@ +#![deny(break_with_label_and_loop)] + +macro_rules! foo { + ( $f:block ) => { + '_l: loop { + break '_l $f; //~ERROR + } + }; +} + +fn main() { + let x = foo!({ 3 }); +} diff --git a/src/test/ui/parser/issue-87812.stderr b/src/test/ui/parser/issue-87812.stderr new file mode 100644 index 0000000000000..d61ee23a50b5b --- /dev/null +++ b/src/test/ui/parser/issue-87812.stderr @@ -0,0 +1,22 @@ +error: this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression + --> $DIR/issue-87812.rs:6:13 + | +LL | break '_l $f; + | ^^^^^^^^^^^^ +... +LL | let x = foo!({ 3 }); + | ----------- in this macro invocation + | +note: the lint level is defined here + --> $DIR/issue-87812.rs:1:9 + | +LL | #![deny(break_with_label_and_loop)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) +help: wrap this expression in parentheses + | +LL | break '_l ($f); + | + + + +error: aborting due to previous error + diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.fixed b/src/test/ui/rust-2021/array-into-iter-ambiguous.fixed new file mode 100644 index 0000000000000..76f661baed750 --- /dev/null +++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.fixed @@ -0,0 +1,27 @@ +// See https://github.com/rust-lang/rust/issues/88475 +// run-rustfix +// edition:2018 +// check-pass +#![warn(array_into_iter)] +#![allow(unused)] + +struct FooIter; + +trait MyIntoIter { + fn into_iter(self) -> FooIter; +} + +impl MyIntoIter for [T; N] { + fn into_iter(self) -> FooIter { + FooIter + } +} + +struct Point; + +pub fn main() { + let points: [Point; 1] = [Point]; + let y = MyIntoIter::into_iter(points); + //~^ WARNING trait method `into_iter` will become ambiguous in Rust 2021 + //~| WARNING this changes meaning in Rust 2021 +} diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.rs b/src/test/ui/rust-2021/array-into-iter-ambiguous.rs new file mode 100644 index 0000000000000..83fbf8f6c218d --- /dev/null +++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.rs @@ -0,0 +1,27 @@ +// See https://github.com/rust-lang/rust/issues/88475 +// run-rustfix +// edition:2018 +// check-pass +#![warn(array_into_iter)] +#![allow(unused)] + +struct FooIter; + +trait MyIntoIter { + fn into_iter(self) -> FooIter; +} + +impl MyIntoIter for [T; N] { + fn into_iter(self) -> FooIter { + FooIter + } +} + +struct Point; + +pub fn main() { + let points: [Point; 1] = [Point]; + let y = points.into_iter(); + //~^ WARNING trait method `into_iter` will become ambiguous in Rust 2021 + //~| WARNING this changes meaning in Rust 2021 +} diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr b/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr new file mode 100644 index 0000000000000..fac8d21c7b48a --- /dev/null +++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr @@ -0,0 +1,16 @@ +warning: trait method `into_iter` will become ambiguous in Rust 2021 + --> $DIR/array-into-iter-ambiguous.rs:24:13 + | +LL | let y = points.into_iter(); + | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyIntoIter::into_iter(points)` + | +note: the lint level is defined here + --> $DIR/array-into-iter-ambiguous.rs:5:9 + | +LL | #![warn(array_into_iter)] + | ^^^^^^^^^^^^^^^ + = warning: this changes meaning in Rust 2021 + = note: for more information, see + +warning: 1 warning emitted + diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed new file mode 100644 index 0000000000000..a1b6f5b16baf8 --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed @@ -0,0 +1,30 @@ +// See https://github.com/rust-lang/rust/issues/88470 +// run-rustfix +// edition:2018 +// check-pass +#![warn(rust_2021_prelude_collisions)] +#![allow(dead_code)] +#![allow(unused_imports)] + +pub trait PyTryFrom<'v, T>: Sized { + fn try_from(value: V) -> Result<&'v Self, T>; +} + +pub trait PyTryInto: Sized { + fn try_into(&self) -> Result<&T, i32>; +} + +struct Foo; + +impl PyTryInto for Foo +where + U: for<'v> PyTryFrom<'v, i32>, +{ + fn try_into(&self) -> Result<&U, i32> { + >::try_from(self) + //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + //~| this is accepted in the current edition (Rust 2018) + } +} + +fn main() {} diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs new file mode 100644 index 0000000000000..142ba552002fc --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs @@ -0,0 +1,30 @@ +// See https://github.com/rust-lang/rust/issues/88470 +// run-rustfix +// edition:2018 +// check-pass +#![warn(rust_2021_prelude_collisions)] +#![allow(dead_code)] +#![allow(unused_imports)] + +pub trait PyTryFrom<'v, T>: Sized { + fn try_from(value: V) -> Result<&'v Self, T>; +} + +pub trait PyTryInto: Sized { + fn try_into(&self) -> Result<&T, i32>; +} + +struct Foo; + +impl PyTryInto for Foo +where + U: for<'v> PyTryFrom<'v, i32>, +{ + fn try_into(&self) -> Result<&U, i32> { + U::try_from(self) + //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + //~| this is accepted in the current edition (Rust 2018) + } +} + +fn main() {} diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr new file mode 100644 index 0000000000000..14ad9b017b694 --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr @@ -0,0 +1,16 @@ +warning: trait-associated function `try_from` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision-generic-trait.rs:24:9 + | +LL | U::try_from(self) + | ^^^^^^^^^^^ help: disambiguate the associated function: `>::try_from` + | +note: the lint level is defined here + --> $DIR/future-prelude-collision-generic-trait.rs:5:9 + | +LL | #![warn(rust_2021_prelude_collisions)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see + +warning: 1 warning emitted + diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.fixed b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed index f0d8cb944cf84..1bb9ba3777404 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-generic.fixed +++ b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed @@ -6,32 +6,32 @@ #![allow(dead_code)] #![allow(unused_imports)] -struct Generic(T, U); +struct Generic<'a, U>(&'a U); trait MyFromIter { fn from_iter(_: i32) -> Self; } -impl MyFromIter for Generic { - fn from_iter(x: i32) -> Self { - Self(x, x) +impl MyFromIter for Generic<'static, i32> { + fn from_iter(_: i32) -> Self { + todo!() } } -impl std::iter::FromIterator for Generic { +impl std::iter::FromIterator for Generic<'static, i32> { fn from_iter>(_: T) -> Self { todo!() } } fn main() { - as MyFromIter>::from_iter(1); + as MyFromIter>::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) - as MyFromIter>::from_iter(1); + as MyFromIter>::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) - as MyFromIter>::from_iter(1); + as MyFromIter>::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) } diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.rs b/src/test/ui/rust-2021/future-prelude-collision-generic.rs index 1984053705984..d7f8affc61ade 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-generic.rs +++ b/src/test/ui/rust-2021/future-prelude-collision-generic.rs @@ -6,19 +6,19 @@ #![allow(dead_code)] #![allow(unused_imports)] -struct Generic(T, U); +struct Generic<'a, U>(&'a U); trait MyFromIter { fn from_iter(_: i32) -> Self; } -impl MyFromIter for Generic { - fn from_iter(x: i32) -> Self { - Self(x, x) +impl MyFromIter for Generic<'static, i32> { + fn from_iter(_: i32) -> Self { + todo!() } } -impl std::iter::FromIterator for Generic { +impl std::iter::FromIterator for Generic<'static, i32> { fn from_iter>(_: T) -> Self { todo!() } @@ -28,10 +28,10 @@ fn main() { Generic::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) - Generic::::from_iter(1); + Generic::<'static, i32>::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) - Generic::<_, _>::from_iter(1); + Generic::<'_, _>::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) } diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr index 0a722baa185cd..e1d3f3c0a4629 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr +++ b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr @@ -2,7 +2,7 @@ warning: trait-associated function `from_iter` will become ambiguous in Rust 202 --> $DIR/future-prelude-collision-generic.rs:28:5 | LL | Generic::from_iter(1); - | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as MyFromIter>::from_iter` + | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as MyFromIter>::from_iter` | note: the lint level is defined here --> $DIR/future-prelude-collision-generic.rs:5:9 @@ -15,8 +15,8 @@ LL | #![warn(rust_2021_prelude_collisions)] warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 --> $DIR/future-prelude-collision-generic.rs:31:5 | -LL | Generic::::from_iter(1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as MyFromIter>::from_iter` +LL | Generic::<'static, i32>::from_iter(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as MyFromIter>::from_iter` | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see @@ -24,8 +24,8 @@ LL | Generic::::from_iter(1); warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 --> $DIR/future-prelude-collision-generic.rs:34:5 | -LL | Generic::<_, _>::from_iter(1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as MyFromIter>::from_iter` +LL | Generic::<'_, _>::from_iter(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as MyFromIter>::from_iter` | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.fixed b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed index c5ff0b4bcd0f8..15ccff7496e09 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-imported.fixed +++ b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed @@ -56,4 +56,15 @@ mod c { } } +mod d { + use super::m::*; + + fn main() { + // See https://github.com/rust-lang/rust/issues/88471 + let _: u32 = TryIntoU32::try_into(3u8).unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this is accepted in the current edition + } +} + fn main() {} diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.rs b/src/test/ui/rust-2021/future-prelude-collision-imported.rs index cd39eec47f2a4..cdffcaf754541 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-imported.rs +++ b/src/test/ui/rust-2021/future-prelude-collision-imported.rs @@ -56,4 +56,15 @@ mod c { } } +mod d { + use super::m::*; + + fn main() { + // See https://github.com/rust-lang/rust/issues/88471 + let _: u32 = 3u8.try_into().unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this is accepted in the current edition + } +} + fn main() {} diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr index fbda5d61f36dc..56abb8abd4d15 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr +++ b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr @@ -30,5 +30,14 @@ LL | let _: u32 = 3u8.try_into().unwrap(); = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see -warning: 3 warnings emitted +warning: trait method `try_into` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision-imported.rs:64:22 + | +LL | let _: u32 = 3u8.try_into().unwrap(); + | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)` + | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see + +warning: 4 warnings emitted diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs new file mode 100644 index 0000000000000..a1584581e6c45 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +mod m { + type Foo = impl std::fmt::Debug; + + pub fn foo() -> Foo { + 22_u32 + } +} + +fn is_send(_: T) {} + +fn main() { + is_send(m::foo()); +} diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs new file mode 100644 index 0000000000000..745379efa6df9 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +mod m { + use std::rc::Rc; + + type Foo = impl std::fmt::Debug; + + pub fn foo() -> Foo { + Rc::new(22_u32) + } +} + +fn is_send(_: T) {} + +fn main() { + is_send(m::foo()); + //~^ ERROR: `Rc` cannot be sent between threads safely [E0277] +} diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr new file mode 100644 index 0000000000000..d60be4b1ccf9c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr @@ -0,0 +1,20 @@ +error[E0277]: `Rc` cannot be sent between threads safely + --> $DIR/auto-trait-leakage2.rs:17:5 + | +LL | type Foo = impl std::fmt::Debug; + | -------------------- within this `impl Debug` +... +LL | is_send(m::foo()); + | ^^^^^^^ `Rc` cannot be sent between threads safely + | + = help: within `impl Debug`, the trait `Send` is not implemented for `Rc` + = note: required because it appears within the type `impl Debug` +note: required by a bound in `is_send` + --> $DIR/auto-trait-leakage2.rs:14:15 + | +LL | fn is_send(_: T) {} + | ^^^^ required by this bound in `is_send` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs new file mode 100644 index 0000000000000..5fb7a9473d3df --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs @@ -0,0 +1,21 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// FIXME This should compile, but it currently doesn't + +mod m { + type Foo = impl std::fmt::Debug; + //~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391] + + pub fn foo() -> Foo { + 22_u32 + } + + pub fn bar() { + is_send(foo()); + } + + fn is_send(_: T) {} +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr new file mode 100644 index 0000000000000..ac7bbd272c771 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr @@ -0,0 +1,22 @@ +error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}` + --> $DIR/auto-trait-leakage3.rs:7:16 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `m::bar`... + --> $DIR/auto-trait-leakage3.rs:14:5 + | +LL | pub fn bar() { + | ^^^^^^^^^^^^ + = note: ...which requires evaluating trait selection obligation `impl std::fmt::Debug: std::marker::Send`... + = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle +note: cycle used when checking item types in module `m` + --> $DIR/auto-trait-leakage3.rs:6:1 + | +LL | mod m { + | ^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/type-alias-impl-trait/inference-cycle.rs b/src/test/ui/type-alias-impl-trait/inference-cycle.rs new file mode 100644 index 0000000000000..c781e200bf8ee --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/inference-cycle.rs @@ -0,0 +1,26 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +mod m { + type Foo = impl std::fmt::Debug; + //~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391] + + // Cycle: error today, but it'd be nice if it eventually worked + + pub fn foo() -> Foo { + is_send(bar()) + } + + pub fn bar() { + is_send(foo()); // Today: error + } + + fn baz() { + let f: Foo = 22_u32; + //~^ ERROR: mismatched types [E0308] + } + + fn is_send(_: T) {} +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/inference-cycle.stderr b/src/test/ui/type-alias-impl-trait/inference-cycle.stderr new file mode 100644 index 0000000000000..ac0ca8e048cb0 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/inference-cycle.stderr @@ -0,0 +1,37 @@ +error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}` + --> $DIR/inference-cycle.rs:5:16 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `m::bar`... + --> $DIR/inference-cycle.rs:14:5 + | +LL | pub fn bar() { + | ^^^^^^^^^^^^ + = note: ...which requires evaluating trait selection obligation `impl std::fmt::Debug: std::marker::Send`... + = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle +note: cycle used when checking item types in module `m` + --> $DIR/inference-cycle.rs:4:1 + | +LL | mod m { + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/inference-cycle.rs:19:22 + | +LL | type Foo = impl std::fmt::Debug; + | -------------------- the expected opaque type +... +LL | let f: Foo = 22_u32; + | --- ^^^^^^ expected opaque type, found `u32` + | | + | expected due to this + | + = note: expected opaque type `impl Debug` + found type `u32` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0391. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs new file mode 100644 index 0000000000000..efb88dabf34cd --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +use std::fmt::Debug; + +type FooX = impl Debug; + +trait Foo { } + +impl Foo<()> for () { } + +fn foo() -> impl Foo { + () +} + +fn main() { } diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs new file mode 100644 index 0000000000000..9b26a65297852 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +use std::fmt::Debug; + +type FooX = impl Debug; +//~^ ERROR: could not find defining uses + +trait Foo {} + +impl Foo<()> for () {} +impl Foo for () {} + +fn foo() -> impl Foo { + //~^ ERROR: the trait bound `(): Foo` is not satisfied [E0277] + () +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr new file mode 100644 index 0000000000000..7e24ee644b1ce --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `(): Foo` is not satisfied + --> $DIR/nested-tait-inference2.rs:14:13 + | +LL | fn foo() -> impl Foo { + | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + | + = help: the following implementations were found: + <() as Foo<()>> + <() as Foo> + +error: could not find defining uses + --> $DIR/nested-tait-inference2.rs:6:13 + | +LL | type FooX = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/weird-return-types.rs b/src/test/ui/type-alias-impl-trait/weird-return-types.rs new file mode 100644 index 0000000000000..faad5ee956a1d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/weird-return-types.rs @@ -0,0 +1,16 @@ +// edition:2018 +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +use std::future::Future; +use std::fmt::Debug; + +type Foo = impl Debug; + +fn f() -> impl Future { + async move { 22_u32 } +} + +fn main() {}