diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 46683d2d25867..60eacde1c723d 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -31,16 +31,6 @@ pub fn is_builtin_attr(attr: &Attribute) -> bool { attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) } -enum AttrError { - MultipleItem(String), - UnknownMetaItem(String, &'static [&'static str]), - MissingSince, - NonIdentFeature, - MissingFeature, - MultipleStabilityLevels, - UnsupportedLiteral(UnsupportedLiteralReason, /* is_bytestr */ bool), -} - pub(crate) enum UnsupportedLiteralReason { Generic, CfgString, @@ -48,37 +38,6 @@ pub(crate) enum UnsupportedLiteralReason { DeprecatedKvPair, } -fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { - match error { - AttrError::MultipleItem(item) => { - sess.emit_err(session_diagnostics::MultipleItem { span, item }); - } - AttrError::UnknownMetaItem(item, expected) => { - sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected }); - } - AttrError::MissingSince => { - sess.emit_err(session_diagnostics::MissingSince { span }); - } - AttrError::NonIdentFeature => { - sess.emit_err(session_diagnostics::NonIdentFeature { span }); - } - AttrError::MissingFeature => { - sess.emit_err(session_diagnostics::MissingFeature { span }); - } - AttrError::MultipleStabilityLevels => { - sess.emit_err(session_diagnostics::MultipleStabilityLevels { span }); - } - AttrError::UnsupportedLiteral(reason, is_bytestr) => { - sess.emit_err(session_diagnostics::UnsupportedLiteral { - span, - reason, - is_bytestr, - start_point_span: sess.source_map().start_point(span), - }); - } - } -} - #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum InlineAttr { None, @@ -241,7 +200,7 @@ pub fn find_stability( sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true, sym::unstable => { if stab.is_some() { - handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); + sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span }); break; } @@ -251,7 +210,7 @@ pub fn find_stability( } sym::stable => { if stab.is_some() { - handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); + sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span }); break; } if let Some((feature, level)) = parse_stability(sess, attr) { @@ -295,7 +254,7 @@ pub fn find_const_stability( sym::rustc_promotable => promotable = true, sym::rustc_const_unstable => { if const_stab.is_some() { - handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); + sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span }); break; } @@ -306,7 +265,7 @@ pub fn find_const_stability( } sym::rustc_const_stable => { if const_stab.is_some() { - handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); + sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span }); break; } if let Some((feature, level)) = parse_stability(sess, attr) { @@ -340,7 +299,7 @@ pub fn find_body_stability( for attr in attrs { if attr.has_name(sym::rustc_default_body_unstable) { if body_stab.is_some() { - handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); + sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span }); break; } @@ -355,11 +314,10 @@ pub fn find_body_stability( fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option) -> Option<()> { if item.is_some() { - handle_errors( - &sess.parse_sess, - meta.span, - AttrError::MultipleItem(pprust::path_to_string(&meta.path)), - ); + sess.emit_err(session_diagnostics::MultipleItem { + span: meta.span, + item: pprust::path_to_string(&meta.path), + }); None } else if let Some(v) = meta.value_str() { *item = Some(v); @@ -380,11 +338,12 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit let mut since = None; for meta in metas { let Some(mi) = meta.meta_item() else { - handle_errors( - &sess.parse_sess, - meta.span(), - AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), - ); + sess.emit_err(session_diagnostics::UnsupportedLiteral { + span: meta.span(), + reason: UnsupportedLiteralReason::Generic, + is_bytestr: false, + start_point_span: sess.source_map().start_point(meta.span()), + }); return None; }; @@ -392,14 +351,11 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit sym::feature => insert_or_error(sess, mi, &mut feature)?, sym::since => insert_or_error(sess, mi, &mut since)?, _ => { - handle_errors( - &sess.parse_sess, - meta.span(), - AttrError::UnknownMetaItem( - pprust::path_to_string(&mi.path), - &["feature", "since"], - ), - ); + sess.emit_err(session_diagnostics::UnknownMetaItem { + span: meta.span(), + item: pprust::path_to_string(&mi.path), + expected: &["feature", "since"], + }); return None; } } @@ -417,11 +373,11 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit Some((feature, level)) } (None, _) => { - handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature); + sess.emit_err(session_diagnostics::MissingFeature { span: attr.span }); None } _ => { - handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince); + sess.emit_err(session_diagnostics::MissingSince { span: attr.span }); None } } @@ -441,11 +397,12 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil let mut implied_by = None; for meta in metas { let Some(mi) = meta.meta_item() else { - handle_errors( - &sess.parse_sess, - meta.span(), - AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), - ); + sess.emit_err(session_diagnostics::UnsupportedLiteral { + span: meta.span(), + reason: UnsupportedLiteralReason::Generic, + is_bytestr: false, + start_point_span: sess.source_map().start_point(meta.span()), + }); return None; }; @@ -484,14 +441,11 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil } sym::implied_by => insert_or_error(sess, mi, &mut implied_by)?, _ => { - handle_errors( - &sess.parse_sess, - meta.span(), - AttrError::UnknownMetaItem( - pprust::path_to_string(&mi.path), - &["feature", "reason", "issue", "soft", "implied_by"], - ), - ); + sess.emit_err(session_diagnostics::UnknownMetaItem { + span: meta.span(), + item: pprust::path_to_string(&mi.path), + expected: &["feature", "reason", "issue", "soft", "implied_by"], + }); return None; } } @@ -500,7 +454,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil match (feature, reason, issue) { (Some(feature), reason, Some(_)) => { if !rustc_lexer::is_ident(feature.as_str()) { - handle_errors(&sess.parse_sess, attr.span, AttrError::NonIdentFeature); + sess.emit_err(session_diagnostics::NonIdentFeature { span: attr.span }); return None; } let level = StabilityLevel::Unstable { @@ -512,7 +466,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil Some((feature, level)) } (None, _, _) => { - handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature); + sess.emit_err(session_diagnostics::MissingFeature { span: attr.span }); return None; } _ => { @@ -659,11 +613,12 @@ pub fn eval_condition( ast::MetaItemKind::List(mis) => { for mi in mis.iter() { if !mi.is_meta_item() { - handle_errors( - sess, - mi.span(), - AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), - ); + sess.emit_err(session_diagnostics::UnsupportedLiteral { + span: mi.span(), + reason: UnsupportedLiteralReason::Generic, + is_bytestr: false, + start_point_span: sess.source_map().start_point(mi.span()), + }); return false; } } @@ -731,14 +686,12 @@ pub fn eval_condition( true } MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { - handle_errors( - sess, - lit.span, - AttrError::UnsupportedLiteral( - UnsupportedLiteralReason::CfgString, - lit.kind.is_bytestr(), - ), - ); + sess.emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::CfgString, + is_bytestr: lit.kind.is_bytestr(), + start_point_span: sess.source_map().start_point(lit.span), + }); true } ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => { @@ -795,11 +748,10 @@ pub fn find_deprecation( MetaItemKind::List(list) => { let get = |meta: &MetaItem, item: &mut Option| { if item.is_some() { - handle_errors( - &sess.parse_sess, - meta.span, - AttrError::MultipleItem(pprust::path_to_string(&meta.path)), - ); + sess.emit_err(session_diagnostics::MultipleItem { + span: meta.span, + item: pprust::path_to_string(&meta.path), + }); return false; } if let Some(v) = meta.value_str() { @@ -807,14 +759,12 @@ pub fn find_deprecation( true } else { if let Some(lit) = meta.name_value_literal() { - handle_errors( - &sess.parse_sess, - lit.span, - AttrError::UnsupportedLiteral( - UnsupportedLiteralReason::DeprecatedString, - lit.kind.is_bytestr(), - ), - ); + sess.emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::DeprecatedString, + is_bytestr: lit.kind.is_bytestr(), + start_point_span: sess.source_map().start_point(lit.span), + }); } else { sess.emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span, @@ -852,30 +802,25 @@ pub fn find_deprecation( } } _ => { - handle_errors( - &sess.parse_sess, - meta.span(), - AttrError::UnknownMetaItem( - pprust::path_to_string(&mi.path), - if features.deprecated_suggestion { - &["since", "note", "suggestion"] - } else { - &["since", "note"] - }, - ), - ); + sess.emit_err(session_diagnostics::UnknownMetaItem { + span: meta.span(), + item: pprust::path_to_string(&mi.path), + expected: if features.deprecated_suggestion { + &["since", "note", "suggestion"] + } else { + &["since", "note"] + }, + }); continue 'outer; } }, NestedMetaItem::Lit(lit) => { - handle_errors( - &sess.parse_sess, - lit.span, - AttrError::UnsupportedLiteral( - UnsupportedLiteralReason::DeprecatedKvPair, - false, - ), - ); + sess.emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::DeprecatedKvPair, + is_bytestr: false, + start_point_span: sess.source_map().start_point(lit.span), + }); continue 'outer; } } @@ -885,7 +830,7 @@ pub fn find_deprecation( if is_rustc { if since.is_none() { - handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince); + sess.emit_err(session_diagnostics::MissingSince { span: attr.span }); continue; } diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 6ea84620bbed8..16814950b0d98 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -272,21 +272,28 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> { loan_issued_at: Location, ) { let sccs = self.regioncx.constraint_sccs(); + let universal_regions = self.regioncx.universal_regions(); let issuing_region_scc = sccs.scc(issuing_region); // We first handle the cases where the loan doesn't go out of scope, depending on the issuing // region's successors. for scc in sccs.depth_first_search(issuing_region_scc) { - // 1. Via member constraints + // 1. Via applied member constraints // // The issuing region can flow into the choice regions, and they are either: // - placeholders or free regions themselves, // - or also transitively outlive a free region. // - // That is to say, if there are member constraints here, the loan escapes the function - // and cannot go out of scope. We can early return. - if self.regioncx.scc_has_member_constraints(scc) { - return; + // That is to say, if there are applied member constraints here, the loan escapes the + // function and cannot go out of scope. We could early return here. + // + // For additional insurance via fuzzing and crater, we verify that the constraint's min + // choice indeed escapes the function. In the future, we could e.g. turn this check into + // a debug assert and early return as an optimization. + for constraint in self.regioncx.applied_member_constraints(scc) { + if universal_regions.is_universal_region(constraint.min_choice) { + return; + } } // 2. Via regions that are live at all points: placeholders and free regions. @@ -413,12 +420,12 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { let mut polonius_prec = PoloniusOutOfScopePrecomputer::new(body, regioncx); for (loan_idx, loan_data) in borrow_set.iter_enumerated() { let issuing_region = loan_data.region; - let issued_location = loan_data.reserve_location; + let loan_issued_at = loan_data.reserve_location; polonius_prec.precompute_loans_out_of_scope( loan_idx, issuing_region, - issued_location, + loan_issued_at, ); } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 96cbe98c21694..05c2cbd49692c 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -644,11 +644,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.scc_universes[scc] } - /// Once region solving has completed, this function will return - /// the member constraints that were applied to the value of a given - /// region `r`. See `AppliedMemberConstraint`. - pub(crate) fn applied_member_constraints(&self, r: RegionVid) -> &[AppliedMemberConstraint] { - let scc = self.constraint_sccs.scc(r); + /// Once region solving has completed, this function will return the member constraints that + /// were applied to the value of a given SCC `scc`. See `AppliedMemberConstraint`. + pub(crate) fn applied_member_constraints( + &self, + scc: ConstraintSccIndex, + ) -> &[AppliedMemberConstraint] { binary_search_util::binary_search_slice( &self.member_constraints_applied, |applied| applied.member_region_scc, @@ -1945,7 +1946,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Member constraints can also give rise to `'r: 'x` edges that // were not part of the graph initially, so watch out for those. // (But they are extremely rare; this loop is very cold.) - for constraint in self.applied_member_constraints(r) { + for constraint in self.applied_member_constraints(self.constraint_sccs.scc(r)) { let p_c = &self.member_constraints[constraint.member_constraint_index]; let constraint = OutlivesConstraint { sup: r, @@ -2292,11 +2293,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.constraint_sccs.as_ref() } - /// Returns whether the given SCC has any member constraints. - pub(crate) fn scc_has_member_constraints(&self, scc: ConstraintSccIndex) -> bool { - self.member_constraints.indices(scc).next().is_some() - } - /// Returns whether the given SCC is live at all points: whether the representative is a /// placeholder or a free region. pub(crate) fn scc_is_live_at_all_points(&self, scc: ConstraintSccIndex) -> bool { diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index ac133f8b039d6..ed19274a7cc44 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -99,7 +99,7 @@ declare_features! ( /// Allows generators to be cloned. (removed, generator_clone, "1.65.0", Some(95360), None, Some("renamed to `coroutine_clone`")), /// Allows defining generators. - (removed, generators, "1.21.0", Some(43122), None, Some("renamed to `coroutine`")), + (removed, generators, "1.21.0", Some(43122), None, Some("renamed to `coroutines`")), /// Allows `impl Trait` in bindings (`let`, `const`, `static`). (removed, impl_trait_in_bindings, "1.55.0", Some(63065), None, Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")), diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 2e991b4c0adb5..462e7e85c65ac 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3463,9 +3463,10 @@ impl DumpMonoStatsFormat { /// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy, /// or future prototype. -#[derive(Clone, Copy, PartialEq, Hash, Debug)] +#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)] pub enum Polonius { /// The default value: disabled. + #[default] Off, /// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`. @@ -3475,12 +3476,6 @@ pub enum Polonius { Next, } -impl Default for Polonius { - fn default() -> Self { - Polonius::Off - } -} - impl Polonius { /// Returns whether the legacy version of polonius is enabled pub fn is_legacy_enabled(&self) -> bool { diff --git a/src/etc/gdb_lookup.py b/src/etc/gdb_lookup.py index 8171cb4e9a68a..f3ac9c1097806 100644 --- a/src/etc/gdb_lookup.py +++ b/src/etc/gdb_lookup.py @@ -1,4 +1,5 @@ import gdb +import gdb.printing import re from gdb_providers import * @@ -9,7 +10,7 @@ gdb_version = [int(num) for num in _gdb_version_matched.groups()] if _gdb_version_matched else [] def register_printers(objfile): - objfile.pretty_printers.append(lookup) + objfile.pretty_printers.append(printer) # BACKCOMPAT: rust 1.35 @@ -38,58 +39,80 @@ def check_enum_discriminant(valobj): return True -def lookup(valobj): - rust_type = classify_rust_type(valobj.type) - - if rust_type == RustType.ENUM: - # use enum provider only for GDB <7.12 - if gdb_version[0] < 7 or (gdb_version[0] == 7 and gdb_version[1] < 12): - if check_enum_discriminant(valobj): - return EnumProvider(valobj) - - if rust_type == RustType.STD_STRING: - return StdStringProvider(valobj) - if rust_type == RustType.STD_OS_STRING: - return StdOsStringProvider(valobj) - if rust_type == RustType.STD_STR: - return StdStrProvider(valobj) - if rust_type == RustType.STD_SLICE: - return StdSliceProvider(valobj) - if rust_type == RustType.STD_VEC: - return StdVecProvider(valobj) - if rust_type == RustType.STD_VEC_DEQUE: - return StdVecDequeProvider(valobj) - if rust_type == RustType.STD_BTREE_SET: - return StdBTreeSetProvider(valobj) - if rust_type == RustType.STD_BTREE_MAP: - return StdBTreeMapProvider(valobj) - if rust_type == RustType.STD_HASH_MAP: - if is_hashbrown_hashmap(valobj): - return StdHashMapProvider(valobj) - else: - return StdOldHashMapProvider(valobj) - if rust_type == RustType.STD_HASH_SET: - hash_map = valobj[valobj.type.fields()[0]] - if is_hashbrown_hashmap(hash_map): - return StdHashMapProvider(valobj, show_values=False) - else: - return StdOldHashMapProvider(hash_map, show_values=False) - - if rust_type == RustType.STD_RC: - return StdRcProvider(valobj) - if rust_type == RustType.STD_ARC: - return StdRcProvider(valobj, is_atomic=True) - - if rust_type == RustType.STD_CELL: - return StdCellProvider(valobj) - if rust_type == RustType.STD_REF: - return StdRefProvider(valobj) - if rust_type == RustType.STD_REF_MUT: - return StdRefProvider(valobj) - if rust_type == RustType.STD_REF_CELL: - return StdRefCellProvider(valobj) - - if rust_type == RustType.STD_NONZERO_NUMBER: - return StdNonZeroNumberProvider(valobj) - +# Helper for enum printing that checks the discriminant. Only used in +# older gdb. +def enum_provider(valobj): + if check_enum_discriminant(valobj): + return EnumProvider(valobj) return None + + +# Helper to handle both old and new hash maps. +def hashmap_provider(valobj): + if is_hashbrown_hashmap(valobj): + return StdHashMapProvider(valobj) + else: + return StdOldHashMapProvider(valobj) + + +# Helper to handle both old and new hash sets. +def hashset_provider(valobj): + hash_map = valobj[valobj.type.fields()[0]] + if is_hashbrown_hashmap(hash_map): + return StdHashMapProvider(valobj, show_values=False) + else: + return StdOldHashMapProvider(hash_map, show_values=False) + + +class PrintByRustType(gdb.printing.SubPrettyPrinter): + def __init__(self, name, provider): + super(PrintByRustType, self).__init__(name) + self.provider = provider + + def __call__(self, val): + if self.enabled: + return self.provider(val) + return None + + +class RustPrettyPrinter(gdb.printing.PrettyPrinter): + def __init__(self, name): + super(RustPrettyPrinter, self).__init__(name, []) + self.type_map = {} + + def add(self, rust_type, provider): + # Just use the rust_type as the name. + printer = PrintByRustType(rust_type, provider) + self.type_map[rust_type] = printer + self.subprinters.append(printer) + + def __call__(self, valobj): + rust_type = classify_rust_type(valobj.type) + if rust_type in self.type_map: + return self.type_map[rust_type](valobj) + return None + + +printer = RustPrettyPrinter("rust") +# use enum provider only for GDB <7.12 +if gdb_version[0] < 7 or (gdb_version[0] == 7 and gdb_version[1] < 12): + printer.add(RustType.ENUM, enum_provider) +printer.add(RustType.STD_STRING, StdStringProvider) +printer.add(RustType.STD_OS_STRING, StdOsStringProvider) +printer.add(RustType.STD_STR, StdStrProvider) +printer.add(RustType.STD_SLICE, StdSliceProvider) +printer.add(RustType.STD_VEC, StdVecProvider) +printer.add(RustType.STD_VEC_DEQUE, StdVecDequeProvider) +printer.add(RustType.STD_BTREE_SET, StdBTreeSetProvider) +printer.add(RustType.STD_BTREE_MAP, StdBTreeMapProvider) +printer.add(RustType.STD_HASH_MAP, hashmap_provider) +printer.add(RustType.STD_HASH_SET, hashset_provider) +printer.add(RustType.STD_RC, StdRcProvider) +printer.add(RustType.STD_ARC, lambda valobj: StdRcProvider(valobj, is_atomic=True)) + +printer.add(RustType.STD_CELL, StdCellProvider) +printer.add(RustType.STD_REF, StdRefProvider) +printer.add(RustType.STD_REF_MUT, StdRefProvider) +printer.add(RustType.STD_REF_CELL, StdRefCellProvider) + +printer.add(RustType.STD_NONZERO_NUMBER, StdNonZeroNumberProvider) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 8ce00e00b5727..ac270a1f0ba4d 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2470,7 +2470,7 @@ impl<'test> TestCx<'test> { } CoverageMap => { rustc.arg("-Cinstrument-coverage"); - // These tests only compile to MIR, so they don't need the + // These tests only compile to LLVM IR, so they don't need the // profiler runtime to be present. rustc.arg("-Zno-profiler-runtime"); // Coverage mappings are sensitive to MIR optimizations, and diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 2b828e58d5418..dcf218bc18954 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -11,7 +11,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1854; -const ROOT_ENTRY_LIMIT: usize = 865; +const ROOT_ENTRY_LIMIT: usize = 866; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/codegen/instrument-coverage-off.rs b/tests/codegen/instrument-coverage-off.rs new file mode 100644 index 0000000000000..ca803beec0b14 --- /dev/null +++ b/tests/codegen/instrument-coverage-off.rs @@ -0,0 +1,23 @@ +// Test that `-Cinstrument-coverage=off` does not add coverage instrumentation to LLVM IR. + +// needs-profiler-support +// revisions: n no off false zero +// [n] compile-flags: -Cinstrument-coverage=n +// [no] compile-flags: -Cinstrument-coverage=no +// [off] compile-flags: -Cinstrument-coverage=off +// [false] compile-flags: -Cinstrument-coverage=false +// [zero] compile-flags: -Cinstrument-coverage=0 + +// CHECK-NOT: __llvm_profile_filename +// CHECK-NOT: __llvm_coverage_mapping + +#![crate_type="lib"] + +#[inline(never)] +fn some_function() { + +} + +pub fn some_other_function() { + some_function(); +} diff --git a/tests/codegen/instrument-coverage.rs b/tests/codegen/instrument-coverage.rs index 78f8875a2d90c..f8437dac46329 100644 --- a/tests/codegen/instrument-coverage.rs +++ b/tests/codegen/instrument-coverage.rs @@ -1,9 +1,16 @@ // Test that `-Cinstrument-coverage` creates expected __llvm_profile_filename symbol in LLVM IR. // needs-profiler-support -// compile-flags: -Cinstrument-coverage +// revisions: default y yes on true all +// [default] compile-flags: -Cinstrument-coverage +// [y] compile-flags: -Cinstrument-coverage=y +// [yes] compile-flags: -Cinstrument-coverage=yes +// [on] compile-flags: -Cinstrument-coverage=on +// [true] compile-flags: -Cinstrument-coverage=true +// [all] compile-flags: -Cinstrument-coverage=all // CHECK: @__llvm_profile_filename = {{.*}}"default_%m_%p.profraw\00"{{.*}} +// CHECK: @__llvm_coverage_mapping #![crate_type="lib"] diff --git a/tests/ui/instrument-coverage/bad-value.bad.stderr b/tests/ui/instrument-coverage/bad-value.bad.stderr new file mode 100644 index 0000000000000..246c4f31a4bac --- /dev/null +++ b/tests/ui/instrument-coverage/bad-value.bad.stderr @@ -0,0 +1,2 @@ +error: incorrect value `bad-value` for codegen option `instrument-coverage` - `all` (default), `except-unused-generics`, `except-unused-functions`, or `off` was expected + diff --git a/tests/ui/instrument-coverage/bad-value.blank.stderr b/tests/ui/instrument-coverage/bad-value.blank.stderr new file mode 100644 index 0000000000000..b539c558d9ba7 --- /dev/null +++ b/tests/ui/instrument-coverage/bad-value.blank.stderr @@ -0,0 +1,2 @@ +error: incorrect value `` for codegen option `instrument-coverage` - `all` (default), `except-unused-generics`, `except-unused-functions`, or `off` was expected + diff --git a/tests/ui/instrument-coverage/bad-value.rs b/tests/ui/instrument-coverage/bad-value.rs new file mode 100644 index 0000000000000..1925c36aa5371 --- /dev/null +++ b/tests/ui/instrument-coverage/bad-value.rs @@ -0,0 +1,5 @@ +// revisions: blank bad +// [blank] compile-flags: -Cinstrument-coverage= +// [bad] compile-flags: -Cinstrument-coverage=bad-value + +fn main() {} diff --git a/tests/ui/instrument-coverage/except-unused-functions.rs b/tests/ui/instrument-coverage/except-unused-functions.rs new file mode 100644 index 0000000000000..5a0b7d4fef900 --- /dev/null +++ b/tests/ui/instrument-coverage/except-unused-functions.rs @@ -0,0 +1,3 @@ +// compile-flags: -Cinstrument-coverage=except-unused-functions + +fn main() {} diff --git a/tests/ui/instrument-coverage/except-unused-functions.stderr b/tests/ui/instrument-coverage/except-unused-functions.stderr new file mode 100644 index 0000000000000..82c1c630cbf23 --- /dev/null +++ b/tests/ui/instrument-coverage/except-unused-functions.stderr @@ -0,0 +1,2 @@ +error: `-C instrument-coverage=except-*` requires `-Z unstable-options` + diff --git a/tests/ui/instrument-coverage/except-unused-generics.rs b/tests/ui/instrument-coverage/except-unused-generics.rs new file mode 100644 index 0000000000000..4b1ddf29026ca --- /dev/null +++ b/tests/ui/instrument-coverage/except-unused-generics.rs @@ -0,0 +1,3 @@ +// compile-flags: -Cinstrument-coverage=except-unused-generics + +fn main() {} diff --git a/tests/ui/instrument-coverage/except-unused-generics.stderr b/tests/ui/instrument-coverage/except-unused-generics.stderr new file mode 100644 index 0000000000000..82c1c630cbf23 --- /dev/null +++ b/tests/ui/instrument-coverage/except-unused-generics.stderr @@ -0,0 +1,2 @@ +error: `-C instrument-coverage=except-*` requires `-Z unstable-options` + diff --git a/tests/ui/instrument-coverage/off-values.rs b/tests/ui/instrument-coverage/off-values.rs new file mode 100644 index 0000000000000..0f9a0c47425dc --- /dev/null +++ b/tests/ui/instrument-coverage/off-values.rs @@ -0,0 +1,9 @@ +// check-pass +// revisions: n no off false zero +// [n] compile-flags: -Cinstrument-coverage=n +// [no] compile-flags: -Cinstrument-coverage=no +// [off] compile-flags: -Cinstrument-coverage=off +// [false] compile-flags: -Cinstrument-coverage=false +// [zero] compile-flags: -Cinstrument-coverage=0 + +fn main() {} diff --git a/tests/ui/instrument-coverage/on-values.rs b/tests/ui/instrument-coverage/on-values.rs new file mode 100644 index 0000000000000..cc54c71c656fd --- /dev/null +++ b/tests/ui/instrument-coverage/on-values.rs @@ -0,0 +1,11 @@ +// check-pass +// needs-profiler-support +// revisions: default y yes on true all +// [default] compile-flags: -Cinstrument-coverage +// [y] compile-flags: -Cinstrument-coverage=y +// [yes] compile-flags: -Cinstrument-coverage=yes +// [on] compile-flags: -Cinstrument-coverage=on +// [true] compile-flags: -Cinstrument-coverage=true +// [all] compile-flags: -Cinstrument-coverage=all + +fn main() {} diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-116657.nll.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-116657.nll.stderr new file mode 100644 index 0000000000000..6f9b330316378 --- /dev/null +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-116657.nll.stderr @@ -0,0 +1,36 @@ +error[E0046]: not all trait items implemented, missing: `call` + --> $DIR/location-insensitive-scopes-issue-116657.rs:18:1 + | +LL | fn call(x: Self) -> Self::Output; + | --------------------------------- `call` from trait +... +LL | impl Callable for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `call` in implementation + +error: unconstrained opaque type + --> $DIR/location-insensitive-scopes-issue-116657.rs:22:19 + | +LL | type Output = impl PlusOne; + | ^^^^^^^^^^^^ + | + = note: `Output` must be used in combination with a concrete type within the same impl + +error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds + --> $DIR/location-insensitive-scopes-issue-116657.rs:28:5 + | +LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne { + | -- ------------ opaque type defined here + | | + | hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here +LL | <&mut i32 as Callable>::call(y) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound + | +LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a { + | ++++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0046, E0700. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-116657.polonius.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-116657.polonius.stderr new file mode 100644 index 0000000000000..6f9b330316378 --- /dev/null +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-116657.polonius.stderr @@ -0,0 +1,36 @@ +error[E0046]: not all trait items implemented, missing: `call` + --> $DIR/location-insensitive-scopes-issue-116657.rs:18:1 + | +LL | fn call(x: Self) -> Self::Output; + | --------------------------------- `call` from trait +... +LL | impl Callable for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `call` in implementation + +error: unconstrained opaque type + --> $DIR/location-insensitive-scopes-issue-116657.rs:22:19 + | +LL | type Output = impl PlusOne; + | ^^^^^^^^^^^^ + | + = note: `Output` must be used in combination with a concrete type within the same impl + +error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds + --> $DIR/location-insensitive-scopes-issue-116657.rs:28:5 + | +LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne { + | -- ------------ opaque type defined here + | | + | hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here +LL | <&mut i32 as Callable>::call(y) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound + | +LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a { + | ++++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0046, E0700. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-116657.rs b/tests/ui/nll/polonius/location-insensitive-scopes-issue-116657.rs new file mode 100644 index 0000000000000..ec17e0b093b38 --- /dev/null +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-116657.rs @@ -0,0 +1,33 @@ +// This is a non-regression test for issue #116657, where NLL and `-Zpolonius=next` computed +// different loan scopes when a member constraint was not ultimately applied. + +// revisions: nll polonius +// [polonius] compile-flags: -Zpolonius=next + +#![feature(impl_trait_in_assoc_type)] + +trait Callable { + type Output; + fn call(x: Self) -> Self::Output; +} + +trait PlusOne {} + +impl<'a> PlusOne for &'a mut i32 {} + +impl Callable for T { + //[nll]~^ ERROR not all trait items implemented + //[polonius]~^^ ERROR not all trait items implemented + + type Output = impl PlusOne; + //[nll]~^ ERROR unconstrained opaque type + //[polonius]~^^ ERROR unconstrained opaque type +} + +fn test<'a>(y: &'a mut i32) -> impl PlusOne { + <&mut i32 as Callable>::call(y) + //[nll]~^ ERROR hidden type for `impl PlusOne` captures lifetime + //[polonius]~^^ ERROR hidden type for `impl PlusOne` captures lifetime +} + +fn main() {}