Auto merge of #117087 - matthiaskrgr:rollup-08kkjkz, r=matthiaskrgr

Rollup of 5 pull requests

Successful merges:

 - #116960 (Location-insensitive polonius: consider a loan escaping if an SCC has member constraints applied only)
 - #116978 (Rewrite gdb pretty-printer registration)
 - #117040 (coverage: Add UI tests for values accepted by `-Cinstrument-coverage`)
 - #117064 (Eliminate rustc_attrs::builtin::handle_errors in favor of emitting errors directly)
 - #117073 (Fix suggestion for renamed coroutines feature)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-10-23 16:04:48 +00:00
commit e2068cdb09
22 changed files with 352 additions and 212 deletions

View File

@ -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)) 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 { pub(crate) enum UnsupportedLiteralReason {
Generic, Generic,
CfgString, CfgString,
@ -48,37 +38,6 @@ pub(crate) enum UnsupportedLiteralReason {
DeprecatedKvPair, 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)] #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum InlineAttr { pub enum InlineAttr {
None, None,
@ -241,7 +200,7 @@ pub fn find_stability(
sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true, sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true,
sym::unstable => { sym::unstable => {
if stab.is_some() { if stab.is_some() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
break; break;
} }
@ -251,7 +210,7 @@ pub fn find_stability(
} }
sym::stable => { sym::stable => {
if stab.is_some() { if stab.is_some() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
break; break;
} }
if let Some((feature, level)) = parse_stability(sess, attr) { 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_promotable => promotable = true,
sym::rustc_const_unstable => { sym::rustc_const_unstable => {
if const_stab.is_some() { if const_stab.is_some() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
break; break;
} }
@ -306,7 +265,7 @@ pub fn find_const_stability(
} }
sym::rustc_const_stable => { sym::rustc_const_stable => {
if const_stab.is_some() { if const_stab.is_some() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
break; break;
} }
if let Some((feature, level)) = parse_stability(sess, attr) { if let Some((feature, level)) = parse_stability(sess, attr) {
@ -340,7 +299,7 @@ pub fn find_body_stability(
for attr in attrs { for attr in attrs {
if attr.has_name(sym::rustc_default_body_unstable) { if attr.has_name(sym::rustc_default_body_unstable) {
if body_stab.is_some() { if body_stab.is_some() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); sess.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span });
break; break;
} }
@ -355,11 +314,10 @@ pub fn find_body_stability(
fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option<Symbol>) -> Option<()> { fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option<Symbol>) -> Option<()> {
if item.is_some() { if item.is_some() {
handle_errors( sess.emit_err(session_diagnostics::MultipleItem {
&sess.parse_sess, span: meta.span,
meta.span, item: pprust::path_to_string(&meta.path),
AttrError::MultipleItem(pprust::path_to_string(&meta.path)), });
);
None None
} else if let Some(v) = meta.value_str() { } else if let Some(v) = meta.value_str() {
*item = Some(v); *item = Some(v);
@ -380,11 +338,12 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
let mut since = None; let mut since = None;
for meta in metas { for meta in metas {
let Some(mi) = meta.meta_item() else { let Some(mi) = meta.meta_item() else {
handle_errors( sess.emit_err(session_diagnostics::UnsupportedLiteral {
&sess.parse_sess, span: meta.span(),
meta.span(), reason: UnsupportedLiteralReason::Generic,
AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), is_bytestr: false,
); start_point_span: sess.source_map().start_point(meta.span()),
});
return None; 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::feature => insert_or_error(sess, mi, &mut feature)?,
sym::since => insert_or_error(sess, mi, &mut since)?, sym::since => insert_or_error(sess, mi, &mut since)?,
_ => { _ => {
handle_errors( sess.emit_err(session_diagnostics::UnknownMetaItem {
&sess.parse_sess, span: meta.span(),
meta.span(), item: pprust::path_to_string(&mi.path),
AttrError::UnknownMetaItem( expected: &["feature", "since"],
pprust::path_to_string(&mi.path), });
&["feature", "since"],
),
);
return None; return None;
} }
} }
@ -417,11 +373,11 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
Some((feature, level)) Some((feature, level))
} }
(None, _) => { (None, _) => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature); sess.emit_err(session_diagnostics::MissingFeature { span: attr.span });
None None
} }
_ => { _ => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince); sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
None None
} }
} }
@ -441,11 +397,12 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
let mut implied_by = None; let mut implied_by = None;
for meta in metas { for meta in metas {
let Some(mi) = meta.meta_item() else { let Some(mi) = meta.meta_item() else {
handle_errors( sess.emit_err(session_diagnostics::UnsupportedLiteral {
&sess.parse_sess, span: meta.span(),
meta.span(), reason: UnsupportedLiteralReason::Generic,
AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), is_bytestr: false,
); start_point_span: sess.source_map().start_point(meta.span()),
});
return None; 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)?, sym::implied_by => insert_or_error(sess, mi, &mut implied_by)?,
_ => { _ => {
handle_errors( sess.emit_err(session_diagnostics::UnknownMetaItem {
&sess.parse_sess, span: meta.span(),
meta.span(), item: pprust::path_to_string(&mi.path),
AttrError::UnknownMetaItem( expected: &["feature", "reason", "issue", "soft", "implied_by"],
pprust::path_to_string(&mi.path), });
&["feature", "reason", "issue", "soft", "implied_by"],
),
);
return None; return None;
} }
} }
@ -500,7 +454,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
match (feature, reason, issue) { match (feature, reason, issue) {
(Some(feature), reason, Some(_)) => { (Some(feature), reason, Some(_)) => {
if !rustc_lexer::is_ident(feature.as_str()) { 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; return None;
} }
let level = StabilityLevel::Unstable { let level = StabilityLevel::Unstable {
@ -512,7 +466,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
Some((feature, level)) Some((feature, level))
} }
(None, _, _) => { (None, _, _) => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature); sess.emit_err(session_diagnostics::MissingFeature { span: attr.span });
return None; return None;
} }
_ => { _ => {
@ -659,11 +613,12 @@ pub fn eval_condition(
ast::MetaItemKind::List(mis) => { ast::MetaItemKind::List(mis) => {
for mi in mis.iter() { for mi in mis.iter() {
if !mi.is_meta_item() { if !mi.is_meta_item() {
handle_errors( sess.emit_err(session_diagnostics::UnsupportedLiteral {
sess, span: mi.span(),
mi.span(), reason: UnsupportedLiteralReason::Generic,
AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), is_bytestr: false,
); start_point_span: sess.source_map().start_point(mi.span()),
});
return false; return false;
} }
} }
@ -731,14 +686,12 @@ pub fn eval_condition(
true true
} }
MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { MetaItemKind::NameValue(lit) if !lit.kind.is_str() => {
handle_errors( sess.emit_err(session_diagnostics::UnsupportedLiteral {
sess, span: lit.span,
lit.span, reason: UnsupportedLiteralReason::CfgString,
AttrError::UnsupportedLiteral( is_bytestr: lit.kind.is_bytestr(),
UnsupportedLiteralReason::CfgString, start_point_span: sess.source_map().start_point(lit.span),
lit.kind.is_bytestr(), });
),
);
true true
} }
ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => { ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => {
@ -795,11 +748,10 @@ pub fn find_deprecation(
MetaItemKind::List(list) => { MetaItemKind::List(list) => {
let get = |meta: &MetaItem, item: &mut Option<Symbol>| { let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() { if item.is_some() {
handle_errors( sess.emit_err(session_diagnostics::MultipleItem {
&sess.parse_sess, span: meta.span,
meta.span, item: pprust::path_to_string(&meta.path),
AttrError::MultipleItem(pprust::path_to_string(&meta.path)), });
);
return false; return false;
} }
if let Some(v) = meta.value_str() { if let Some(v) = meta.value_str() {
@ -807,14 +759,12 @@ pub fn find_deprecation(
true true
} else { } else {
if let Some(lit) = meta.name_value_literal() { if let Some(lit) = meta.name_value_literal() {
handle_errors( sess.emit_err(session_diagnostics::UnsupportedLiteral {
&sess.parse_sess, span: lit.span,
lit.span, reason: UnsupportedLiteralReason::DeprecatedString,
AttrError::UnsupportedLiteral( is_bytestr: lit.kind.is_bytestr(),
UnsupportedLiteralReason::DeprecatedString, start_point_span: sess.source_map().start_point(lit.span),
lit.kind.is_bytestr(), });
),
);
} else { } else {
sess.emit_err(session_diagnostics::IncorrectMetaItem { sess.emit_err(session_diagnostics::IncorrectMetaItem {
span: meta.span, span: meta.span,
@ -852,30 +802,25 @@ pub fn find_deprecation(
} }
} }
_ => { _ => {
handle_errors( sess.emit_err(session_diagnostics::UnknownMetaItem {
&sess.parse_sess, span: meta.span(),
meta.span(), item: pprust::path_to_string(&mi.path),
AttrError::UnknownMetaItem( expected: if features.deprecated_suggestion {
pprust::path_to_string(&mi.path), &["since", "note", "suggestion"]
if features.deprecated_suggestion { } else {
&["since", "note", "suggestion"] &["since", "note"]
} else { },
&["since", "note"] });
},
),
);
continue 'outer; continue 'outer;
} }
}, },
NestedMetaItem::Lit(lit) => { NestedMetaItem::Lit(lit) => {
handle_errors( sess.emit_err(session_diagnostics::UnsupportedLiteral {
&sess.parse_sess, span: lit.span,
lit.span, reason: UnsupportedLiteralReason::DeprecatedKvPair,
AttrError::UnsupportedLiteral( is_bytestr: false,
UnsupportedLiteralReason::DeprecatedKvPair, start_point_span: sess.source_map().start_point(lit.span),
false, });
),
);
continue 'outer; continue 'outer;
} }
} }
@ -885,7 +830,7 @@ pub fn find_deprecation(
if is_rustc { if is_rustc {
if since.is_none() { if since.is_none() {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince); sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
continue; continue;
} }

View File

@ -272,21 +272,28 @@ fn precompute_loans_out_of_scope(
loan_issued_at: Location, loan_issued_at: Location,
) { ) {
let sccs = self.regioncx.constraint_sccs(); let sccs = self.regioncx.constraint_sccs();
let universal_regions = self.regioncx.universal_regions();
let issuing_region_scc = sccs.scc(issuing_region); 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 // We first handle the cases where the loan doesn't go out of scope, depending on the issuing
// region's successors. // region's successors.
for scc in sccs.depth_first_search(issuing_region_scc) { 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: // The issuing region can flow into the choice regions, and they are either:
// - placeholders or free regions themselves, // - placeholders or free regions themselves,
// - or also transitively outlive a free region. // - or also transitively outlive a free region.
// //
// That is to say, if there are member constraints here, the loan escapes the function // That is to say, if there are applied member constraints here, the loan escapes the
// and cannot go out of scope. We can early return. // function and cannot go out of scope. We could early return here.
if self.regioncx.scc_has_member_constraints(scc) { //
return; // 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. // 2. Via regions that are live at all points: placeholders and free regions.
@ -413,12 +420,12 @@ pub fn new(
let mut polonius_prec = PoloniusOutOfScopePrecomputer::new(body, regioncx); let mut polonius_prec = PoloniusOutOfScopePrecomputer::new(body, regioncx);
for (loan_idx, loan_data) in borrow_set.iter_enumerated() { for (loan_idx, loan_data) in borrow_set.iter_enumerated() {
let issuing_region = loan_data.region; 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( polonius_prec.precompute_loans_out_of_scope(
loan_idx, loan_idx,
issuing_region, issuing_region,
issued_location, loan_issued_at,
); );
} }

View File

@ -644,11 +644,12 @@ pub(crate) fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex {
self.scc_universes[scc] self.scc_universes[scc]
} }
/// Once region solving has completed, this function will return /// Once region solving has completed, this function will return the member constraints that
/// the member constraints that were applied to the value of a given /// were applied to the value of a given SCC `scc`. See `AppliedMemberConstraint`.
/// region `r`. See `AppliedMemberConstraint`. pub(crate) fn applied_member_constraints(
pub(crate) fn applied_member_constraints(&self, r: RegionVid) -> &[AppliedMemberConstraint] { &self,
let scc = self.constraint_sccs.scc(r); scc: ConstraintSccIndex,
) -> &[AppliedMemberConstraint] {
binary_search_util::binary_search_slice( binary_search_util::binary_search_slice(
&self.member_constraints_applied, &self.member_constraints_applied,
|applied| applied.member_region_scc, |applied| applied.member_region_scc,
@ -1945,7 +1946,7 @@ pub(crate) fn find_constraint_paths_between_regions(
// Member constraints can also give rise to `'r: 'x` edges that // Member constraints can also give rise to `'r: 'x` edges that
// were not part of the graph initially, so watch out for those. // were not part of the graph initially, so watch out for those.
// (But they are extremely rare; this loop is very cold.) // (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 p_c = &self.member_constraints[constraint.member_constraint_index];
let constraint = OutlivesConstraint { let constraint = OutlivesConstraint {
sup: r, sup: r,
@ -2292,11 +2293,6 @@ pub(crate) fn constraint_sccs(&self) -> &Sccs<RegionVid, ConstraintSccIndex> {
self.constraint_sccs.as_ref() 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 /// Returns whether the given SCC is live at all points: whether the representative is a
/// placeholder or a free region. /// placeholder or a free region.
pub(crate) fn scc_is_live_at_all_points(&self, scc: ConstraintSccIndex) -> bool { pub(crate) fn scc_is_live_at_all_points(&self, scc: ConstraintSccIndex) -> bool {

View File

@ -99,7 +99,7 @@ macro_rules! declare_features {
/// Allows generators to be cloned. /// Allows generators to be cloned.
(removed, generator_clone, "1.65.0", Some(95360), None, Some("renamed to `coroutine_clone`")), (removed, generator_clone, "1.65.0", Some(95360), None, Some("renamed to `coroutine_clone`")),
/// Allows defining generators. /// 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`). /// Allows `impl Trait` in bindings (`let`, `const`, `static`).
(removed, impl_trait_in_bindings, "1.55.0", Some(63065), None, (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")), Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),

View File

@ -3463,9 +3463,10 @@ pub fn extension(self) -> &'static str {
/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy, /// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
/// or future prototype. /// or future prototype.
#[derive(Clone, Copy, PartialEq, Hash, Debug)] #[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
pub enum Polonius { pub enum Polonius {
/// The default value: disabled. /// The default value: disabled.
#[default]
Off, Off,
/// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`. /// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.
@ -3475,12 +3476,6 @@ pub enum Polonius {
Next, Next,
} }
impl Default for Polonius {
fn default() -> Self {
Polonius::Off
}
}
impl Polonius { impl Polonius {
/// Returns whether the legacy version of polonius is enabled /// Returns whether the legacy version of polonius is enabled
pub fn is_legacy_enabled(&self) -> bool { pub fn is_legacy_enabled(&self) -> bool {

View File

@ -1,4 +1,5 @@
import gdb import gdb
import gdb.printing
import re import re
from gdb_providers import * from gdb_providers import *
@ -9,7 +10,7 @@ _gdb_version_matched = re.search('([0-9]+)\\.([0-9]+)', gdb.VERSION)
gdb_version = [int(num) for num in _gdb_version_matched.groups()] if _gdb_version_matched else [] gdb_version = [int(num) for num in _gdb_version_matched.groups()] if _gdb_version_matched else []
def register_printers(objfile): def register_printers(objfile):
objfile.pretty_printers.append(lookup) objfile.pretty_printers.append(printer)
# BACKCOMPAT: rust 1.35 # BACKCOMPAT: rust 1.35
@ -38,58 +39,80 @@ def check_enum_discriminant(valobj):
return True return True
def lookup(valobj): # Helper for enum printing that checks the discriminant. Only used in
rust_type = classify_rust_type(valobj.type) # older gdb.
def enum_provider(valobj):
if rust_type == RustType.ENUM: if check_enum_discriminant(valobj):
# use enum provider only for GDB <7.12 return EnumProvider(valobj)
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)
return None 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)

View File

@ -2470,7 +2470,7 @@ fn make_compile_args(
} }
CoverageMap => { CoverageMap => {
rustc.arg("-Cinstrument-coverage"); 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. // profiler runtime to be present.
rustc.arg("-Zno-profiler-runtime"); rustc.arg("-Zno-profiler-runtime");
// Coverage mappings are sensitive to MIR optimizations, and // Coverage mappings are sensitive to MIR optimizations, and

View File

@ -11,7 +11,7 @@
const ENTRY_LIMIT: usize = 900; const ENTRY_LIMIT: usize = 900;
// FIXME: The following limits should be reduced eventually. // FIXME: The following limits should be reduced eventually.
const ISSUES_ENTRY_LIMIT: usize = 1854; const ISSUES_ENTRY_LIMIT: usize = 1854;
const ROOT_ENTRY_LIMIT: usize = 865; const ROOT_ENTRY_LIMIT: usize = 866;
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files "rs", // test source files

View File

@ -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();
}

View File

@ -1,9 +1,16 @@
// Test that `-Cinstrument-coverage` creates expected __llvm_profile_filename symbol in LLVM IR. // Test that `-Cinstrument-coverage` creates expected __llvm_profile_filename symbol in LLVM IR.
// needs-profiler-support // 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_profile_filename = {{.*}}"default_%m_%p.profraw\00"{{.*}}
// CHECK: @__llvm_coverage_mapping
#![crate_type="lib"] #![crate_type="lib"]

View File

@ -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

View File

@ -0,0 +1,2 @@
error: incorrect value `` for codegen option `instrument-coverage` - `all` (default), `except-unused-generics`, `except-unused-functions`, or `off` was expected

View File

@ -0,0 +1,5 @@
// revisions: blank bad
// [blank] compile-flags: -Cinstrument-coverage=
// [bad] compile-flags: -Cinstrument-coverage=bad-value
fn main() {}

View File

@ -0,0 +1,3 @@
// compile-flags: -Cinstrument-coverage=except-unused-functions
fn main() {}

View File

@ -0,0 +1,2 @@
error: `-C instrument-coverage=except-*` requires `-Z unstable-options`

View File

@ -0,0 +1,3 @@
// compile-flags: -Cinstrument-coverage=except-unused-generics
fn main() {}

View File

@ -0,0 +1,2 @@
error: `-C instrument-coverage=except-*` requires `-Z unstable-options`

View File

@ -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() {}

View File

@ -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() {}

View File

@ -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<T: PlusOne> 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`.

View File

@ -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<T: PlusOne> 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`.

View File

@ -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<T: PlusOne> 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() {}