diff --git a/RELEASES.md b/RELEASES.md index 5ceeea8d037cb..355e53cbed25c 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -62,7 +62,7 @@ Misc Compatibility Notes ------------------- - With the stabilisation of `mem::MaybeUninit`, `mem::uninitialized` use is no - longer recommended, and will be deprecated in 1.38.0. + longer recommended, and will be deprecated in 1.39.0. [60318]: https://github.com/rust-lang/rust/pull/60318/ [60364]: https://github.com/rust-lang/rust/pull/60364/ diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index b62d81affddbd..f2729168763bb 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -472,7 +472,7 @@ pub unsafe fn zeroed() -> T { /// [`MaybeUninit`]: union.MaybeUninit.html /// [inv]: union.MaybeUninit.html#initialization-invariant #[inline] -#[rustc_deprecated(since = "1.38.0", reason = "use `mem::MaybeUninit` instead")] +#[rustc_deprecated(since = "1.39.0", reason = "use `mem::MaybeUninit` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized() -> T { MaybeUninit::uninit().assume_init() diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 29169951e469d..193cdb15b548d 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -178,7 +178,7 @@ impl Option { /// ``` /// /// [`Some`]: #variant.Some - #[must_use] + #[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn is_some(&self) -> bool { @@ -201,7 +201,8 @@ impl Option { /// ``` /// /// [`None`]: #variant.None - #[must_use] + #[must_use = "if you intended to assert that this doesn't have a value, consider \ + `.and_then(|| panic!(\"`Option` had a value when expected `None`\"))` instead"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn is_none(&self) -> bool { diff --git a/src/libcore/result.rs b/src/libcore/result.rs index b64ad149cf4db..ba72e1e75f8e1 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -277,7 +277,7 @@ impl Result { /// let x: Result = Err("Some error message"); /// assert_eq!(x.is_ok(), false); /// ``` - #[must_use] + #[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn is_ok(&self) -> bool { @@ -302,7 +302,7 @@ impl Result { /// let x: Result = Err("Some error message"); /// assert_eq!(x.is_err(), true); /// ``` - #[must_use] + #[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn is_err(&self) -> bool { diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 9b4b97202d96d..d1cae76de60a1 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -350,7 +350,8 @@ declare_lint! { declare_lint! { pub INDIRECT_STRUCTURAL_MATCH, - Warn, + // defaulting to allow until rust-lang/rust#62614 is fixed. + Allow, "pattern with const indirectly referencing non-`#[structural_match]` type" } @@ -451,6 +452,7 @@ declare_lint_pass! { AMBIGUOUS_ASSOCIATED_ITEMS, NESTED_IMPL_TRAIT, MUTABLE_BORROW_RESERVATION_CONFLICT, + INDIRECT_STRUCTURAL_MATCH, ] } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 3221b41ee1d44..beb8061842dd3 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -9,7 +9,7 @@ use crate::hir::def::{Res, DefKind}; use crate::hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use crate::hir::map::Map; use crate::hir::ptr::P; -use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName}; +use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName, QPath}; use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; use crate::rustc::lint; @@ -1458,10 +1458,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } // helper method to issue suggestions from `fn rah<'a>(&'a T)` to `fn rah(&T)` + // or from `fn rah<'a>(T<'a>)` to `fn rah(T<'_>)` fn suggest_eliding_single_use_lifetime( &self, err: &mut DiagnosticBuilder<'_>, def_id: DefId, lifetime: &hir::Lifetime ) { - // FIXME: future work: also suggest `impl Foo<'_>` for `impl<'a> Foo<'a>` let name = lifetime.name.ident(); let mut remove_decl = None; if let Some(parent_def_id) = self.tcx.parent(def_id) { @@ -1471,18 +1471,38 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } let mut remove_use = None; + let mut elide_use = None; let mut find_arg_use_span = |inputs: &hir::HirVec| { for input in inputs { - if let hir::TyKind::Rptr(lt, _) = input.node { - if lt.name.ident() == name { - // include the trailing whitespace between the ampersand and the type name - let lt_through_ty_span = lifetime.span.to(input.span.shrink_to_hi()); - remove_use = Some( - self.tcx.sess.source_map() - .span_until_non_whitespace(lt_through_ty_span) - ); - break; + match input.node { + hir::TyKind::Rptr(lt, _) => { + if lt.name.ident() == name { + // include the trailing whitespace between the lifetime and type names + let lt_through_ty_span = lifetime.span.to(input.span.shrink_to_hi()); + remove_use = Some( + self.tcx.sess.source_map() + .span_until_non_whitespace(lt_through_ty_span) + ); + break; + } } + hir::TyKind::Path(ref qpath) => { + if let QPath::Resolved(_, path) = qpath { + + let last_segment = &path.segments[path.segments.len()-1]; + let generics = last_segment.generic_args(); + for arg in generics.args.iter() { + if let GenericArg::Lifetime(lt) = arg { + if lt.name.ident() == name { + elide_use = Some(lt.span); + break; + } + } + } + break; + } + }, + _ => {} } } }; @@ -1506,24 +1526,35 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } - if let (Some(decl_span), Some(use_span)) = (remove_decl, remove_use) { - // if both declaration and use deletion spans start at the same - // place ("start at" because the latter includes trailing - // whitespace), then this is an in-band lifetime - if decl_span.shrink_to_lo() == use_span.shrink_to_lo() { - err.span_suggestion( - use_span, - "elide the single-use lifetime", - String::new(), - Applicability::MachineApplicable, - ); - } else { + let msg = "elide the single-use lifetime"; + match (remove_decl, remove_use, elide_use) { + (Some(decl_span), Some(use_span), None) => { + // if both declaration and use deletion spans start at the same + // place ("start at" because the latter includes trailing + // whitespace), then this is an in-band lifetime + if decl_span.shrink_to_lo() == use_span.shrink_to_lo() { + err.span_suggestion( + use_span, + msg, + String::new(), + Applicability::MachineApplicable, + ); + } else { + err.multipart_suggestion( + msg, + vec![(decl_span, String::new()), (use_span, String::new())], + Applicability::MachineApplicable, + ); + } + } + (Some(decl_span), None, Some(use_span)) => { err.multipart_suggestion( - "elide the single-use lifetime", - vec![(decl_span, String::new()), (use_span, String::new())], + msg, + vec![(decl_span, String::new()), (use_span, "'_".to_owned())], Applicability::MachineApplicable, ); } + _ => {} } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index a3b99f143d055..56cb89b5144ac 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -22,7 +22,6 @@ use rustc_macros::HashStable; use std::{cmp, fmt}; use syntax::ast; use syntax::attr::{self, SignedInt, UnsignedInt}; -use syntax::symbol::sym; use syntax_pos::{Span, DUMMY_SP}; #[derive(Copy, Clone, Debug)] @@ -435,20 +434,6 @@ impl<'tcx> TyCtxt<'tcx> { Some(dtor) => dtor.did }; - // RFC 1238: if the destructor method is tagged with the - // attribute `unsafe_destructor_blind_to_params`, then the - // compiler is being instructed to *assume* that the - // destructor will not access borrowed data, - // even if such data is otherwise reachable. - // - // Such access can be in plain sight (e.g., dereferencing - // `*foo.0` of `Foo<'a>(&'a u32)`) or indirectly hidden - // (e.g., calling `foo.0.clone()` of `Foo`). - if self.has_attr(dtor, sym::unsafe_destructor_blind_to_params) { - debug!("destructor_constraint({:?}) - blind", def.did); - return vec![]; - } - let impl_def_id = self.associated_item(dtor).container.id(); let impl_generics = self.generics_of(impl_def_id); diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index fc74e43ff5739..41d0638f7c6bd 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -380,10 +380,13 @@ impl<'a> Debug for DiagnosticBuilder<'a> { impl<'a> Drop for DiagnosticBuilder<'a> { fn drop(&mut self) { if !panicking() && !self.cancelled() { - let mut db = DiagnosticBuilder::new(self.handler, - Level::Bug, - "Error constructed but not emitted"); + let mut db = DiagnosticBuilder::new( + self.handler, + Level::Bug, + "the following error was constructed but not emitted", + ); db.emit(); + self.emit(); panic!(); } } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 1fa539f8a2aee..21b8f06d0895f 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -890,6 +890,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { let target = match body[bb].terminator().kind { TerminatorKind::Goto { target } | + TerminatorKind::FalseUnwind { real_target: target, .. } | TerminatorKind::Drop { target, .. } | TerminatorKind::DropAndReplace { target, .. } | TerminatorKind::Assert { target, .. } | @@ -908,8 +909,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } | TerminatorKind::Unreachable | - TerminatorKind::FalseEdges { .. } | - TerminatorKind::FalseUnwind { .. } => None, + TerminatorKind::FalseEdges { .. } => None, TerminatorKind::Return => { break; diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index c4c4e10a14cc0..babffe479bc2e 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -246,7 +246,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( /// /// * (1.) `D` has a lifetime- or type-parametric Drop implementation, /// (where that `Drop` implementation does not opt-out of -/// this check via the `unsafe_destructor_blind_to_params` +/// this check via the `may_dangle` /// attribute), and /// * (2.) the structure of `D` can reach a reference of type `&'a _`, /// @@ -279,7 +279,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( /// instead Drop-Check now simply assumes that if a destructor has /// access (direct or indirect) to a lifetime parameter, then that /// lifetime must be forced to outlive that destructor's dynamic -/// extent. We then provide the `unsafe_destructor_blind_to_params` +/// extent. We then provide the `may_dangle` /// attribute as a way for destructor implementations to opt-out of /// this conservative assumption (and thus assume the obligation of /// ensuring that they do not access data nor invoke methods of diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5c6847b414136..3cd520fd4b50b 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3809,7 +3809,6 @@ const ATTRIBUTE_WHITELIST: &'static [Symbol] = &[ sym::must_use, sym::no_mangle, sym::repr, - sym::unsafe_destructor_blind_to_params, sym::non_exhaustive ]; diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index d18fcb4a1da0a..f5018485ef7bc 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -119,7 +119,7 @@ mod continue_keyword { } /// The `as` keyword can be used to change what the crate is referred to as in your project. If a /// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores. /// -/// `crate` is also used as in conjunction with `pub` to signify that the item it's attached to +/// `crate` can also be used as in conjunction with `pub` to signify that the item it's attached to /// is public only to other members of the same crate it's in. /// /// ```rust @@ -131,6 +131,10 @@ mod continue_keyword { } /// } /// ``` /// +/// `crate` is also used to represent the absolute path of a module, where `crate` refers to the +/// root of the current crate. For instance, `crate::foo::bar` refers to the name `bar` inside the +/// module `foo`, from anywhere else in the same crate. +/// /// [Reference]: ../reference/items/extern-crates.html mod crate_keyword { } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 84a012f03c9d3..e3628d908fb1e 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -199,9 +199,6 @@ declare_features! ( // no-tracking-issue-end - // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238). - (active, dropck_parametricity, "1.3.0", Some(28498), None), - // no-tracking-issue-start // Allows using `#[omit_gdb_pretty_printer_section]`. @@ -641,6 +638,8 @@ declare_features! ( (removed, extern_in_paths, "1.33.0", Some(55600), None, Some("subsumed by `::foo::bar` paths")), (removed, quote, "1.33.0", Some(29601), None, None), + // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238). + (removed, dropck_parametricity, "1.38.0", Some(28498), None, None), // ------------------------------------------------------------------------- // feature-group-end: removed features @@ -1447,15 +1446,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ cfg_fn!(omit_gdb_pretty_printer_section) ) ), - (sym::unsafe_destructor_blind_to_params, - Normal, - template!(Word), - Gated(Stability::Deprecated("https://github.com/rust-lang/rust/issues/34761", - Some("replace this attribute with `#[may_dangle]`")), - sym::dropck_parametricity, - "unsafe_destructor_blind_to_params has been replaced by \ - may_dangle and will be removed in the future", - cfg_fn!(dropck_parametricity))), (sym::may_dangle, Normal, template!(Word), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 83dbff6b2d574..e0633f73ac465 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4629,6 +4629,9 @@ impl<'a> Parser<'a> { fn parse_block_tail(&mut self, lo: Span, s: BlockCheckMode) -> PResult<'a, P> { let mut stmts = vec![]; while !self.eat(&token::CloseDelim(token::Brace)) { + if self.token == token::Eof { + break; + } let stmt = match self.parse_full_stmt(false) { Err(mut err) => { err.emit(); @@ -4643,8 +4646,6 @@ impl<'a> Parser<'a> { }; if let Some(stmt) = stmt { stmts.push(stmt); - } else if self.token == token::Eof { - break; } else { // Found only `;` or `}`. continue; @@ -6666,12 +6667,13 @@ impl<'a> Parser<'a> { } /// Reads a module from a source file. - fn eval_src_mod(&mut self, - path: PathBuf, - directory_ownership: DirectoryOwnership, - name: String, - id_sp: Span) - -> PResult<'a, (ast::Mod, Vec )> { + fn eval_src_mod( + &mut self, + path: PathBuf, + directory_ownership: DirectoryOwnership, + name: String, + id_sp: Span, + ) -> PResult<'a, (ast::Mod, Vec)> { let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut(); if let Some(i) = included_mod_stack.iter().position(|p| *p == path) { let mut err = String::from("circular modules: "); diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index f850960624ce7..2ef32d37d44cd 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -34,7 +34,7 @@ fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T } /// Parse a string, return a crate. -pub fn string_to_crate (source_str : String) -> ast::Crate { +pub fn string_to_crate(source_str : String) -> ast::Crate { let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_crate_mod() @@ -42,7 +42,7 @@ pub fn string_to_crate (source_str : String) -> ast::Crate { } /// Parse a string, return an expr -pub fn string_to_expr (source_str : String) -> P { +pub fn string_to_expr(source_str : String) -> P { let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_expr() @@ -50,7 +50,7 @@ pub fn string_to_expr (source_str : String) -> P { } /// Parse a string, return an item -pub fn string_to_item (source_str : String) -> Option> { +pub fn string_to_item(source_str : String) -> Option> { let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_item() diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 581fd47c4b3b5..a983180ac01e1 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -695,7 +695,6 @@ symbols! { unmarked_api, unreachable_code, unrestricted_attribute_tokens, - unsafe_destructor_blind_to_params, unsafe_no_drop_flag, unsized_locals, unsized_tuple_coercion, diff --git a/src/test/compile-fail/const-fn-error.rs b/src/test/compile-fail/const-fn-error.rs index 87a9cf9490d86..1de23f2a5e94f 100644 --- a/src/test/compile-fail/const-fn-error.rs +++ b/src/test/compile-fail/const-fn-error.rs @@ -6,6 +6,7 @@ const fn f(x: usize) -> usize { let mut sum = 0; for i in 0..x { //~^ ERROR E0015 + //~| ERROR E0017 //~| ERROR E0019 //~| ERROR E0019 //~| ERROR E0080 diff --git a/src/test/compile-fail/issue-52443.rs b/src/test/compile-fail/issue-52443.rs index a993d811d327f..28d9937b5e881 100644 --- a/src/test/compile-fail/issue-52443.rs +++ b/src/test/compile-fail/issue-52443.rs @@ -1,10 +1,14 @@ fn main() { [(); & { loop { continue } } ]; //~ ERROR mismatched types [(); loop { break }]; //~ ERROR mismatched types - [(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type - //~^ WARN denote infinite loops with - [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions + [(); {while true {break}; 0}]; //~^ ERROR constant contains unimplemented expression type //~| ERROR constant contains unimplemented expression type + //~| WARN denote infinite loops with + [(); { for _ in 0usize.. {}; 0}]; + //~^ ERROR calls in constants are limited to constant functions + //~| ERROR references in constants may only refer to immutable values + //~| ERROR constant contains unimplemented expression type + //~| ERROR constant contains unimplemented expression type //~| ERROR evaluation of constant value failed } diff --git a/src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs b/src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs index 41b9d64d5f71e..9a191bad8b0bf 100644 --- a/src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs +++ b/src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs @@ -20,3 +20,12 @@ pub struct BatchInsert<'a, T: 'a, Tab> { impl<'a, T:'a, Tab, DB> QueryFragment for BatchInsert<'a, T, Tab> where DB: SupportsDefaultKeyword + Backend, {} + +pub trait LibToOwned { + type Owned; +} + +pub struct LibCow::Owned> { + pub t: T, + pub o: Owned, +} diff --git a/src/test/run-pass/coherence/re-rebalance-coherence-default-generic-associated-type.rs b/src/test/run-pass/coherence/re-rebalance-coherence-default-generic-associated-type.rs new file mode 100644 index 0000000000000..4168b7a6146a9 --- /dev/null +++ b/src/test/run-pass/coherence/re-rebalance-coherence-default-generic-associated-type.rs @@ -0,0 +1,27 @@ +// run-pass +// aux-build:re_rebalance_coherence_lib.rs + +#![allow(dead_code)] +#![feature(re_rebalance_coherence)] +// check that a generic type with a default value from an associated type can be used without +// specifying the value, and without invoking coherence errors. + +extern crate re_rebalance_coherence_lib as lib; +use lib::*; + +struct MyString {} + +impl LibToOwned for MyString { + type Owned = String; +} + +impl PartialEq for LibCow { + fn eq(&self, _other: &MyString) -> bool { + // Test that the default type is used. + let _s: &String = &self.o; + + false + } +} + +fn main() {} diff --git a/src/test/run-pass/issues/issue-24805-dropck-itemless.rs b/src/test/run-pass/issues/issue-24805-dropck-itemless.rs index db427ed3d3194..555eefeb3a1f8 100644 --- a/src/test/run-pass/issues/issue-24805-dropck-itemless.rs +++ b/src/test/run-pass/issues/issue-24805-dropck-itemless.rs @@ -1,12 +1,11 @@ // run-pass -#![allow(deprecated)] // Check that item-less traits do not cause dropck to inject extra // region constraints. #![allow(non_camel_case_types)] -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] trait UserDefined { } @@ -20,9 +19,8 @@ impl<'a, T> UserDefined for &'a T { } // ``` macro_rules! impl_drop { ($Bound:ident, $Id:ident) => { - struct $Id(T); - impl Drop for $Id { - #[unsafe_destructor_blind_to_params] + struct $Id(T); + unsafe impl <#[may_dangle] T: $Bound> Drop for $Id { fn drop(&mut self) { } } } diff --git a/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs b/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs index c4f249c45f13c..90cf2cddcf02a 100644 --- a/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs +++ b/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs @@ -1,21 +1,19 @@ // run-pass -#![allow(deprecated)] // FIXME: switch to `#[may_dangle]` below. // Example taken from RFC 1238 text // https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md // #example-of-the-unguarded-escape-hatch -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] use std::cell::Cell; struct Concrete<'a>(u32, Cell>>); struct Foo { data: Vec } -impl Drop for Foo { - // Below is the UGEH attribute - #[unsafe_destructor_blind_to_params] +// Below is the UGEH attribute +unsafe impl<#[may_dangle] T> Drop for Foo { fn drop(&mut self) { } } diff --git a/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs index 573ec8f6131f7..aea9fde5309e2 100644 --- a/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs +++ b/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs @@ -1,12 +1,11 @@ // run-pass -#![allow(deprecated)] // FIXME: switch to `#[may_dangle]` below. // Demonstrate the use of the unguarded escape hatch with a lifetime param // to assert that destructor will not access any dead data. // // Compare with compile-fail/issue28498-reject-lifetime-param.rs -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] #[derive(Debug)] struct ScribbleOnDrop(String); @@ -19,11 +18,9 @@ impl Drop for ScribbleOnDrop { struct Foo<'a>(u32, &'a ScribbleOnDrop); -impl<'a> Drop for Foo<'a> { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] 'a> Drop for Foo<'a> { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is sound, - // because destructor never accesses `self.1`. + // Use of `may_dangle` is sound, because destructor never accesses `self.1`. println!("Dropping Foo({}, _)", self.0); } } diff --git a/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs index e0863fa9947ed..91ef5a7c98d6d 100644 --- a/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs +++ b/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs @@ -1,5 +1,4 @@ // run-pass -#![allow(deprecated)] // FIXME: switch to `#[may_dangle]` below. // Demonstrate the use of the unguarded escape hatch with a type param in negative position // to assert that destructor will not access any dead data. @@ -11,7 +10,7 @@ // // Compare with run-pass/issue28498-ugeh-with-passed-to-fn.rs -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] #[derive(Debug)] struct ScribbleOnDrop(String); @@ -24,12 +23,10 @@ impl Drop for ScribbleOnDrop { struct Foo(u32, T, Box fn(&'r T) -> String>); -impl Drop for Foo { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T> Drop for Foo { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is sound, - // because destructor never passes a `self.1` to the callback - // (in `self.2`) despite having it available. + // Use of `may_dangle` is sound, because destructor never passes a `self.1` + // to the callback (in `self.2`) despite having it available. println!("Dropping Foo({}, _)", self.0); } } diff --git a/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs index 01d884584f640..808f3b6e81e52 100644 --- a/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs +++ b/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs @@ -1,12 +1,11 @@ // run-pass -#![allow(deprecated)] // FIXME: switch to `#[may_dangle]` below. // Demonstrate the use of the unguarded escape hatch with a trait bound // to assert that destructor will not access any dead data. // // Compare with compile-fail/issue28498-reject-trait-bound.rs -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] use std::fmt; @@ -19,14 +18,12 @@ impl Drop for ScribbleOnDrop { } } -struct Foo(u32, T); +struct Foo(u32, T); -impl Drop for Foo { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T: fmt::Debug> Drop for Foo { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is sound, - // because destructor never accesses the `Debug::fmt` method - // of `T`, despite having it available. + // Use of `may_dangle` is sound, because destructor never accesses + // the `Debug::fmt` method of `T`, despite having it available. println!("Dropping Foo({}, _)", self.0); } } diff --git a/src/test/ui/async-await/async-await.rs b/src/test/ui/async-await/async-await.rs index 29622c9d030a3..5ec99c5d183fb 100644 --- a/src/test/ui/async-await/async-await.rs +++ b/src/test/ui/async-await/async-await.rs @@ -70,6 +70,8 @@ fn async_nonmove_block(x: u8) -> impl Future { } } +// see async-closure.rs for async_closure + async_closure_in_unsafe_block + async fn async_fn(x: u8) -> u8 { wake_and_yield_once().await; x @@ -120,6 +122,18 @@ async unsafe fn unsafe_async_fn(x: u8) -> u8 { x } +unsafe fn unsafe_fn(x: u8) -> u8 { + x +} + +fn async_block_in_unsafe_block(x: u8) -> impl Future { + unsafe { + async move { + unsafe_fn(unsafe_async_fn(x).await) + } + } +} + struct Foo; trait Bar { @@ -176,6 +190,7 @@ fn main() { async_fn, generic_async_fn, async_fn_with_internal_borrow, + async_block_in_unsafe_block, Foo::async_assoc_item, |x| { async move { diff --git a/src/test/ui/async-await/async-closure.rs b/src/test/ui/async-await/async-closure.rs index f5dc9e24d2d86..925b54b398517 100644 --- a/src/test/ui/async-await/async-closure.rs +++ b/src/test/ui/async-await/async-closure.rs @@ -53,6 +53,21 @@ fn async_closure(x: u8) -> impl Future { })(x) } +fn async_closure_in_unsafe_block(x: u8) -> impl Future { + (unsafe { + async move |x: u8| unsafe_fn(unsafe_async_fn(x).await) + })(x) +} + +async unsafe fn unsafe_async_fn(x: u8) -> u8 { + wake_and_yield_once().await; + x +} + +unsafe fn unsafe_fn(x: u8) -> u8 { + x +} + fn test_future_yields_once_then_returns(f: F) where F: FnOnce(u8) -> Fut, @@ -77,5 +92,6 @@ fn main() { test! { async_closure, + async_closure_in_unsafe_block, } } diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs new file mode 100644 index 0000000000000..cb9156dcc6e58 --- /dev/null +++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs @@ -0,0 +1,21 @@ +// edition:2018 + +#![feature(async_await)] + +struct S; + +impl S { + async unsafe fn f() {} +} + +async unsafe fn f() {} + +async fn g() { + S::f(); //~ ERROR call to unsafe function is unsafe + f(); //~ ERROR call to unsafe function is unsafe +} + +fn main() { + S::f(); //~ ERROR call to unsafe function is unsafe + f(); //~ ERROR call to unsafe function is unsafe +} diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr new file mode 100644 index 0000000000000..d22413beecbcf --- /dev/null +++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr @@ -0,0 +1,35 @@ +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:14:5 + | +LL | S::f(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:15:5 + | +LL | f(); + | ^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:19:5 + | +LL | S::f(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:20:5 + | +LL | f(); + | ^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/async-await/await-macro.rs b/src/test/ui/async-await/await-macro.rs index c37835d73e92b..b9cd3903513a4 100644 --- a/src/test/ui/async-await/await-macro.rs +++ b/src/test/ui/async-await/await-macro.rs @@ -77,6 +77,12 @@ fn async_closure(x: u8) -> impl Future { })(x) } +fn async_closure_in_unsafe_block(x: u8) -> impl Future { + (unsafe { + async move |x: u8| unsafe_fn(await!(unsafe_async_fn(x))) + })(x) +} + async fn async_fn(x: u8) -> u8 { await!(wake_and_yield_once()); x @@ -127,6 +133,18 @@ async unsafe fn unsafe_async_fn(x: u8) -> u8 { x } +unsafe fn unsafe_fn(x: u8) -> u8 { + x +} + +fn async_block_in_unsafe_block(x: u8) -> impl Future { + unsafe { + async move { + unsafe_fn(await!(unsafe_async_fn(x))) + } + } +} + struct Foo; trait Bar { @@ -134,11 +152,15 @@ trait Bar { } impl Foo { - async fn async_method(x: u8) -> u8 { + async fn async_assoc_item(x: u8) -> u8 { unsafe { await!(unsafe_async_fn(x)) } } + + async unsafe fn async_unsafe_assoc_item(x: u8) -> u8 { + await!(unsafe_async_fn(x)) + } } fn test_future_yields_once_then_returns(f: F) @@ -177,15 +199,22 @@ fn main() { async_block, async_nonmove_block, async_closure, + async_closure_in_unsafe_block, async_fn, generic_async_fn, async_fn_with_internal_borrow, - Foo::async_method, + async_block_in_unsafe_block, + Foo::async_assoc_item, |x| { async move { unsafe { await!(unsafe_async_fn(x)) } } }, + |x| { + async move { + unsafe { await!(Foo::async_unsafe_assoc_item(x)) } + } + }, } test_with_borrow! { async_block_with_borrow_named_lifetime, diff --git a/src/test/ui/consts/const-eval/infinite_loop.rs b/src/test/ui/consts/const-eval/infinite_loop.rs index a2a45af7cb086..8fa5b0a961f9f 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.rs +++ b/src/test/ui/consts/const-eval/infinite_loop.rs @@ -4,7 +4,9 @@ fn main() { let _ = [(); { //~^ WARNING Constant evaluating a complex constant, this might take some time let mut n = 113383; // #20 in https://oeis.org/A006884 - while n != 0 { //~ ERROR constant contains unimplemented expression type + while n != 0 { + //~^ ERROR constant contains unimplemented expression type + //~| ERROR constant contains unimplemented expression type n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/consts/const-eval/infinite_loop.stderr b/src/test/ui/consts/const-eval/infinite_loop.stderr index 3a7da9ff2c8d8..68e7fdb12517b 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.stderr +++ b/src/test/ui/consts/const-eval/infinite_loop.stderr @@ -1,7 +1,15 @@ +error[E0019]: constant contains unimplemented expression type + --> $DIR/infinite_loop.rs:7:15 + | +LL | while n != 0 { + | ^^^^^^ + error[E0019]: constant contains unimplemented expression type --> $DIR/infinite_loop.rs:7:9 | LL | / while n != 0 { +LL | | +LL | | LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; LL | | LL | | } @@ -21,12 +29,12 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/infinite_loop.rs:8:20 + --> $DIR/infinite_loop.rs:10:20 | LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; | ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0019, E0080. For more information about an error, try `rustc --explain E0019`. diff --git a/src/test/ui/consts/const-eval/issue-52442.rs b/src/test/ui/consts/const-eval/issue-52442.rs index fadcde528d86e..2989b200b2fc4 100644 --- a/src/test/ui/consts/const-eval/issue-52442.rs +++ b/src/test/ui/consts/const-eval/issue-52442.rs @@ -1,4 +1,5 @@ fn main() { - [(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type - //~^ ERROR it is undefined behavior to use this value + [(); { &loop { break } as *const _ as usize } ]; + //~^ ERROR casting pointers to integers in constants is unstable + //~| ERROR it is undefined behavior to use this value } diff --git a/src/test/ui/consts/const-eval/issue-52442.stderr b/src/test/ui/consts/const-eval/issue-52442.stderr index e9afec5766a0c..88c94d917fe0e 100644 --- a/src/test/ui/consts/const-eval/issue-52442.stderr +++ b/src/test/ui/consts/const-eval/issue-52442.stderr @@ -1,8 +1,11 @@ -error[E0019]: constant contains unimplemented expression type - --> $DIR/issue-52442.rs:2:14 +error[E0658]: casting pointers to integers in constants is unstable + --> $DIR/issue-52442.rs:2:13 | LL | [(); { &loop { break } as *const _ as usize } ]; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/51910 + = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable error[E0080]: it is undefined behavior to use this value --> $DIR/issue-52442.rs:2:11 @@ -14,5 +17,5 @@ LL | [(); { &loop { break } as *const _ as usize } ]; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0019, E0080. -For more information about an error, try `rustc --explain E0019`. +Some errors have detailed explanations: E0080, E0658. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-52475.rs b/src/test/ui/consts/const-eval/issue-52475.rs index aafdd5fe61782..b42249e57fa9a 100644 --- a/src/test/ui/consts/const-eval/issue-52475.rs +++ b/src/test/ui/consts/const-eval/issue-52475.rs @@ -3,7 +3,9 @@ fn main() { //~^ WARNING Constant evaluating a complex constant, this might take some time let mut x = &0; let mut n = 0; - while n < 5 { //~ ERROR constant contains unimplemented expression type + while n < 5 { + //~^ ERROR constant contains unimplemented expression type + //~| ERROR constant contains unimplemented expression type n = (n + 1) % 5; //~ ERROR evaluation of constant value failed x = &0; // Materialize a new AllocId } diff --git a/src/test/ui/consts/const-eval/issue-52475.stderr b/src/test/ui/consts/const-eval/issue-52475.stderr index 7a52a38d767cc..1e83cbcff2bf1 100644 --- a/src/test/ui/consts/const-eval/issue-52475.stderr +++ b/src/test/ui/consts/const-eval/issue-52475.stderr @@ -1,7 +1,15 @@ +error[E0019]: constant contains unimplemented expression type + --> $DIR/issue-52475.rs:6:15 + | +LL | while n < 5 { + | ^^^^^ + error[E0019]: constant contains unimplemented expression type --> $DIR/issue-52475.rs:6:9 | LL | / while n < 5 { +LL | | +LL | | LL | | n = (n + 1) % 5; LL | | x = &0; // Materialize a new AllocId LL | | } @@ -21,12 +29,12 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/issue-52475.rs:7:17 + --> $DIR/issue-52475.rs:9:17 | LL | n = (n + 1) % 5; | ^^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0019, E0080. For more information about an error, try `rustc --explain E0019`. diff --git a/src/test/ui/consts/const-eval/issue-62272.rs b/src/test/ui/consts/const-eval/issue-62272.rs new file mode 100644 index 0000000000000..ad8589c73788c --- /dev/null +++ b/src/test/ui/consts/const-eval/issue-62272.rs @@ -0,0 +1,9 @@ +// run-pass + +// Tests that `loop`s unconditionally-broken-from are allowed in constants. + +const FOO: () = loop { break; }; + +fn main() { + [FOO; { let x; loop { x = 5; break; } x }]; +} diff --git a/src/test/ui/consts/const-labeled-break.rs b/src/test/ui/consts/const-labeled-break.rs index 512ad9427ea54..36e308ade9c54 100644 --- a/src/test/ui/consts/const-labeled-break.rs +++ b/src/test/ui/consts/const-labeled-break.rs @@ -1,9 +1,10 @@ +// run-pass + // Using labeled break in a while loop has caused an illegal instruction being // generated, and an ICE later. // // See https://github.com/rust-lang/rust/issues/51350 for more information. const CRASH: () = 'a: while break 'a {}; -//~^ ERROR constant contains unimplemented expression type fn main() {} diff --git a/src/test/ui/consts/const-labeled-break.stderr b/src/test/ui/consts/const-labeled-break.stderr deleted file mode 100644 index 2009e92235566..0000000000000 --- a/src/test/ui/consts/const-labeled-break.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-labeled-break.rs:6:19 - | -LL | const CRASH: () = 'a: while break 'a {}; - | ^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0019`. diff --git a/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.rs b/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.rs deleted file mode 100644 index 33252019e71e6..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![deny(deprecated)] -#![feature(dropck_parametricity)] - -struct Foo; - -impl Drop for Foo { - #[unsafe_destructor_blind_to_params] - //~^ ERROR use of deprecated attribute `dropck_parametricity` - fn drop(&mut self) {} -} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.stderr b/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.stderr deleted file mode 100644 index b6a474575c677..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: use of deprecated attribute `dropck_parametricity`: unsafe_destructor_blind_to_params has been replaced by may_dangle and will be removed in the future. See https://github.com/rust-lang/rust/issues/34761 - --> $DIR/feature-gate-dropck-ugeh-2.rs:7:5 - | -LL | #[unsafe_destructor_blind_to_params] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this attribute with `#[may_dangle]` - | -note: lint level defined here - --> $DIR/feature-gate-dropck-ugeh-2.rs:1:9 - | -LL | #![deny(deprecated)] - | ^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/feature-gates/feature-gate-dropck-ugeh.rs b/src/test/ui/feature-gates/feature-gate-dropck-ugeh.rs deleted file mode 100644 index a2377cda9bd66..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-dropck-ugeh.rs +++ /dev/null @@ -1,29 +0,0 @@ -// gate-test-dropck_parametricity - -// Ensure that attempts to use the unsafe attribute are feature-gated. -// Example adapted from RFC 1238 text (just left out the feature gate). - -// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md -// #example-of-the-unguarded-escape-hatch - -use std::cell::Cell; - -struct Concrete<'a>(u32, Cell>>); - -struct Foo { data: Vec } - -impl Drop for Foo { - #[unsafe_destructor_blind_to_params] // This is the UGEH attribute - //~^ ERROR unsafe_destructor_blind_to_params has been replaced - //~| WARN use of deprecated attribute `dropck_parametricity` - fn drop(&mut self) { } -} - -fn main() { - let mut foo = Foo { data: Vec::new() }; - foo.data.push(Concrete(0, Cell::new(None))); - foo.data.push(Concrete(0, Cell::new(None))); - - foo.data[0].1.set(Some(&foo.data[1])); - foo.data[1].1.set(Some(&foo.data[0])); -} diff --git a/src/test/ui/feature-gates/feature-gate-dropck-ugeh.stderr b/src/test/ui/feature-gates/feature-gate-dropck-ugeh.stderr deleted file mode 100644 index 581b760ba4f47..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-dropck-ugeh.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0658]: unsafe_destructor_blind_to_params has been replaced by may_dangle and will be removed in the future - --> $DIR/feature-gate-dropck-ugeh.rs:16:5 - | -LL | #[unsafe_destructor_blind_to_params] // This is the UGEH attribute - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/28498 - = help: add `#![feature(dropck_parametricity)]` to the crate attributes to enable - -warning: use of deprecated attribute `dropck_parametricity`: unsafe_destructor_blind_to_params has been replaced by may_dangle and will be removed in the future. See https://github.com/rust-lang/rust/issues/34761 - --> $DIR/feature-gate-dropck-ugeh.rs:16:5 - | -LL | #[unsafe_destructor_blind_to_params] // This is the UGEH attribute - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this attribute with `#[may_dangle]` - | - = note: #[warn(deprecated)] on by default - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issues/issue-49919.rs b/src/test/ui/issues/issue-49919.rs new file mode 100644 index 0000000000000..780f338681dd3 --- /dev/null +++ b/src/test/ui/issues/issue-49919.rs @@ -0,0 +1,7 @@ +fn foo<'a, T: 'a>(t: T) -> Box &'a T + 'a> { + let foo: Box Fn() -> &'c T> = Box::new(move || &t); + //~^ ERROR: binding for associated type + unimplemented!() +} + +fn main() {} diff --git a/src/test/ui/issues/issue-49919.stderr b/src/test/ui/issues/issue-49919.stderr new file mode 100644 index 0000000000000..8098be5cc4584 --- /dev/null +++ b/src/test/ui/issues/issue-49919.stderr @@ -0,0 +1,9 @@ +error[E0582]: binding for associated type `Output` references lifetime `'c`, which does not appear in the trait input types + --> $DIR/issue-49919.rs:2:39 + | +LL | let foo: Box Fn() -> &'c T> = Box::new(move || &t); + | ^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0582`. diff --git a/src/test/ui/issues/issue-55511.rs b/src/test/ui/issues/issue-55511.rs index 42c6f24b36a0c..055886bf3676c 100644 --- a/src/test/ui/issues/issue-55511.rs +++ b/src/test/ui/issues/issue-55511.rs @@ -1,5 +1,5 @@ +#![warn(indirect_structural_match)] use std::cell::Cell; - trait Foo<'a> { const C: Option>; } diff --git a/src/test/ui/issues/issue-55511.stderr b/src/test/ui/issues/issue-55511.stderr index c0f702e4fab23..e094256f5c827 100644 --- a/src/test/ui/issues/issue-55511.stderr +++ b/src/test/ui/issues/issue-55511.stderr @@ -4,7 +4,11 @@ warning: to use a constant of type `std::cell::Cell` in a pattern, `std::cell::C LL | <() as Foo<'static>>::C => { } | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(indirect_structural_match)] on by default +note: lint level defined here + --> $DIR/issue-55511.rs:1:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 diff --git a/src/test/ui/issues/issue-61858.rs b/src/test/ui/issues/issue-61858.rs new file mode 100644 index 0000000000000..6c3b56586c4ec --- /dev/null +++ b/src/test/ui/issues/issue-61858.rs @@ -0,0 +1,3 @@ +fn main() { + (if foobar) //~ ERROR expected `{`, found `)` +} diff --git a/src/test/ui/issues/issue-61858.stderr b/src/test/ui/issues/issue-61858.stderr new file mode 100644 index 0000000000000..ea2ec3d013f59 --- /dev/null +++ b/src/test/ui/issues/issue-61858.stderr @@ -0,0 +1,10 @@ +error: expected `{`, found `)` + --> $DIR/issue-61858.rs:2:15 + | +LL | (if foobar) + | -- ^ expected `{` + | | + | this `if` statement has a condition, but no block + +error: aborting due to previous error + diff --git a/src/test/ui/rfc1445/allow-use-behind-cousin-variant.rs b/src/test/ui/rfc1445/allow-use-behind-cousin-variant.rs new file mode 100644 index 0000000000000..dca8aaef1500d --- /dev/null +++ b/src/test/ui/rfc1445/allow-use-behind-cousin-variant.rs @@ -0,0 +1,59 @@ +// rust-lang/rust#62614: we want to allow matching on constants of types that +// have non-structural-match variants, *if* the constant itself does not use +// any such variant. + +// NOTE: for now, deliberately leaving the lint `indirect_structural_match` set +// to its default, so that we will not issue a diangostic even if +// rust-lang/rust#62614 remains an open issue. + +// run-pass + +struct Sum(u32, u32); + +impl PartialEq for Sum { + fn eq(&self, other: &Self) -> bool { self.0 + self.1 == other.0 + other.1 } +} + +impl Eq for Sum { } + +#[derive(PartialEq, Eq)] +enum Eek { + TheConst, + UnusedByTheConst(Sum) +} + +const THE_CONST: Eek = Eek::TheConst; +const SUM_THREE: Eek = Eek::UnusedByTheConst(Sum(3,0)); + +const EEK_ZERO: &[Eek] = &[]; +const EEK_ONE: &[Eek] = &[THE_CONST]; + +pub fn main() { + match Eek::UnusedByTheConst(Sum(1,2)) { + ref sum if sum == &SUM_THREE => { println!("Hello 0"); } + _ => { println!("Gbye"); } + } + + match Eek::TheConst { + THE_CONST => { println!("Hello 1"); } + _ => { println!("Gbye"); } + } + + + match & &Eek::TheConst { + & & THE_CONST => { println!("Hello 2"); } + _ => { println!("Gbye"); } + } + + match & & &[][..] { + & & EEK_ZERO => { println!("Hello 3"); } + & & EEK_ONE => { println!("Gbye"); } + _ => { println!("Gbye"); } + } + + match & & &[Eek::TheConst][..] { + & & EEK_ZERO => { println!("Gby"); } + & & EEK_ONE => { println!("Hello 4"); } + _ => { println!("Gbye"); } + } +} diff --git a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs index a3a615ea748cb..584e7a00f0993 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs +++ b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs @@ -4,7 +4,7 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 - +#![warn(indirect_structural_match)] struct NoDerive(i32); // This impl makes NoDerive irreflexive. diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs index b6d9c52b298b6..0328db5a49cf3 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs @@ -4,7 +4,7 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 - +#![warn(indirect_structural_match)] // run-pass struct NoDerive(i32); diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr index 3de63f43ecbb6..5281d576066da 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr @@ -4,7 +4,11 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(indirect_structural_match)] on by default +note: lint level defined here + --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs index 804d336b3ea61..54579e487a6b9 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs @@ -4,7 +4,7 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 - +#![warn(indirect_structural_match)] // run-pass struct NoDerive(i32); diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr index ee4652d153283..5d601c2c006f7 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr @@ -4,7 +4,11 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(indirect_structural_match)] on by default +note: lint level defined here + --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs index 85d2e65a9a080..2a24316898b5d 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs +++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs @@ -4,7 +4,7 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 - +#![warn(indirect_structural_match)] // run-pass struct NoDerive(i32); diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr index eb7468499316f..4ac19afa706b0 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr @@ -4,7 +4,11 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(indirect_structural_match)] on by default +note: lint level defined here + --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs index 849aa14776697..64e777f232234 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs +++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs @@ -4,7 +4,7 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 - +#![warn(indirect_structural_match)] // run-pass struct NoDerive(i32); diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr index 8a16556844454..4000a47987854 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr @@ -4,7 +4,11 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(indirect_structural_match)] on by default +note: lint level defined here + --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 diff --git a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs index 7646f7558a396..98943a9666a9a 100644 --- a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs +++ b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs @@ -10,7 +10,7 @@ // Issue 62307 pointed out a case where the checking for // `#[structural_match]` was too shallow. - +#![warn(indirect_structural_match)] // run-pass #[derive(Debug)] diff --git a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr index ba0275f5f9f93..0e158c2fda560 100644 --- a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr +++ b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr @@ -4,7 +4,11 @@ warning: to use a constant of type `B` in a pattern, `B` must be annotated with LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } | ^^^^^ | - = note: #[warn(indirect_structural_match)] on by default +note: lint level defined here + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs index 900e8434d4ff5..ff9d6bd01c670 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs @@ -9,4 +9,14 @@ fn a<'a>(x: &'a u32) { //~ ERROR `'a` only used once //~^ HELP elide the single-use lifetime } +struct Single<'a> { x: &'a u32 } +struct Double<'a, 'b> { f: &'a &'b u32 } + +fn center<'m>(_: Single<'m>) {} //~ ERROR `'m` only used once +//~^ HELP elide the single-use lifetime +fn left<'x, 'y>(foo: Double<'x, 'y>) -> &'x u32 { foo.f } //~ ERROR `'y` only used once +//~^ HELP elide the single-use lifetime +fn right<'x, 'y>(foo: Double<'x, 'y>) -> &'y u32 { foo.f } //~ ERROR `'x` only used once +//~^ HELP elide the single-use lifetime + fn main() { } diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr index 4bf08534b8c48..faaa7e2f1b01b 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr @@ -16,5 +16,37 @@ help: elide the single-use lifetime LL | fn a(x: &u32) { | -- -- -error: aborting due to previous error +error: lifetime parameter `'m` only used once + --> $DIR/one-use-in-fn-argument.rs:15:11 + | +LL | fn center<'m>(_: Single<'m>) {} + | ^^ -- ...is used only here + | | + | this lifetime... +help: elide the single-use lifetime + | +LL | fn center(_: Single<'_>) {} + | -- ^^ + +error: lifetime parameter `'y` only used once + --> $DIR/one-use-in-fn-argument.rs:17:13 + | +LL | fn left<'x, 'y>(foo: Double<'x, 'y>) -> &'x u32 { foo.f } + | ^^ this lifetime... -- ...is used only here +help: elide the single-use lifetime + | +LL | fn left<'x>(foo: Double<'x, '_>) -> &'x u32 { foo.f } + | -- ^^ + +error: lifetime parameter `'x` only used once + --> $DIR/one-use-in-fn-argument.rs:19:10 + | +LL | fn right<'x, 'y>(foo: Double<'x, 'y>) -> &'y u32 { foo.f } + | ^^ this lifetime... -- ...is used only here +help: elide the single-use lifetime + | +LL | fn right<'y>(foo: Double<'_, 'y>) -> &'y u32 { foo.f } + | -- ^^ + +error: aborting due to 4 previous errors diff --git a/src/test/ui/span/issue28498-reject-lifetime-param.rs b/src/test/ui/span/issue28498-reject-lifetime-param.rs index 9bc01766be564..1e7190157856c 100644 --- a/src/test/ui/span/issue28498-reject-lifetime-param.rs +++ b/src/test/ui/span/issue28498-reject-lifetime-param.rs @@ -16,9 +16,8 @@ struct Foo<'a>(u32, &'a ScribbleOnDrop); impl<'a> Drop for Foo<'a> { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is unsound, - // because destructor accesses borrowed data in `self.1` - // and we must force that to strictly outlive `self`. + // Use of `may_dangle` is unsound, because destructor accesses borrowed data + // in `self.1` and we must force that to strictly outlive `self`. println!("Dropping Foo({}, {:?})", self.0, self.1); } } diff --git a/src/test/ui/span/issue28498-reject-lifetime-param.stderr b/src/test/ui/span/issue28498-reject-lifetime-param.stderr index 1dcb40e5d9cb7..3119ddd03cc26 100644 --- a/src/test/ui/span/issue28498-reject-lifetime-param.stderr +++ b/src/test/ui/span/issue28498-reject-lifetime-param.stderr @@ -1,5 +1,5 @@ error[E0597]: `first_dropped` does not live long enough - --> $DIR/issue28498-reject-lifetime-param.rs:33:19 + --> $DIR/issue28498-reject-lifetime-param.rs:32:19 | LL | foo1 = Foo(1, &first_dropped); | ^^^^^^^^^^^^^^ borrowed value does not live long enough diff --git a/src/test/ui/span/issue28498-reject-passed-to-fn.rs b/src/test/ui/span/issue28498-reject-passed-to-fn.rs index c59de5df41170..dcd2e9ad4ba98 100644 --- a/src/test/ui/span/issue28498-reject-passed-to-fn.rs +++ b/src/test/ui/span/issue28498-reject-passed-to-fn.rs @@ -16,8 +16,7 @@ struct Foo(u32, T, Box fn(&'r T) -> String>); impl Drop for Foo { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is unsound, - // because we pass `T` to the callback in `self.2` + // Use of `may_dangle` is unsound, because we pass `T` to the callback in `self.2` // below, and thus potentially read from borrowed data. println!("Dropping Foo({}, {})", self.0, (self.2)(&self.1)); } diff --git a/src/test/ui/span/issue28498-reject-passed-to-fn.stderr b/src/test/ui/span/issue28498-reject-passed-to-fn.stderr index 214a6f6d65ca5..60e8a648cd597 100644 --- a/src/test/ui/span/issue28498-reject-passed-to-fn.stderr +++ b/src/test/ui/span/issue28498-reject-passed-to-fn.stderr @@ -1,5 +1,5 @@ error[E0597]: `first_dropped` does not live long enough - --> $DIR/issue28498-reject-passed-to-fn.rs:35:19 + --> $DIR/issue28498-reject-passed-to-fn.rs:34:19 | LL | foo1 = Foo(1, &first_dropped, Box::new(callback)); | ^^^^^^^^^^^^^^ borrowed value does not live long enough diff --git a/src/test/ui/span/issue28498-reject-trait-bound.rs b/src/test/ui/span/issue28498-reject-trait-bound.rs index 8813180c8919f..444cebb19a73d 100644 --- a/src/test/ui/span/issue28498-reject-trait-bound.rs +++ b/src/test/ui/span/issue28498-reject-trait-bound.rs @@ -14,13 +14,12 @@ impl Drop for ScribbleOnDrop { } } -struct Foo(u32, T); +struct Foo(u32, T); -impl Drop for Foo { +impl Drop for Foo { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is unsound, - // because we access `T` fmt method when we pass `self.1` - // below, and thus potentially read from borrowed data. + // Use of `may_dangle` is unsound, because we access `T` fmt method when we pass + // `self.1` below, and thus potentially read from borrowed data. println!("Dropping Foo({}, {:?})", self.0, self.1); } } diff --git a/src/test/ui/span/issue28498-reject-trait-bound.stderr b/src/test/ui/span/issue28498-reject-trait-bound.stderr index d4fe291bef398..22e4a8205b617 100644 --- a/src/test/ui/span/issue28498-reject-trait-bound.stderr +++ b/src/test/ui/span/issue28498-reject-trait-bound.stderr @@ -1,5 +1,5 @@ error[E0597]: `first_dropped` does not live long enough - --> $DIR/issue28498-reject-trait-bound.rs:35:19 + --> $DIR/issue28498-reject-trait-bound.rs:34:19 | LL | foo1 = Foo(1, &first_dropped); | ^^^^^^^^^^^^^^ borrowed value does not live long enough