diff --git a/src/backtrace b/src/backtrace index 8f89434446f72..5965cf5fc17af 160000 --- a/src/backtrace +++ b/src/backtrace @@ -1 +1 @@ -Subproject commit 8f89434446f72f27f8145d8bbc1a302c6ef29d1e +Subproject commit 5965cf5fc17affc84c11dc9972ae8f4dc2c32db1 diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 5e2e04c063bc4..93908e9190e64 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -26,6 +26,9 @@ of bugs: * Double-free, invalid free * Memory leaks +The memory leak detection is enabled by default on Linux, and can be enabled +with runtime flag `ASAN_OPTIONS=detect_leaks=1` on macOS. + AddressSanitizer is supported on the following targets: * `x86_64-apple-darwin` @@ -196,10 +199,6 @@ fn main() { ```shell $ export \ - CC=clang \ - CXX=clang++ \ - CFLAGS='-fsanitize=memory -fsanitize-memory-track-origins' \ - CXXFLAGS='-fsanitize=memory -fsanitize-memory-track-origins' \ RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' \ RUSTDOCFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' $ cargo clean diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 061d1ea6b1c46..9fb7296ce31cc 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -242,7 +242,7 @@ pub mod consts { /// The full circle constant (τ) /// /// Equal to 2π. - #[unstable(feature = "tau_constant", issue = "66770")] + #[stable(feature = "tau_constant", since = "1.47.0")] pub const TAU: f32 = 6.28318530717958647692528676655900577_f32; /// π/2 diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index b0df4d64f6ee1..bcb6cd4084691 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -242,7 +242,7 @@ pub mod consts { /// The full circle constant (τ) /// /// Equal to 2π. - #[unstable(feature = "tau_constant", issue = "66770")] + #[stable(feature = "tau_constant", since = "1.47.0")] pub const TAU: f64 = 6.28318530717958647692528676655900577_f64; /// π/2 diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index d86f39c4550c8..179038d1977c8 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -39,7 +39,7 @@ use crate::hash::Hash; /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html #[doc(alias = "..")] -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFull; @@ -71,7 +71,7 @@ impl fmt::Debug for RangeFull { /// assert_eq!(arr[1..=3], [ 1,2,3 ]); /// ``` #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { /// The lower bound of the range (inclusive). diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index bbbd8359f0126..279c65ce03d2d 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -453,6 +453,7 @@ E0767: include_str!("./error_codes/E0767.md"), E0768: include_str!("./error_codes/E0768.md"), E0769: include_str!("./error_codes/E0769.md"), E0770: include_str!("./error_codes/E0770.md"), +E0771: include_str!("./error_codes/E0771.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/src/librustc_error_codes/error_codes/E0771.md b/src/librustc_error_codes/error_codes/E0771.md new file mode 100644 index 0000000000000..824a955f6b3f4 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0771.md @@ -0,0 +1,23 @@ +A non-`'static` lifetime was used in a const generic. This is currently not +allowed. + +Erroneous code example: + +```compile_fail,E0771 +#![feature(const_generics)] + +fn function_with_str<'a, const STRING: &'a str>() {} // error! +``` + +To fix this issue, the lifetime in the const generic need to be changed to +`'static`: + +``` +#![feature(const_generics)] + +fn function_with_str() {} // ok! +``` + +For more information, see [GitHub issue #74052]. + +[GitHub issue #74052]: https://github.com/rust-lang/rust/issues/74052 diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index 4dd8723bd72a1..f479a030d6325 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -103,9 +103,13 @@ rustc_queries! { /// // ^ While calling `opt_const_param_of` for other bodies returns `None`. /// } /// ``` + // It looks like caching this query on disk actually slightly + // worsened performance in #74376. + // + // Once const generics are more prevalently used, we might want to + // consider only caching calls returning `Some`. query opt_const_param_of(key: LocalDefId) -> Option { desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) } - // FIXME(#74113): consider storing this query on disk. } /// Records the type of every item. diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index ed88e54969215..261c2031364f6 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -1500,11 +1500,17 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { pat_src: PatternSource, bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet); 1]>, ) { + let is_tuple_struct_pat = matches!(pat.kind, PatKind::TupleStruct(_, _)); + // Visit all direct subpatterns of this pattern. pat.walk(&mut |pat| { debug!("resolve_pattern pat={:?} node={:?}", pat, pat.kind); match pat.kind { - PatKind::Ident(bmode, ident, ref sub) => { + // In tuple struct patterns ignore the invalid `ident @ ...`. + // It will be handled as an error by the AST lowering. + PatKind::Ident(bmode, ident, ref sub) + if !(is_tuple_struct_pat && sub.as_ref().filter(|p| p.is_rest()).is_some()) => + { // First try to resolve the identifier as some existing entity, // then fall back to a fresh binding. let has_sub = sub.is_some(); diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 9323c15a94109..c86b414184759 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -1141,6 +1141,24 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { err.emit(); } + // FIXME(const_generics): This patches over a ICE caused by non-'static lifetimes in const + // generics. We are disallowing this until we can decide on how we want to handle non-'static + // lifetimes in const generics. See issue #74052 for discussion. + crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &hir::Lifetime) { + let mut err = struct_span_err!( + self.tcx.sess, + lifetime_ref.span, + E0771, + "use of non-static lifetime `{}` in const generic", + lifetime_ref + ); + err.note( + "for more information, see issue #74052 \ + ", + ); + err.emit(); + } + crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool { if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res { if [ diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index 567db8edec9af..6009e48a54f5e 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -173,6 +173,8 @@ crate struct LifetimeContext<'a, 'tcx> { /// Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax. is_in_fn_syntax: bool, + is_in_const_generic: bool, + /// List of labels in the function/method currently under analysis. labels_in_fn: Vec, @@ -333,6 +335,7 @@ fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap { scope: ROOT_SCOPE, trait_ref_hack: false, is_in_fn_syntax: false, + is_in_const_generic: false, labels_in_fn: vec![], xcrate_object_lifetime_defaults: Default::default(), lifetime_uses: &mut Default::default(), @@ -828,6 +831,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.insert_lifetime(lifetime_ref, Region::Static); return; } + if self.is_in_const_generic && lifetime_ref.name != LifetimeName::Error { + self.emit_non_static_lt_in_const_generic_error(lifetime_ref); + return; + } self.resolve_lifetime_ref(lifetime_ref); } @@ -860,8 +867,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } GenericParamKind::Const { ref ty, .. } => { + let was_in_const_generic = self.is_in_const_generic; + self.is_in_const_generic = true; walk_list!(self, visit_param_bound, param.bounds); self.visit_ty(&ty); + self.is_in_const_generic = was_in_const_generic; } } } @@ -1317,6 +1327,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope: &wrap_scope, trait_ref_hack: self.trait_ref_hack, is_in_fn_syntax: self.is_in_fn_syntax, + is_in_const_generic: self.is_in_const_generic, labels_in_fn, xcrate_object_lifetime_defaults, lifetime_uses, diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 845a4fcafc224..dabae6cbc4137 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; use rustc_session::parse::feature_err; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use rustc_trait_selection::opaque_types::may_define_opaque_type; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; @@ -142,8 +142,8 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) { _ => unreachable!(), } } - hir::ItemKind::Fn(..) => { - check_item_fn(tcx, item); + hir::ItemKind::Fn(ref sig, ..) => { + check_item_fn(tcx, item.hir_id, item.ident, item.span, sig.decl); } hir::ItemKind::Static(ref ty, ..) => { check_item_type(tcx, item.hir_id, ty.span, false); @@ -153,8 +153,14 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) { } hir::ItemKind::ForeignMod(ref module) => { for it in module.items.iter() { - if let hir::ForeignItemKind::Static(ref ty, ..) = it.kind { - check_item_type(tcx, it.hir_id, ty.span, true); + match it.kind { + hir::ForeignItemKind::Fn(ref decl, ..) => { + check_item_fn(tcx, it.hir_id, it.ident, it.span, decl) + } + hir::ForeignItemKind::Static(ref ty, ..) => { + check_item_type(tcx, it.hir_id, ty.span, true) + } + hir::ForeignItemKind::Type => (), } } } @@ -303,7 +309,7 @@ fn check_associated_item( fcx, item.ident.span, sig, - hir_sig, + hir_sig.decl, item.def_id, &mut implied_bounds, ); @@ -564,22 +570,24 @@ fn check_associated_type_defaults(fcx: &FnCtxt<'_, '_>, trait_def_id: DefId) { } } -fn check_item_fn(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { - for_item(tcx, item).with_fcx(|fcx, tcx| { - let def_id = fcx.tcx.hir().local_def_id(item.hir_id); +fn check_item_fn( + tcx: TyCtxt<'_>, + item_id: hir::HirId, + ident: Ident, + span: Span, + decl: &hir::FnDecl<'_>, +) { + for_id(tcx, item_id, span).with_fcx(|fcx, tcx| { + let def_id = fcx.tcx.hir().local_def_id(item_id); let sig = fcx.tcx.fn_sig(def_id); - let sig = fcx.normalize_associated_types_in(item.span, &sig); + let sig = fcx.normalize_associated_types_in(span, &sig); let mut implied_bounds = vec![]; - let hir_sig = match &item.kind { - ItemKind::Fn(sig, ..) => sig, - _ => bug!("expected `ItemKind::Fn`, found `{:?}`", item.kind), - }; check_fn_or_method( tcx, fcx, - item.ident.span, + ident.span, sig, - hir_sig, + decl, def_id.to_def_id(), &mut implied_bounds, ); @@ -835,28 +843,28 @@ fn check_fn_or_method<'fcx, 'tcx>( fcx: &FnCtxt<'fcx, 'tcx>, span: Span, sig: ty::PolyFnSig<'tcx>, - hir_sig: &hir::FnSig<'_>, + hir_decl: &hir::FnDecl<'_>, def_id: DefId, implied_bounds: &mut Vec>, ) { let sig = fcx.normalize_associated_types_in(span, &sig); let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); - for (&input_ty, span) in sig.inputs().iter().zip(hir_sig.decl.inputs.iter().map(|t| t.span)) { + for (&input_ty, span) in sig.inputs().iter().zip(hir_decl.inputs.iter().map(|t| t.span)) { fcx.register_wf_obligation(input_ty.into(), span, ObligationCauseCode::MiscObligation); } implied_bounds.extend(sig.inputs()); fcx.register_wf_obligation( sig.output().into(), - hir_sig.decl.output.span(), + hir_decl.output.span(), ObligationCauseCode::ReturnType, ); // FIXME(#25759) return types should not be implied bounds implied_bounds.push(sig.output()); - check_where_clauses(tcx, fcx, span, def_id, Some((sig.output(), hir_sig.decl.output.span()))); + check_where_clauses(tcx, fcx, span, def_id, Some((sig.output(), hir_decl.output.span()))); } /// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ec534aa925d4f..c3b54f1461426 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1927,7 +1927,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat let re_root_empty = tcx.lifetimes.re_root_empty; let predicate = ty::OutlivesPredicate(ty, re_root_empty); predicates.push(( - ty::PredicateKind::TypeOutlives(ty::Binder::dummy(predicate)) + ty::PredicateKind::TypeOutlives(ty::Binder::bind(predicate)) .to_predicate(tcx), span, )); diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 38709b445efae..850a4b3cbc216 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1511,6 +1511,11 @@ h4 > .important-traits { #main > .line-numbers { margin-top: 0; } + + .important-traits .important-traits-tooltiptext { + left: 0; + top: 100%; + } } @media print { diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index e0ab7170ea877..96ba5c46a3cde 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -237,16 +237,6 @@ a { #crate-search+.search-input:focus { box-shadow: 0 0 0 1px #148099,0 0 0 2px transparent; - color: #ffffff; - background-color: #141920; - box-shadow: none; - transition: box-shadow 150ms ease-in-out; - border-radius: 4px; - margin-left: 8px; -} - -#crate-search+.search-input:focus { - box-shadow: 0px 6px 20px 0px black; } .search-focus:disabled { @@ -318,12 +308,12 @@ a.test-arrow { font-size: 100%; color: #788797; border-radius: 4px; - background-color: rgba(255, 255, 255, 0); + background-color: rgba(57, 175, 215, 0.09); } a.test-arrow:hover { - background-color: rgba(242, 151, 24, 0.05); - color: #ffb44c; + background-color: rgba(57, 175, 215, 0.368); + color: #c5c5c5; } .toggle-label { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 11b8f953be460..02de3fff29f87 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -224,10 +224,7 @@ all(target_vendor = "fortanix", target_env = "sgx"), feature(slice_index_methods, coerce_unsized, sgx_platform, ptr_wrapping_offset_from) )] -#![cfg_attr( - all(test, target_vendor = "fortanix", target_env = "sgx"), - feature(fixed_size_array, maybe_uninit_extra) -)] +#![cfg_attr(all(test, target_vendor = "fortanix", target_env = "sgx"), feature(fixed_size_array))] // std is implemented with unstable features, many of which are internal // compiler details that will never be stable // NB: the following list is sorted to minimize merge conflicts. diff --git a/src/test/ui/const-generics/const-argument-non-static-lifetime.rs b/src/test/ui/const-generics/const-argument-non-static-lifetime.rs new file mode 100644 index 0000000000000..bc09ba2ab553b --- /dev/null +++ b/src/test/ui/const-generics/const-argument-non-static-lifetime.rs @@ -0,0 +1,17 @@ +// run-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete +#![allow(dead_code)] + +fn test() {} + +fn wow<'a>() -> &'a () { + test::<{ + let _: &'a (); + 3 + }>(); + &() +} + +fn main() {} diff --git a/src/test/ui/const-generics/const-argument-non-static-lifetime.stderr b/src/test/ui/const-generics/const-argument-non-static-lifetime.stderr new file mode 100644 index 0000000000000..53a7550090d44 --- /dev/null +++ b/src/test/ui/const-generics/const-argument-non-static-lifetime.stderr @@ -0,0 +1,11 @@ +warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/const-argument-non-static-lifetime.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44580 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/error-codes/E0771.rs b/src/test/ui/error-codes/E0771.rs new file mode 100644 index 0000000000000..ba3592719408c --- /dev/null +++ b/src/test/ui/error-codes/E0771.rs @@ -0,0 +1,8 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete + +fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0771 + +fn main() { + function_with_str::<"Hello, world!">() +} diff --git a/src/test/ui/error-codes/E0771.stderr b/src/test/ui/error-codes/E0771.stderr new file mode 100644 index 0000000000000..60220be6b57ba --- /dev/null +++ b/src/test/ui/error-codes/E0771.stderr @@ -0,0 +1,20 @@ +warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/E0771.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44580 for more information + +error[E0771]: use of non-static lifetime `'a` in const generic + --> $DIR/E0771.rs:4:41 + | +LL | fn function_with_str<'a, const STRING: &'a str>() {} + | ^^ + | + = note: for more information, see issue #74052 + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0771`. diff --git a/src/test/ui/issues/issue-74539.rs b/src/test/ui/issues/issue-74539.rs new file mode 100644 index 0000000000000..75632d11c1df0 --- /dev/null +++ b/src/test/ui/issues/issue-74539.rs @@ -0,0 +1,12 @@ +enum E { + A(u8, u8), +} + +fn main() { + let e = E::A(2, 3); + match e { + E::A(x @ ..) => { //~ ERROR `x @` is not allowed in a tuple + x //~ ERROR cannot find value `x` in this scope + } + }; +} diff --git a/src/test/ui/issues/issue-74539.stderr b/src/test/ui/issues/issue-74539.stderr new file mode 100644 index 0000000000000..94526dcd7cb39 --- /dev/null +++ b/src/test/ui/issues/issue-74539.stderr @@ -0,0 +1,21 @@ +error[E0425]: cannot find value `x` in this scope + --> $DIR/issue-74539.rs:9:13 + | +LL | x + | ^ help: a local variable with a similar name exists: `e` + +error: `x @` is not allowed in a tuple struct + --> $DIR/issue-74539.rs:8:14 + | +LL | E::A(x @ ..) => { + | ^^^^^^ this is only allowed in slice patterns + | + = help: remove this and bind each tuple field independently +help: if you don't need to use the contents of x, discard the tuple's remaining fields + | +LL | E::A(..) => { + | ^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/lint/lint-ctypes.rs b/src/test/ui/lint/lint-ctypes.rs index bdf95350c7045..f485766bcd34e 100644 --- a/src/test/ui/lint/lint-ctypes.rs +++ b/src/test/ui/lint/lint-ctypes.rs @@ -7,6 +7,7 @@ extern crate libc; use std::marker::PhantomData; +trait Bar { } trait Mirror { type It: ?Sized; } impl Mirror for T { type It = Self; } #[repr(C)] @@ -53,7 +54,7 @@ extern { pub fn char_type(p: char); //~ ERROR uses type `char` pub fn i128_type(p: i128); //~ ERROR uses type `i128` pub fn u128_type(p: u128); //~ ERROR uses type `u128` - pub fn trait_type(p: &dyn Clone); //~ ERROR uses type `dyn std::clone::Clone` + pub fn trait_type(p: &dyn Bar); //~ ERROR uses type `dyn Bar` pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)` pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)` pub fn zero_size(p: ZeroSize); //~ ERROR uses type `ZeroSize` diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr index 13b9adca3f9f5..a54226a7fc4a2 100644 --- a/src/test/ui/lint/lint-ctypes.stderr +++ b/src/test/ui/lint/lint-ctypes.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `Foo`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:46:28 + --> $DIR/lint-ctypes.rs:47:28 | LL | pub fn ptr_type1(size: *const Foo); | ^^^^^^^^^^ not FFI-safe @@ -12,13 +12,13 @@ LL | #![deny(improper_ctypes)] = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout note: the type is defined here - --> $DIR/lint-ctypes.rs:24:1 + --> $DIR/lint-ctypes.rs:25:1 | LL | pub struct Foo; | ^^^^^^^^^^^^^^^ error: `extern` block uses type `Foo`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:47:28 + --> $DIR/lint-ctypes.rs:48:28 | LL | pub fn ptr_type2(size: *const Foo); | ^^^^^^^^^^ not FFI-safe @@ -26,13 +26,13 @@ LL | pub fn ptr_type2(size: *const Foo); = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout note: the type is defined here - --> $DIR/lint-ctypes.rs:24:1 + --> $DIR/lint-ctypes.rs:25:1 | LL | pub struct Foo; | ^^^^^^^^^^^^^^^ error: `extern` block uses type `[u32]`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:48:26 + --> $DIR/lint-ctypes.rs:49:26 | LL | pub fn slice_type(p: &[u32]); | ^^^^^^ not FFI-safe @@ -41,7 +41,7 @@ LL | pub fn slice_type(p: &[u32]); = note: slices have no C equivalent error: `extern` block uses type `str`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:49:24 + --> $DIR/lint-ctypes.rs:50:24 | LL | pub fn str_type(p: &str); | ^^^^ not FFI-safe @@ -50,7 +50,7 @@ LL | pub fn str_type(p: &str); = note: string slices have no C equivalent error: `extern` block uses type `std::boxed::Box`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:50:24 + --> $DIR/lint-ctypes.rs:51:24 | LL | pub fn box_type(p: Box); | ^^^^^^^^ not FFI-safe @@ -59,7 +59,7 @@ LL | pub fn box_type(p: Box); = note: this struct has unspecified layout error: `extern` block uses type `std::option::Option>`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:51:28 + --> $DIR/lint-ctypes.rs:52:28 | LL | pub fn opt_box_type(p: Option>); | ^^^^^^^^^^^^^^^^ not FFI-safe @@ -68,7 +68,7 @@ LL | pub fn opt_box_type(p: Option>); = note: enum has no representation hint error: `extern` block uses type `char`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:53:25 + --> $DIR/lint-ctypes.rs:54:25 | LL | pub fn char_type(p: char); | ^^^^ not FFI-safe @@ -77,7 +77,7 @@ LL | pub fn char_type(p: char); = note: the `char` type has no C equivalent error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:54:25 + --> $DIR/lint-ctypes.rs:55:25 | LL | pub fn i128_type(p: i128); | ^^^^ not FFI-safe @@ -85,23 +85,23 @@ LL | pub fn i128_type(p: i128); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:55:25 + --> $DIR/lint-ctypes.rs:56:25 | LL | pub fn u128_type(p: u128); | ^^^^ not FFI-safe | = note: 128-bit integers don't currently have a known stable ABI -error: `extern` block uses type `dyn std::clone::Clone`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:56:26 +error: `extern` block uses type `dyn Bar`, which is not FFI-safe + --> $DIR/lint-ctypes.rs:57:26 | -LL | pub fn trait_type(p: &dyn Clone); - | ^^^^^^^^^^ not FFI-safe +LL | pub fn trait_type(p: &dyn Bar); + | ^^^^^^^^ not FFI-safe | = note: trait objects have no C equivalent error: `extern` block uses type `(i32, i32)`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:57:26 + --> $DIR/lint-ctypes.rs:58:26 | LL | pub fn tuple_type(p: (i32, i32)); | ^^^^^^^^^^ not FFI-safe @@ -110,7 +110,7 @@ LL | pub fn tuple_type(p: (i32, i32)); = note: tuples have unspecified layout error: `extern` block uses type `(i32, i32)`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:58:27 + --> $DIR/lint-ctypes.rs:59:27 | LL | pub fn tuple_type2(p: I32Pair); | ^^^^^^^ not FFI-safe @@ -119,7 +119,7 @@ LL | pub fn tuple_type2(p: I32Pair); = note: tuples have unspecified layout error: `extern` block uses type `ZeroSize`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:59:25 + --> $DIR/lint-ctypes.rs:60:25 | LL | pub fn zero_size(p: ZeroSize); | ^^^^^^^^ not FFI-safe @@ -127,26 +127,26 @@ LL | pub fn zero_size(p: ZeroSize); = help: consider adding a member to this struct = note: this struct has no fields note: the type is defined here - --> $DIR/lint-ctypes.rs:20:1 + --> $DIR/lint-ctypes.rs:21:1 | LL | pub struct ZeroSize; | ^^^^^^^^^^^^^^^^^^^^ error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:60:33 + --> $DIR/lint-ctypes.rs:61:33 | LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); | ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: composed only of `PhantomData` note: the type is defined here - --> $DIR/lint-ctypes.rs:43:1 + --> $DIR/lint-ctypes.rs:44:1 | LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `extern` block uses type `std::marker::PhantomData`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:63:12 + --> $DIR/lint-ctypes.rs:64:12 | LL | -> ::std::marker::PhantomData; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -154,7 +154,7 @@ LL | -> ::std::marker::PhantomData; = note: composed only of `PhantomData` error: `extern` block uses type `fn()`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:64:23 + --> $DIR/lint-ctypes.rs:65:23 | LL | pub fn fn_type(p: RustFn); | ^^^^^^ not FFI-safe @@ -163,7 +163,7 @@ LL | pub fn fn_type(p: RustFn); = note: this function pointer has Rust-specific calling convention error: `extern` block uses type `fn()`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:65:24 + --> $DIR/lint-ctypes.rs:66:24 | LL | pub fn fn_type2(p: fn()); | ^^^^ not FFI-safe @@ -172,7 +172,7 @@ LL | pub fn fn_type2(p: fn()); = note: this function pointer has Rust-specific calling convention error: `extern` block uses type `std::boxed::Box`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:66:28 + --> $DIR/lint-ctypes.rs:67:28 | LL | pub fn fn_contained(p: RustBadRet); | ^^^^^^^^^^ not FFI-safe @@ -181,7 +181,7 @@ LL | pub fn fn_contained(p: RustBadRet); = note: this struct has unspecified layout error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:67:32 + --> $DIR/lint-ctypes.rs:68:32 | LL | pub fn transparent_i128(p: TransparentI128); | ^^^^^^^^^^^^^^^ not FFI-safe @@ -189,7 +189,7 @@ LL | pub fn transparent_i128(p: TransparentI128); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `str`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:68:31 + --> $DIR/lint-ctypes.rs:69:31 | LL | pub fn transparent_str(p: TransparentStr); | ^^^^^^^^^^^^^^ not FFI-safe @@ -198,7 +198,7 @@ LL | pub fn transparent_str(p: TransparentStr); = note: string slices have no C equivalent error: `extern` block uses type `std::boxed::Box`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:69:30 + --> $DIR/lint-ctypes.rs:70:30 | LL | pub fn transparent_fn(p: TransparentBadFn); | ^^^^^^^^^^^^^^^^ not FFI-safe @@ -207,7 +207,7 @@ LL | pub fn transparent_fn(p: TransparentBadFn); = note: this struct has unspecified layout error: `extern` block uses type `[u8; 8]`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:70:27 + --> $DIR/lint-ctypes.rs:71:27 | LL | pub fn raw_array(arr: [u8; 8]); | ^^^^^^^ not FFI-safe @@ -216,7 +216,7 @@ LL | pub fn raw_array(arr: [u8; 8]); = note: passing raw arrays by value is not FFI-safe error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:72:34 + --> $DIR/lint-ctypes.rs:73:34 | LL | pub static static_u128_type: u128; | ^^^^ not FFI-safe @@ -224,7 +224,7 @@ LL | pub static static_u128_type: u128; = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:73:40 + --> $DIR/lint-ctypes.rs:74:40 | LL | pub static static_u128_array_type: [u128; 16]; | ^^^^^^^^^^ not FFI-safe diff --git a/src/test/ui/traits/issue-72410.rs b/src/test/ui/traits/issue-72410.rs new file mode 100644 index 0000000000000..c95f1dfdca53a --- /dev/null +++ b/src/test/ui/traits/issue-72410.rs @@ -0,0 +1,18 @@ +// Regression test for #72410, this should be used with debug assertion enabled. + +// should be fine +pub trait Foo { + fn map() + where + Self: Sized, + for<'a> &'a mut [u8]: ; +} + +// should fail +pub trait Bar { + fn map() + where for<'a> &'a mut [dyn Bar]: ; + //~^ ERROR: the trait `Bar` cannot be made into an object +} + +fn main() {} diff --git a/src/test/ui/traits/issue-72410.stderr b/src/test/ui/traits/issue-72410.stderr new file mode 100644 index 0000000000000..1db2320841ff7 --- /dev/null +++ b/src/test/ui/traits/issue-72410.stderr @@ -0,0 +1,18 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/issue-72410.rs:14:19 + | +LL | pub trait Bar { + | --- this trait cannot be made into an object... +LL | fn map() + | --- ...because associated function `map` has no `self` parameter +LL | where for<'a> &'a mut [dyn Bar]: ; + | ^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | +help: consider turning `map` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects + | +LL | where for<'a> &'a mut [dyn Bar]:, Self: Sized ; + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.rs b/src/test/ui/wf/wf-foreign-fn-decl-ret.rs new file mode 100644 index 0000000000000..b9d956c056869 --- /dev/null +++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.rs @@ -0,0 +1,18 @@ +pub trait Unsatisfied {} + +#[repr(transparent)] +pub struct Bar(T); + +pub trait Foo { + type Assoc; +} + +extern "C" { + pub fn lint_me() -> <() as Foo>::Assoc; + //~^ ERROR: the trait bound `(): Foo` is not satisfied [E0277] + + pub fn lint_me_aswell() -> Bar; + //~^ ERROR: the trait bound `u32: Unsatisfied` is not satisfied [E0277] +} + +fn main() {} diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr new file mode 100644 index 0000000000000..9081b7929d935 --- /dev/null +++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `(): Foo` is not satisfied + --> $DIR/wf-foreign-fn-decl-ret.rs:11:5 + | +LL | pub fn lint_me() -> <() as Foo>::Assoc; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + +error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied + --> $DIR/wf-foreign-fn-decl-ret.rs:14:32 + | +LL | pub struct Bar(T); + | ----------- required by this bound in `Bar` +... +LL | pub fn lint_me_aswell() -> Bar; + | ^^^^^^^^ the trait `Unsatisfied` is not implemented for `u32` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.