diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 816a71f255798..702df250999fb 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -1197,6 +1197,19 @@ impl Clone for LinkedList { fn clone(&self) -> Self { self.iter().cloned().collect() } + + fn clone_from(&mut self, other: &Self) { + let mut iter_other = other.iter(); + if self.len() > other.len() { + self.split_off(other.len()); + } + for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) { + elem.clone_from(elem_other); + } + if !iter_other.is_empty() { + self.extend(iter_other.cloned()); + } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index ecb5948f11b36..1001f6bba3b82 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -110,6 +110,49 @@ fn test_append() { check_links(&n); } +#[test] +fn test_clone_from() { + // Short cloned from long + { + let v = vec![1, 2, 3, 4, 5]; + let u = vec![8, 7, 6, 2, 3, 4, 5]; + let mut m = list_from(&v); + let n = list_from(&u); + m.clone_from(&n); + check_links(&m); + assert_eq!(m, n); + for elt in u { + assert_eq!(m.pop_front(), Some(elt)) + } + } + // Long cloned from short + { + let v = vec![1, 2, 3, 4, 5]; + let u = vec![6, 7, 8]; + let mut m = list_from(&v); + let n = list_from(&u); + m.clone_from(&n); + check_links(&m); + assert_eq!(m, n); + for elt in u { + assert_eq!(m.pop_front(), Some(elt)) + } + } + // Two equal length lists + { + let v = vec![1, 2, 3, 4, 5]; + let u = vec![9, 8, 1, 2, 3]; + let mut m = list_from(&v); + let n = list_from(&u); + m.clone_from(&n); + check_links(&m); + assert_eq!(m, n); + for elt in u { + assert_eq!(m.pop_front(), Some(elt)) + } + } +} + #[test] fn test_insert_prev() { let mut m = list_from(&[0, 2, 4, 6, 8]); diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 0c7aa3582ac23..9aea46da68b1a 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1026,7 +1026,8 @@ impl EmitterWriter { children.iter() .map(|sub| self.get_multispan_max_line_num(&sub.span)) .max() - .unwrap_or(primary) + .unwrap_or(0) + .max(primary) } /// Adds a left margin to every line but the first, given a padding length and the label being diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs index 7689ece706695..7dee00b3eca67 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs @@ -70,6 +70,10 @@ impl LocalUseMap { appearances: IndexVec::new(), }; + if live_locals.is_empty() { + return local_use_map; + } + let mut locals_with_use_data: IndexVec = IndexVec::from_elem_n(false, body.local_decls.len()); live_locals.iter().for_each(|&local| locals_with_use_data[local] = true); diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs index 3f2ec1ba97017..a01b528833b2d 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs @@ -36,31 +36,39 @@ pub(super) fn generate<'tcx>( ) { debug!("liveness::generate"); - let live_locals: Vec = if AllFacts::enabled(typeck.tcx()) { - // If "dump facts from NLL analysis" was requested perform - // the liveness analysis for all `Local`s. This case opens - // the possibility of the variables being analyzed in `trace` - // to be *any* `Local`, not just the "live" ones, so we can't - // make any assumptions past this point as to the characteristics - // of the `live_locals`. - // FIXME: Review "live" terminology past this point, we should - // not be naming the `Local`s as live. - body.local_decls.indices().collect() + let free_regions = regions_that_outlive_free_regions( + typeck.infcx.num_region_vars(), + &typeck.borrowck_context.universal_regions, + &typeck.borrowck_context.constraints.outlives_constraints, + ); + let live_locals = compute_live_locals(typeck.tcx(), &free_regions, body); + let facts_enabled = AllFacts::enabled(typeck.tcx()); + + + let polonius_drop_used = if facts_enabled { + let mut drop_used = Vec::new(); + polonius::populate_access_facts( + typeck, + body, + location_table, + move_data, + &mut drop_used, + ); + Some(drop_used) } else { - let free_regions = { - regions_that_outlive_free_regions( - typeck.infcx.num_region_vars(), - &typeck.borrowck_context.universal_regions, - &typeck.borrowck_context.constraints.outlives_constraints, - ) - }; - compute_live_locals(typeck.tcx(), &free_regions, body) + None }; - if !live_locals.is_empty() { - trace::trace(typeck, body, elements, flow_inits, move_data, live_locals); - - polonius::populate_access_facts(typeck, body, location_table, move_data); + if !live_locals.is_empty() || facts_enabled { + trace::trace( + typeck, + body, + elements, + flow_inits, + move_data, + live_locals, + polonius_drop_used, + ); } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs index e37ddbda4be02..526ad7fb905bb 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs @@ -16,7 +16,7 @@ struct UseFactsExtractor<'me> { var_defined: &'me mut VarPointRelations, var_used: &'me mut VarPointRelations, location_table: &'me LocationTable, - var_drop_used: &'me mut VarPointRelations, + var_drop_used: &'me mut Vec<(Local, Location)>, move_data: &'me MoveData<'me>, path_accessed_at: &'me mut MovePathPointRelations, } @@ -39,7 +39,7 @@ impl UseFactsExtractor<'_> { fn insert_drop_use(&mut self, local: Local, location: Location) { debug!("LivenessFactsExtractor::insert_drop_use()"); - self.var_drop_used.push((local, self.location_to_index(location))); + self.var_drop_used.push((local, location)); } fn insert_path_access(&mut self, path: MovePathIndex, location: Location) { @@ -100,6 +100,7 @@ pub(super) fn populate_access_facts( body: &Body<'tcx>, location_table: &LocationTable, move_data: &MoveData<'_>, + drop_used: &mut Vec<(Local, Location)>, ) { debug!("populate_var_liveness_facts()"); @@ -107,12 +108,16 @@ pub(super) fn populate_access_facts( UseFactsExtractor { var_defined: &mut facts.var_defined, var_used: &mut facts.var_used, - var_drop_used: &mut facts.var_drop_used, + var_drop_used: drop_used, path_accessed_at: &mut facts.path_accessed_at, location_table, move_data, } .visit_body(body); + + facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| { + (local, location_table.mid_index(location)) + })); } for (local, local_decl) in body.local_decls.iter_enumerated() { diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs index 36482a7b13534..eacc4d084dbb8 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs @@ -13,7 +13,7 @@ use rustc::traits::query::type_op::outlives::DropckOutlives; use rustc::traits::query::type_op::TypeOp; use rustc::ty::{Ty, TypeFoldable}; use rustc_index::bit_set::HybridBitSet; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use std::rc::Rc; /// This is the heart of the liveness computation. For each variable X @@ -37,6 +37,7 @@ pub(super) fn trace( flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>, move_data: &MoveData<'tcx>, live_locals: Vec, + polonius_drop_used: Option>, ) { debug!("trace()"); @@ -52,7 +53,13 @@ pub(super) fn trace( drop_data: FxHashMap::default(), }; - LivenessResults::new(cx).compute_for_all_locals(live_locals); + let mut results = LivenessResults::new(cx); + + if let Some(drop_used) = polonius_drop_used { + results.add_extra_drop_facts(drop_used, live_locals.iter().copied().collect()) + } + + results.compute_for_all_locals(live_locals); } /// Contextual state for the type-liveness generator. @@ -145,6 +152,32 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { } } + /// Add extra drop facts needed for Polonius. + /// + /// Add facts for all locals with free regions, since regions may outlive + /// the function body only at certain nodes in the CFG. + fn add_extra_drop_facts( + &mut self, + drop_used: Vec<(Local, Location)>, + live_locals: FxHashSet, + ) { + let locations = HybridBitSet::new_empty(self.cx.elements.num_points()); + + for (local, location) in drop_used { + if !live_locals.contains(&local) { + let local_ty = self.cx.body.local_decls[local].ty; + if local_ty.has_free_regions() { + self.cx.add_drop_live_facts_for( + local, + local_ty, + &[location], + &locations, + ); + } + } + } + } + /// Clear the value of fields that are "per local variable". fn reset_local_state(&mut self) { self.defs.clear(); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index b24ba596d7e93..adc3381a1e762 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -276,7 +276,17 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) { self.super_constant(constant, location); - self.sanitize_type(constant, constant.literal.ty); + let ty = self.sanitize_type(constant, constant.literal.ty); + + self.cx.infcx.tcx.for_each_free_region(&ty, |live_region| { + let live_region_vid = + self.cx.borrowck_context.universal_regions.to_region_vid(live_region); + self.cx + .borrowck_context + .constraints + .liveness_constraints + .add_element(live_region_vid, location); + }); if let Some(annotation_index) = constant.user_ty { if let Err(terr) = self.cx.relate_type_and_user_type( @@ -528,25 +538,37 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { let parent_body = mem::replace(&mut self.body, promoted_body); + // Use new sets of constraints and closure bounds so that we can + // modify their locations. let all_facts = &mut None; let mut constraints = Default::default(); let mut closure_bounds = Default::default(); + let mut liveness_constraints = LivenessValues::new( + Rc::new(RegionValueElements::new(promoted_body)), + ); // Don't try to add borrow_region facts for the promoted MIR - mem::swap(self.cx.borrowck_context.all_facts, all_facts); - // Use a new sets of constraints and closure bounds so that we can - // modify their locations. - mem::swap( - &mut self.cx.borrowck_context.constraints.outlives_constraints, - &mut constraints - ); - mem::swap( - &mut self.cx.borrowck_context.constraints.closure_bounds_mapping, - &mut closure_bounds - ); + let mut swap_constraints = |this: &mut Self| { + mem::swap(this.cx.borrowck_context.all_facts, all_facts); + mem::swap( + &mut this.cx.borrowck_context.constraints.outlives_constraints, + &mut constraints + ); + mem::swap( + &mut this.cx.borrowck_context.constraints.closure_bounds_mapping, + &mut closure_bounds + ); + mem::swap( + &mut this.cx.borrowck_context.constraints.liveness_constraints, + &mut liveness_constraints + ); + }; + + swap_constraints(self); self.visit_body(promoted_body); + if !self.errors_reported { // if verifier failed, don't do further checks to avoid ICEs self.cx.typeck_mir(promoted_body); @@ -554,23 +576,15 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { self.body = parent_body; // Merge the outlives constraints back in, at the given location. - mem::swap(self.cx.borrowck_context.all_facts, all_facts); - mem::swap( - &mut self.cx.borrowck_context.constraints.outlives_constraints, - &mut constraints - ); - mem::swap( - &mut self.cx.borrowck_context.constraints.closure_bounds_mapping, - &mut closure_bounds - ); + swap_constraints(self); let locations = location.to_locations(); for constraint in constraints.outlives().iter() { let mut constraint = *constraint; constraint.locations = locations; if let ConstraintCategory::Return - | ConstraintCategory::UseAsConst - | ConstraintCategory::UseAsStatic = constraint.category + | ConstraintCategory::UseAsConst + | ConstraintCategory::UseAsStatic = constraint.category { // "Returning" from a promoted is an assigment to a // temporary from the user's point of view. @@ -578,6 +592,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { } self.cx.borrowck_context.constraints.outlives_constraints.push(constraint) } + for live_region in liveness_constraints.rows() { + self.cx.borrowck_context.constraints.liveness_constraints + .add_element(live_region, location); + } if !closure_bounds.is_empty() { let combined_bounds_mapping = closure_bounds diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs index 61c42a56071e6..9f400713a86d4 100644 --- a/src/libstd/backtrace.rs +++ b/src/libstd/backtrace.rs @@ -113,7 +113,7 @@ pub struct Backtrace { /// The current status of a backtrace, indicating whether it was captured or /// whether it is empty for some other reason. #[non_exhaustive] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub enum BacktraceStatus { /// Capturing a backtrace is not supported, likely because it's not /// implemented for the current platform. diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index 47ee41f0adc16..20a77fa37cf6a 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -519,6 +519,9 @@ declare_features! ( /// Allows the use of or-patterns (e.g., `0 | 1`). (active, or_patterns, "1.38.0", Some(54883), None), + /// Allows the definition of `const extern fn` and `const unsafe extern fn`. + (active, const_extern_fn, "1.40.0", Some(64926), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index d7fc74955bbbd..9e40b1a26ac1a 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -821,6 +821,7 @@ pub fn check_crate(krate: &ast::Crate, gate_all!(async_closure, "async closures are unstable"); gate_all!(yields, generators, "yield syntax is experimental"); gate_all!(or_patterns, "or-patterns syntax is experimental"); + gate_all!(const_extern_fn, "`const extern fn` definitions are unstable"); visit::walk_crate(&mut visitor, krate); } diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index e8d7b7663ed52..4ad0bd06d99ae 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -1220,6 +1220,7 @@ impl<'a> Parser<'a> { err: &mut DiagnosticBuilder<'_>, pat: P, require_name: bool, + is_self_allowed: bool, is_trait_item: bool, ) -> Option { // If we find a pattern followed by an identifier, it could be an (incorrect) @@ -1241,14 +1242,27 @@ impl<'a> Parser<'a> { if require_name && ( is_trait_item || self.token == token::Comma || + self.token == token::Lt || self.token == token::CloseDelim(token::Paren) - ) { // `fn foo(a, b) {}` or `fn foo(usize, usize) {}` - err.span_suggestion( - pat.span, - "if this was a parameter name, give it a type", - format!("{}: TypeName", ident), - Applicability::HasPlaceholders, - ); + ) { // `fn foo(a, b) {}`, `fn foo(a, b) {}` or `fn foo(usize, usize) {}` + if is_self_allowed { + err.span_suggestion( + pat.span, + "if this is a `self` type, give it a parameter name", + format!("self: {}", ident), + Applicability::MaybeIncorrect, + ); + } + // Avoid suggesting that `fn foo(HashMap)` is fixed with a change to + // `fn foo(HashMap: TypeName)`. + if self.token != token::Lt { + err.span_suggestion( + pat.span, + "if this was a parameter name, give it a type", + format!("{}: TypeName", ident), + Applicability::HasPlaceholders, + ); + } err.span_suggestion( pat.span, "if this is a type, explicitly ignore the parameter name", @@ -1256,7 +1270,9 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)"); - return Some(ident); + + // Don't attempt to recover by using the `X` in `X` as the parameter name. + return if self.token == token::Lt { None } else { Some(ident) }; } } None diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index fa4c10431228a..1518da23b096f 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -57,6 +57,8 @@ pub struct GatedSpans { pub yields: Lock>, /// Spans collected for gating `or_patterns`, e.g. `Some(Foo | Bar)`. pub or_patterns: Lock>, + /// Spans collected for gating `const_extern_fn`, e.g. `const extern fn foo`. + pub const_extern_fn: Lock>, } /// Info about a parsing session. diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 95f84d5cb3314..93165b0964903 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1212,6 +1212,7 @@ impl<'a> Parser<'a> { &mut err, pat, is_name_required, + is_self_allowed, is_trait_item, ) { err.emit(); @@ -1486,6 +1487,15 @@ impl<'a> Parser<'a> { Ok(()) } + /// Parses `extern` followed by an optional ABI string, or nothing. + fn parse_extern_abi(&mut self) -> PResult<'a, Abi> { + if self.eat_keyword(kw::Extern) { + Ok(self.parse_opt_abi()?.unwrap_or(Abi::C)) + } else { + Ok(Abi::Rust) + } + } + /// Parses a string as an ABI spec on an extern type or module. Consumes /// the `extern` keyword, if one is found. fn parse_opt_abi(&mut self) -> PResult<'a, Option> { diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index c00a5807d52c5..2ac0352764fa0 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -149,17 +149,24 @@ impl<'a> Parser<'a> { } if self.eat_keyword(kw::Const) { let const_span = self.prev_span; - if self.check_keyword(kw::Fn) - || (self.check_keyword(kw::Unsafe) - && self.is_keyword_ahead(1, &[kw::Fn])) { + if [kw::Fn, kw::Unsafe, kw::Extern].iter().any(|k| self.check_keyword(*k)) { // CONST FUNCTION ITEM + let unsafety = self.parse_unsafety(); - self.bump(); + + if self.check_keyword(kw::Extern) { + self.sess.gated_spans.const_extern_fn.borrow_mut().push( + lo.to(self.token.span) + ); + } + let abi = self.parse_extern_abi()?; + self.bump(); // 'fn' + let header = FnHeader { unsafety, asyncness: respan(const_span, IsAsync::NotAsync), constness: respan(const_span, Constness::Const), - abi: Abi::Rust, + abi, }; return self.parse_item_fn(lo, visibility, attrs, header); } @@ -257,11 +264,7 @@ impl<'a> Parser<'a> { self.bump(); // `unsafe` // `{` is also expected after `unsafe`; in case of error, include it in the diagnostic. self.check(&token::OpenDelim(token::Brace)); - let abi = if self.eat_keyword(kw::Extern) { - self.parse_opt_abi()?.unwrap_or(Abi::C) - } else { - Abi::Rust - }; + let abi = self.parse_extern_abi()?; self.expect_keyword(kw::Fn)?; let fn_span = self.prev_span; let header = FnHeader { @@ -834,11 +837,7 @@ impl<'a> Parser<'a> { let (constness, unsafety, abi) = if is_const_fn { (respan(const_span, Constness::Const), unsafety, Abi::Rust) } else { - let abi = if self.eat_keyword(kw::Extern) { - self.parse_opt_abi()?.unwrap_or(Abi::C) - } else { - Abi::Rust - }; + let abi = self.parse_extern_abi()?; (respan(self.prev_span, Constness::NotConst), unsafety, abi) }; if !self.eat_keyword(kw::Fn) { @@ -1278,14 +1277,30 @@ impl<'a> Parser<'a> { // Treat `const` as `static` for error recovery, but don't add it to expected tokens. if self.check_keyword(kw::Static) || self.token.is_keyword(kw::Const) { if self.token.is_keyword(kw::Const) { - self.diagnostic() - .struct_span_err(self.token.span, "extern items cannot be `const`") - .span_suggestion( + let mut err = self + .struct_span_err(self.token.span, "extern items cannot be `const`"); + + + // The user wrote 'const fn' + if self.is_keyword_ahead(1, &[kw::Fn, kw::Unsafe]) { + err.emit(); + // Consume `const` + self.bump(); + // Consume `unsafe` if present, since `extern` blocks + // don't allow it. This will leave behind a plain 'fn' + self.eat_keyword(kw::Unsafe); + // Treat 'const fn` as a plain `fn` for error recovery purposes. + // We've already emitted an error, so compilation is guaranteed + // to fail + return Ok(self.parse_item_foreign_fn(visibility, lo, attrs, extern_sp)?); + } + err.span_suggestion( self.token.span, "try using a static value", "static".to_owned(), Applicability::MachineApplicable - ).emit(); + ); + err.emit(); } self.bump(); // `static` or `const` return Ok(self.parse_item_foreign_static(visibility, lo, attrs)?); diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 82c47e6dbb758..cc95dcb3c4484 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -196,6 +196,7 @@ symbols! { console, const_compare_raw_pointers, const_constructor, + const_extern_fn, const_fn, const_fn_union, const_generics, diff --git a/src/test/ui/anon-params-denied-2018.stderr b/src/test/ui/anon-params-denied-2018.stderr index a58998e4891e0..3fcf41a9a60a2 100644 --- a/src/test/ui/anon-params-denied-2018.stderr +++ b/src/test/ui/anon-params-denied-2018.stderr @@ -5,6 +5,10 @@ LL | fn foo(i32); | ^ expected one of `:`, `@`, or `|` here | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn foo(self: i32); + | ^^^^^^^^^ help: if this was a parameter name, give it a type | LL | fn foo(i32: TypeName); @@ -21,6 +25,10 @@ LL | fn bar_with_default_impl(String, String) {} | ^ expected one of `:`, `@`, or `|` here | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn bar_with_default_impl(self: String, String) {} + | ^^^^^^^^^^^^ help: if this was a parameter name, give it a type | LL | fn bar_with_default_impl(String: TypeName, String) {} diff --git a/src/test/ui/async-await/async-borrowck-escaping-closure-error.polonius.stderr b/src/test/ui/async-await/async-borrowck-escaping-closure-error.polonius.stderr deleted file mode 100644 index 5f20367b6aba9..0000000000000 --- a/src/test/ui/async-await/async-borrowck-escaping-closure-error.polonius.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0597]: `x` does not live long enough - --> $DIR/async-borrowck-escaping-closure-error.rs:5:24 - | -LL | Box::new((async || x)()) - | -------------------^---- - | | | | - | | | borrowed value does not live long enough - | | value captured here - | borrow later used here -LL | -LL | } - | - `x` dropped here while still borrowed - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr deleted file mode 100644 index 89af8764557ff..0000000000000 --- a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0597]: `books` does not live long enough - --> $DIR/borrowck-escaping-closure-error-2.rs:11:17 - | -LL | Box::new(|| books.push(4)) - | ------------^^^^^--------- - | | | | - | | | borrowed value does not live long enough - | | value captured here - | borrow later used here -LL | -LL | } - | - `books` dropped here while still borrowed - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr deleted file mode 100644 index a5b2e8762746c..0000000000000 --- a/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr +++ /dev/null @@ -1,59 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/promote-ref-mut-in-let-issue-46557.rs:5:21 - | -LL | let ref mut x = 1234543; - | ^^^^^^^ creates a temporary which is freed while still in use -LL | x - | - borrow later used here -LL | } - | - temporary value is freed at the end of this statement - | - = note: consider using a `let` binding to create a longer lived value - -error[E0716]: temporary value dropped while borrowed - --> $DIR/promote-ref-mut-in-let-issue-46557.rs:10:25 - | -LL | let (ref mut x, ) = (1234543, ); - | ^^^^^^^^^^^ creates a temporary which is freed while still in use -LL | x - | - borrow later used here -LL | } - | - temporary value is freed at the end of this statement - | - = note: consider using a `let` binding to create a longer lived value - -error[E0515]: cannot return value referencing temporary value - --> $DIR/promote-ref-mut-in-let-issue-46557.rs:15:5 - | -LL | match 1234543 { - | ^ ------- temporary value created here - | _____| - | | -LL | | ref mut x => x -LL | | } - | |_____^ returns a value referencing data owned by the current function - -error[E0515]: cannot return value referencing temporary value - --> $DIR/promote-ref-mut-in-let-issue-46557.rs:21:5 - | -LL | match (123443,) { - | ^ --------- temporary value created here - | _____| - | | -LL | | (ref mut x,) => x, -LL | | } - | |_____^ returns a value referencing data owned by the current function - -error[E0515]: cannot return reference to temporary value - --> $DIR/promote-ref-mut-in-let-issue-46557.rs:27:5 - | -LL | &mut 1234543 - | ^^^^^------- - | | | - | | temporary value created here - | returns a reference to data owned by the current function - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0515, E0716. -For more information about an error, try `rustc --explain E0515`. diff --git a/src/test/ui/borrowck/return-local-binding-from-desugaring.polonius.stderr b/src/test/ui/borrowck/return-local-binding-from-desugaring.polonius.stderr deleted file mode 100644 index c818379762c9d..0000000000000 --- a/src/test/ui/borrowck/return-local-binding-from-desugaring.polonius.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/return-local-binding-from-desugaring.rs:26:18 - | -LL | for ref x in xs { - | ^^ creates a temporary which is freed while still in use -... -LL | } - | - temporary value is freed at the end of this statement -LL | result - | ------ borrow later used here - | - = note: consider using a `let` binding to create a longer lived value - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr b/src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr deleted file mode 100644 index 7b246426a2333..0000000000000 --- a/src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr +++ /dev/null @@ -1,148 +0,0 @@ -error[E0503]: cannot use `self.cx` because it was mutably borrowed - --> $DIR/two-phase-surprise-no-conflict.rs:21:23 - | -LL | let _mut_borrow = &mut *self; - | ---------- borrow of `*self` occurs here -LL | let _access = self.cx; - | ^^^^^^^ use of borrowed `*self` -LL | -LL | _mut_borrow; - | ----------- borrow later used here - -error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-surprise-no-conflict.rs:57:17 - | -LL | self.hash_expr(&self.cx_mut.body(eid).value); - | ^^^^^---------^^-----------^^^^^^^^^^^^^^^^^ - | | | | - | | | immutable borrow occurs here - | | immutable borrow later used by call - | mutable borrow occurs here - -error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time - --> $DIR/two-phase-surprise-no-conflict.rs:119:51 - | -LL | reg.register_static(Box::new(TrivialPass::new(&mut reg.sess_mut))); - | --- --------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here - | | | - | | first borrow later used by call - | first mutable borrow occurs here - -error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time - --> $DIR/two-phase-surprise-no-conflict.rs:122:54 - | -LL | reg.register_bound(Box::new(TrivialPass::new_mut(&mut reg.sess_mut))); - | --- -------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here - | | | - | | first borrow later used by call - | first mutable borrow occurs here - -error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time - --> $DIR/two-phase-surprise-no-conflict.rs:125:53 - | -LL | reg.register_univ(Box::new(TrivialPass::new_mut(&mut reg.sess_mut))); - | --- ------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here - | | | - | | first borrow later used by call - | first mutable borrow occurs here - -error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time - --> $DIR/two-phase-surprise-no-conflict.rs:128:44 - | -LL | reg.register_ref(&TrivialPass::new_mut(&mut reg.sess_mut)); - | --- ------------ ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here - | | | - | | first borrow later used by call - | first mutable borrow occurs here - -error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-surprise-no-conflict.rs:138:5 - | -LL | reg.register_bound(Box::new(CapturePass::new(®.sess_mut))); - | ^^^^--------------^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^ - | | | | - | | | immutable borrow occurs here - | | immutable borrow later used by call - | mutable borrow occurs here - -error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-surprise-no-conflict.rs:141:5 - | -LL | reg.register_univ(Box::new(CapturePass::new(®.sess_mut))); - | ^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^ - | | | | - | | | immutable borrow occurs here - | | immutable borrow later used by call - | mutable borrow occurs here - -error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-surprise-no-conflict.rs:144:5 - | -LL | reg.register_ref(&CapturePass::new(®.sess_mut)); - | ^^^^------------^^^^^^^^^^^^^^^^^^^-------------^^ - | | | | - | | | immutable borrow occurs here - | | immutable borrow later used by call - | mutable borrow occurs here - -error[E0499]: cannot borrow `*reg` as mutable more than once at a time - --> $DIR/two-phase-surprise-no-conflict.rs:154:5 - | -LL | reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); - | ^^^^--------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^ - | | | | - | | | first mutable borrow occurs here - | | first borrow later used by call - | second mutable borrow occurs here - -error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time - --> $DIR/two-phase-surprise-no-conflict.rs:154:54 - | -LL | reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); - | --- -------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here - | | | - | | first borrow later used by call - | first mutable borrow occurs here - -error[E0499]: cannot borrow `*reg` as mutable more than once at a time - --> $DIR/two-phase-surprise-no-conflict.rs:158:5 - | -LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); - | ^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^ - | | | | - | | | first mutable borrow occurs here - | | first borrow later used by call - | second mutable borrow occurs here - -error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time - --> $DIR/two-phase-surprise-no-conflict.rs:158:53 - | -LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); - | --- ------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here - | | | - | | first borrow later used by call - | first mutable borrow occurs here - -error[E0499]: cannot borrow `*reg` as mutable more than once at a time - --> $DIR/two-phase-surprise-no-conflict.rs:162:5 - | -LL | reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut)); - | ^^^^------------^^^^^^^^^^^^^^^^^^^^^^^-----------------^^ - | | | | - | | | first mutable borrow occurs here - | | first borrow later used by call - | second mutable borrow occurs here - -error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time - --> $DIR/two-phase-surprise-no-conflict.rs:162:44 - | -LL | reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut)); - | --- ------------ ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here - | | | - | | first borrow later used by call - | first mutable borrow occurs here - -error: aborting due to 15 previous errors - -Some errors have detailed explanations: E0499, E0502, E0503. -For more information about an error, try `rustc --explain E0499`. diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.rs b/src/test/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.rs new file mode 100644 index 0000000000000..7c6a574a2110f --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.rs @@ -0,0 +1,23 @@ +#![feature(const_extern_fn)] + +extern "C" { + fn regular_in_block(); +} + +const extern fn bar() { + unsafe { + regular_in_block(); + //~^ ERROR: cannot call functions with `"C"` abi in `min_const_fn` + } +} + +extern fn regular() {} + +const extern fn foo() { + unsafe { + regular(); + //~^ ERROR: cannot call functions with `"C"` abi in `min_const_fn` + } +} + +fn main() {} diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr new file mode 100644 index 0000000000000..d8bdf0a57cf66 --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr @@ -0,0 +1,21 @@ +error[E0723]: cannot call functions with `"C"` abi in `min_const_fn` + --> $DIR/const-extern-fn-call-extern-fn.rs:9:9 + | +LL | regular_in_block(); + | ^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add `#![feature(const_fn)]` to the crate attributes to enable + +error[E0723]: cannot call functions with `"C"` abi in `min_const_fn` + --> $DIR/const-extern-fn-call-extern-fn.rs:18:9 + | +LL | regular(); + | ^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add `#![feature(const_fn)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0723`. diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs new file mode 100644 index 0000000000000..5619811768801 --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs @@ -0,0 +1,13 @@ +#![feature(const_extern_fn)] + +const extern fn unsize(x: &[u8; 3]) -> &[u8] { x } +//~^ ERROR unsizing casts are not allowed in const fn +const unsafe extern "C" fn closure() -> fn() { || {} } +//~^ ERROR function pointers in const fn are unstable +const unsafe extern fn use_float() { 1.0 + 1.0; } +//~^ ERROR only int, `bool` and `char` operations are stable in const fn +const extern "C" fn ptr_cast(val: *const u8) { val as usize; } +//~^ ERROR casting pointers to ints is unstable in const fn + + +fn main() {} diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr new file mode 100644 index 0000000000000..0ab1ddd8d5225 --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr @@ -0,0 +1,39 @@ +error[E0723]: unsizing casts are not allowed in const fn + --> $DIR/const-extern-fn-min-const-fn.rs:3:48 + | +LL | const extern fn unsize(x: &[u8; 3]) -> &[u8] { x } + | ^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add `#![feature(const_fn)]` to the crate attributes to enable + +error[E0723]: function pointers in const fn are unstable + --> $DIR/const-extern-fn-min-const-fn.rs:5:41 + | +LL | const unsafe extern "C" fn closure() -> fn() { || {} } + | ^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add `#![feature(const_fn)]` to the crate attributes to enable + +error[E0723]: only int, `bool` and `char` operations are stable in const fn + --> $DIR/const-extern-fn-min-const-fn.rs:7:38 + | +LL | const unsafe extern fn use_float() { 1.0 + 1.0; } + | ^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add `#![feature(const_fn)]` to the crate attributes to enable + +error[E0723]: casting pointers to ints is unstable in const fn + --> $DIR/const-extern-fn-min-const-fn.rs:9:48 + | +LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; } + | ^^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add `#![feature(const_fn)]` to the crate attributes to enable + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0723`. diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs new file mode 100644 index 0000000000000..cab175bbfa818 --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs @@ -0,0 +1,10 @@ +#![feature(const_extern_fn)] + +const unsafe extern fn foo() -> usize { 5 } + +fn main() { + let a: [u8; foo()]; + //~^ ERROR call to unsafe function is unsafe and requires unsafe function or block + foo(); + //~^ ERROR call to unsafe function is unsafe and requires unsafe function or block +} diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.stderr new file mode 100644 index 0000000000000..5196b8ee0a21d --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.stderr @@ -0,0 +1,19 @@ +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/const-extern-fn-requires-unsafe.rs:8:5 + | +LL | foo(); + | ^^^^^ 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/const-extern-fn-requires-unsafe.rs:6:17 + | +LL | let a: [u8; foo()]; + | ^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn.rs b/src/test/ui/consts/const-extern-fn/const-extern-fn.rs new file mode 100644 index 0000000000000..1dc0f83cadf7d --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn.rs @@ -0,0 +1,35 @@ +// run-pass +#![feature(const_extern_fn)] + +const extern fn foo1(val: u8) -> u8 { + val + 1 +} + +const extern "C" fn foo2(val: u8) -> u8 { + val + 1 +} + +const unsafe extern fn bar1(val: bool) -> bool { + !val +} + +const unsafe extern "C" fn bar2(val: bool) -> bool { + !val +} + + +fn main() { + let a: [u8; foo1(25) as usize] = [0; 26]; + let b: [u8; foo2(25) as usize] = [0; 26]; + assert_eq!(a, b); + + let bar1_res = unsafe { bar1(false) }; + let bar2_res = unsafe { bar2(false) }; + assert!(bar1_res); + assert_eq!(bar1_res, bar2_res); + + let _foo1_cast: extern fn(u8) -> u8 = foo1; + let _foo2_cast: extern fn(u8) -> u8 = foo2; + let _bar1_cast: unsafe extern fn(bool) -> bool = bar1; + let _bar2_cast: unsafe extern fn(bool) -> bool = bar2; +} diff --git a/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs b/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs new file mode 100644 index 0000000000000..d39f2c1fe277e --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs @@ -0,0 +1,12 @@ +// Check that `const extern fn` and `const unsafe extern fn` are feature-gated. + +#[cfg(FALSE)] const extern fn foo1() {} //~ ERROR `const extern fn` definitions are unstable +#[cfg(FALSE)] const extern "C" fn foo2() {} //~ ERROR `const extern fn` definitions are unstable +#[cfg(FALSE)] const extern "Rust" fn foo3() {} //~ ERROR `const extern fn` definitions are unstable +#[cfg(FALSE)] const unsafe extern fn bar1() {} //~ ERROR `const extern fn` definitions are unstable +#[cfg(FALSE)] const unsafe extern "C" fn bar2() {} +//~^ ERROR `const extern fn` definitions are unstable +#[cfg(FALSE)] const unsafe extern "Rust" fn bar3() {} +//~^ ERROR `const extern fn` definitions are unstable + +fn main() {} diff --git a/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.stderr b/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.stderr new file mode 100644 index 0000000000000..f138620ffefba --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.stderr @@ -0,0 +1,57 @@ +error[E0658]: `const extern fn` definitions are unstable + --> $DIR/feature-gate-const_extern_fn.rs:3:15 + | +LL | #[cfg(FALSE)] const extern fn foo1() {} + | ^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/64926 + = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable + +error[E0658]: `const extern fn` definitions are unstable + --> $DIR/feature-gate-const_extern_fn.rs:4:15 + | +LL | #[cfg(FALSE)] const extern "C" fn foo2() {} + | ^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/64926 + = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable + +error[E0658]: `const extern fn` definitions are unstable + --> $DIR/feature-gate-const_extern_fn.rs:5:15 + | +LL | #[cfg(FALSE)] const extern "Rust" fn foo3() {} + | ^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/64926 + = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable + +error[E0658]: `const extern fn` definitions are unstable + --> $DIR/feature-gate-const_extern_fn.rs:6:15 + | +LL | #[cfg(FALSE)] const unsafe extern fn bar1() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/64926 + = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable + +error[E0658]: `const extern fn` definitions are unstable + --> $DIR/feature-gate-const_extern_fn.rs:7:15 + | +LL | #[cfg(FALSE)] const unsafe extern "C" fn bar2() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/64926 + = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable + +error[E0658]: `const extern fn` definitions are unstable + --> $DIR/feature-gate-const_extern_fn.rs:9:15 + | +LL | #[cfg(FALSE)] const unsafe extern "Rust" fn bar3() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/64926 + = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/promote_const_let.polonius.stderr b/src/test/ui/consts/promote_const_let.polonius.stderr deleted file mode 100644 index cf41bd7bdb1eb..0000000000000 --- a/src/test/ui/consts/promote_const_let.polonius.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0597]: `y` does not live long enough - --> $DIR/promote_const_let.rs:4:9 - | -LL | let x: &'static u32 = { - | - borrow later stored here -LL | let y = 42; -LL | &y - | ^^ borrowed value does not live long enough -LL | }; - | - `y` dropped here while still borrowed - -error[E0716]: temporary value dropped while borrowed - --> $DIR/promote_const_let.rs:6:28 - | -LL | let x: &'static u32 = &{ - | ____________------------____^ - | | | - | | type annotation requires that borrow lasts for `'static` -LL | | let y = 42; -LL | | y -LL | | }; - | |_____^ creates a temporary which is freed while still in use -LL | } - | - temporary value is freed at the end of this statement - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0597, E0716. -For more information about an error, try `rustc --explain E0597`. diff --git a/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr b/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr deleted file mode 100644 index 5e93a0234259c..0000000000000 --- a/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr +++ /dev/null @@ -1,78 +0,0 @@ -error[E0597]: `o2` does not live long enough - --> $DIR/dropck_trait_cycle_checked.rs:111:13 - | -LL | o1.set0(&o2); - | ^^^ borrowed value does not live long enough -... -LL | } - | - - | | - | `o2` dropped here while still borrowed - | borrow might be used here, when `o1` is dropped and runs the destructor for type `std::boxed::Box>` - | - = note: values in a scope are dropped in the opposite order they are defined - -error[E0597]: `o3` does not live long enough - --> $DIR/dropck_trait_cycle_checked.rs:112:13 - | -LL | o1.set1(&o3); - | ^^^ borrowed value does not live long enough -... -LL | } - | - - | | - | `o3` dropped here while still borrowed - | borrow might be used here, when `o1` is dropped and runs the destructor for type `std::boxed::Box>` - | - = note: values in a scope are dropped in the opposite order they are defined - -error[E0597]: `o2` does not live long enough - --> $DIR/dropck_trait_cycle_checked.rs:113:13 - | -LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -------- cast requires that `o2` is borrowed for `'static` -... -LL | o2.set0(&o2); - | ^^^ borrowed value does not live long enough -... -LL | } - | - `o2` dropped here while still borrowed - -error[E0597]: `o3` does not live long enough - --> $DIR/dropck_trait_cycle_checked.rs:114:13 - | -LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -------- cast requires that `o3` is borrowed for `'static` -... -LL | o2.set1(&o3); - | ^^^ borrowed value does not live long enough -... -LL | } - | - `o3` dropped here while still borrowed - -error[E0597]: `o1` does not live long enough - --> $DIR/dropck_trait_cycle_checked.rs:115:13 - | -LL | o3.set0(&o1); - | ^^^ borrowed value does not live long enough -LL | o3.set1(&o2); -LL | } - | - - | | - | `o1` dropped here while still borrowed - | borrow might be used here, when `o1` is dropped and runs the destructor for type `std::boxed::Box>` - -error[E0597]: `o2` does not live long enough - --> $DIR/dropck_trait_cycle_checked.rs:116:13 - | -LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -------- cast requires that `o2` is borrowed for `'static` -... -LL | o3.set1(&o2); - | ^^^ borrowed value does not live long enough -LL | } - | - `o2` dropped here while still borrowed - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr deleted file mode 100644 index 530bf368f676e..0000000000000 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0597]: `b` does not live long enough - --> $DIR/ref-escapes-but-not-over-yield.rs:11:13 - | -LL | let mut b = move || { - | _________________- -LL | | yield(); -LL | | let b = 5; -LL | | a = &b; - | | ^^ borrowed value does not live long enough -LL | | -LL | | }; - | | - - | | | - | | `b` dropped here while still borrowed - | |_____... and the borrow might be used here, when that temporary is dropped and runs the destructor for generator - | a temporary with access to the borrow is created here ... - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/hrtb/due-to-where-clause.nll.stderr b/src/test/ui/hrtb/due-to-where-clause.nll.stderr new file mode 100644 index 0000000000000..e476047a7a644 --- /dev/null +++ b/src/test/ui/hrtb/due-to-where-clause.nll.stderr @@ -0,0 +1,8 @@ +error: higher-ranked subtype error + --> $DIR/due-to-where-clause.rs:2:5 + | +LL | test::(&mut 42); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/hrtb/due-to-where-clause.rs b/src/test/ui/hrtb/due-to-where-clause.rs index 04e2ddd4a6090..1afd15613b51c 100644 --- a/src/test/ui/hrtb/due-to-where-clause.rs +++ b/src/test/ui/hrtb/due-to-where-clause.rs @@ -1,6 +1,3 @@ -// ignore-compare-mode-nll -// ^ This code works in nll mode. - fn main() { test::(&mut 42); //~ ERROR implementation of `Foo` is not general enough } diff --git a/src/test/ui/hrtb/due-to-where-clause.stderr b/src/test/ui/hrtb/due-to-where-clause.stderr index 9fef1e3354399..e4096ec059a6e 100644 --- a/src/test/ui/hrtb/due-to-where-clause.stderr +++ b/src/test/ui/hrtb/due-to-where-clause.stderr @@ -1,5 +1,5 @@ error: implementation of `Foo` is not general enough - --> $DIR/due-to-where-clause.rs:5:5 + --> $DIR/due-to-where-clause.rs:2:5 | LL | test::(&mut 42); | ^^^^^^^^^^^^ implementation of `Foo` is not general enough diff --git a/src/test/ui/nll/get_default.polonius.stderr b/src/test/ui/nll/get_default.polonius.stderr index 2df6d5d61fc46..476d86cfba9c3 100644 --- a/src/test/ui/nll/get_default.polonius.stderr +++ b/src/test/ui/nll/get_default.polonius.stderr @@ -1,6 +1,9 @@ error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable --> $DIR/get_default.rs:32:17 | +LL | fn err(map: &mut Map) -> &String { + | - let's call the lifetime of this reference `'1` +LL | loop { LL | match map.get() { | --- immutable borrow occurs here LL | Some(v) => { @@ -8,7 +11,7 @@ LL | map.set(String::new()); // Both AST and MIR error here | ^^^ mutable borrow occurs here LL | LL | return v; - | - immutable borrow later used here + | - returning this value requires that `*map` is borrowed for `'1` error: aborting due to previous error diff --git a/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr b/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr deleted file mode 100644 index eb8442b31d7c7..0000000000000 --- a/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0506]: cannot assign to `data.0` because it is borrowed - --> $DIR/loan_ends_mid_block_pair.rs:12:5 - | -LL | let c = &mut data.0; - | ----------- borrow of `data.0` occurs here -LL | capitalize(c); -LL | data.0 = 'e'; - | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here -... -LL | capitalize(c); - | - borrow later used here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/polonius/polonius-smoke-test.stderr b/src/test/ui/nll/polonius/polonius-smoke-test.stderr index dbc5b7a019a69..1faf8e2212aab 100644 --- a/src/test/ui/nll/polonius/polonius-smoke-test.stderr +++ b/src/test/ui/nll/polonius/polonius-smoke-test.stderr @@ -17,12 +17,14 @@ LL | let w = y; error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/polonius-smoke-test.rs:19:13 | +LL | pub fn use_while_mut_fr(x: &mut i32) -> &mut i32 { + | - let's call the lifetime of this reference `'1` LL | let y = &mut *x; | ------- borrow of `*x` occurs here LL | let z = x; | ^ move out of `x` occurs here LL | y - | - borrow later used here + | - returning this value requires that `*x` is borrowed for `'1` error[E0505]: cannot move out of `s` because it is borrowed --> $DIR/polonius-smoke-test.rs:43:5 diff --git a/src/test/ui/nll/promoted-liveness.rs b/src/test/ui/nll/promoted-liveness.rs new file mode 100644 index 0000000000000..e5a8e1e5c2fcc --- /dev/null +++ b/src/test/ui/nll/promoted-liveness.rs @@ -0,0 +1,8 @@ +// Test that promoted that have larger mir bodies than their containing function +// don't cause an ICE. + +// check-pass + +fn main() { + &["0", "1", "2", "3", "4", "5", "6", "7"]; +} diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr b/src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr deleted file mode 100644 index 8e3cf59cffb44..0000000000000 --- a/src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/return-ref-mut-issue-46557.rs:4:21 - | -LL | let ref mut x = 1234543; - | ^^^^^^^ creates a temporary which is freed while still in use -LL | x - | - borrow later used here -LL | } - | - temporary value is freed at the end of this statement - | - = note: consider using a `let` binding to create a longer lived value - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/parser/no-const-fn-in-extern-block.rs b/src/test/ui/parser/no-const-fn-in-extern-block.rs new file mode 100644 index 0000000000000..29f26389ded18 --- /dev/null +++ b/src/test/ui/parser/no-const-fn-in-extern-block.rs @@ -0,0 +1,8 @@ +extern { + const fn foo(); + //~^ ERROR extern items cannot be `const` + const unsafe fn bar(); + //~^ ERROR extern items cannot be `const` +} + +fn main() {} diff --git a/src/test/ui/parser/no-const-fn-in-extern-block.stderr b/src/test/ui/parser/no-const-fn-in-extern-block.stderr new file mode 100644 index 0000000000000..5b4663a702f06 --- /dev/null +++ b/src/test/ui/parser/no-const-fn-in-extern-block.stderr @@ -0,0 +1,14 @@ +error: extern items cannot be `const` + --> $DIR/no-const-fn-in-extern-block.rs:2:5 + | +LL | const fn foo(); + | ^^^^^ + +error: extern items cannot be `const` + --> $DIR/no-const-fn-in-extern-block.rs:4:5 + | +LL | const unsafe fn bar(); + | ^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/pat-lt-bracket-2.stderr b/src/test/ui/parser/pat-lt-bracket-2.stderr index dbc8d0f5865c6..2191e31ad1ff2 100644 --- a/src/test/ui/parser/pat-lt-bracket-2.stderr +++ b/src/test/ui/parser/pat-lt-bracket-2.stderr @@ -3,6 +3,12 @@ error: expected one of `:`, `@`, or `|`, found `<` | LL | fn a(B<) {} | ^ expected one of `:`, `@`, or `|` here + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a type, explicitly ignore the parameter name + | +LL | fn a(_: B<) {} + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/reify-intrinsic.stderr b/src/test/ui/reify-intrinsic.stderr index 4a1bd77cf7ee9..a4fa451e8cbad 100644 --- a/src/test/ui/reify-intrinsic.stderr +++ b/src/test/ui/reify-intrinsic.stderr @@ -8,9 +8,9 @@ LL | let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::tr | help: use parentheses to call this function: `std::mem::transmute(...)` | = note: expected type `unsafe extern "rust-intrinsic" fn(isize) -> usize` - found type `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` + found type `unsafe extern "rust-intrinsic" fn(_) -> _ {std::mem::transmute::<_, _>}` -error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid +error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {std::mem::transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid --> $DIR/reify-intrinsic.rs:11:13 | LL | let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize; diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr index 9860e9805b2ed..e4248f3b974b9 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr @@ -5,6 +5,10 @@ LL | trait Trait2015 { fn foo(#[allow(C)] i32); } | ^ expected one of `:`, `@`, or `|` here | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | trait Trait2015 { fn foo(#[allow(C)] self: i32); } + | ^^^^^^^^^ help: if this was a parameter name, give it a type | LL | trait Trait2015 { fn foo(#[allow(C)] i32: TypeName); } diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr index cc0eccd37a26f..8d4a66f142d2c 100644 --- a/src/test/ui/span/issue-34264.stderr +++ b/src/test/ui/span/issue-34264.stderr @@ -3,6 +3,12 @@ error: expected one of `:`, `@`, or `|`, found `<` | LL | fn foo(Option, String) {} | ^ expected one of `:`, `@`, or `|` here + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a type, explicitly ignore the parameter name + | +LL | fn foo(_: Option, String) {} + | ^^^^^^^^^ error: expected one of `:`, `@`, or `|`, found `)` --> $DIR/issue-34264.rs:1:27 diff --git a/src/test/ui/suggestions/issue-64252-self-type.rs b/src/test/ui/suggestions/issue-64252-self-type.rs new file mode 100644 index 0000000000000..128d5e85c22c8 --- /dev/null +++ b/src/test/ui/suggestions/issue-64252-self-type.rs @@ -0,0 +1,14 @@ +// This test checks that a suggestion to add a `self: ` parameter name is provided +// to functions where this is applicable. + +pub fn foo(Box) { } +//~^ ERROR expected one of `:`, `@`, or `|`, found `<` + +struct Bar; + +impl Bar { + fn bar(Box) { } + //~^ ERROR expected one of `:`, `@`, or `|`, found `<` +} + +fn main() { } diff --git a/src/test/ui/suggestions/issue-64252-self-type.stderr b/src/test/ui/suggestions/issue-64252-self-type.stderr new file mode 100644 index 0000000000000..fa28a0d684e5e --- /dev/null +++ b/src/test/ui/suggestions/issue-64252-self-type.stderr @@ -0,0 +1,30 @@ +error: expected one of `:`, `@`, or `|`, found `<` + --> $DIR/issue-64252-self-type.rs:4:15 + | +LL | pub fn foo(Box) { } + | ^ expected one of `:`, `@`, or `|` here + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a type, explicitly ignore the parameter name + | +LL | pub fn foo(_: Box) { } + | ^^^^^^ + +error: expected one of `:`, `@`, or `|`, found `<` + --> $DIR/issue-64252-self-type.rs:10:15 + | +LL | fn bar(Box) { } + | ^ expected one of `:`, `@`, or `|` here + | + = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) +help: if this is a `self` type, give it a parameter name + | +LL | fn bar(self: Box) { } + | ^^^^^^^^^ +help: if this is a type, explicitly ignore the parameter name + | +LL | fn bar(_: Box) { } + | ^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr deleted file mode 100644 index 4b906f75149af..0000000000000 --- a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr +++ /dev/null @@ -1,60 +0,0 @@ -error[E0597]: `factorial` does not live long enough - --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:15:17 - | -LL | let f = |x: u32| -> u32 { - | --------------- value captured here -LL | let g = factorial.as_ref().unwrap(); - | ^^^^^^^^^ borrowed value does not live long enough -... -LL | } - | - - | | - | `factorial` dropped here while still borrowed - | borrow might be used here, when `factorial` is dropped and runs the destructor for type `std::option::Option u32>>` - -error[E0506]: cannot assign to `factorial` because it is borrowed - --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:20:5 - | -LL | let f = |x: u32| -> u32 { - | --------------- borrow of `factorial` occurs here -LL | let g = factorial.as_ref().unwrap(); - | --------- borrow occurs due to use in closure -... -LL | factorial = Some(Box::new(f)); - | ^^^^^^^^^ - | | - | assignment to borrowed `factorial` occurs here - | borrow later used here - -error[E0597]: `factorial` does not live long enough - --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:28:17 - | -LL | let f = |x: u32| -> u32 { - | --------------- value captured here -LL | let g = factorial.as_ref().unwrap(); - | ^^^^^^^^^ borrowed value does not live long enough -... -LL | } - | - - | | - | `factorial` dropped here while still borrowed - | borrow might be used here, when `factorial` is dropped and runs the destructor for type `std::option::Option u32>>` - -error[E0506]: cannot assign to `factorial` because it is borrowed - --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:33:5 - | -LL | let f = |x: u32| -> u32 { - | --------------- borrow of `factorial` occurs here -LL | let g = factorial.as_ref().unwrap(); - | --------- borrow occurs due to use in closure -... -LL | factorial = Some(Box::new(f)); - | ^^^^^^^^^ - | | - | assignment to borrowed `factorial` occurs here - | borrow later used here - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0506, E0597. -For more information about an error, try `rustc --explain E0506`. diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index e01184e3658b5..337f9c4d6dbed 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -53,6 +53,9 @@ fn filter_dirs(path: &Path) -> bool { "src/tools/rls", "src/tools/rust-installer", "src/tools/rustfmt", + + // Filter RLS output directories + "target/rls", ]; skip.iter().any(|p| path.ends_with(p)) }