Skip to content

Commit 12a8bb8

Browse files
committed
Do not suggest struct literal when fields are private
1 parent e0e379b commit 12a8bb8

File tree

2 files changed

+65
-36
lines changed

2 files changed

+65
-36
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

+64-35
Original file line numberDiff line numberDiff line change
@@ -1449,44 +1449,73 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
14491449
),
14501450
_ => (": val", "literal", Applicability::HasPlaceholders, None),
14511451
};
1452-
let field_ids = self.r.field_def_ids(def_id);
1453-
let (fields, applicability) = match field_ids {
1454-
Some(field_ids) => {
1455-
let fields = field_ids.iter().map(|&id| self.r.tcx.item_name(id));
1456-
1457-
let fields = if let Some(old_fields) = old_fields {
1458-
fields
1459-
.enumerate()
1460-
.map(|(idx, new)| (new, old_fields.get(idx)))
1461-
.map(|(new, old)| {
1462-
let new = new.to_ident_string();
1463-
if let Some(Some(old)) = old
1464-
&& new != *old
1465-
{
1466-
format!("{new}: {old}")
1467-
} else {
1468-
new
1469-
}
1470-
})
1471-
.collect::<Vec<String>>()
1472-
} else {
1473-
fields.map(|f| format!("{f}{tail}")).collect::<Vec<String>>()
1474-
};
14751452

1476-
(fields.join(", "), applicability)
1453+
let fields = match def_id.as_local() {
1454+
Some(def_id) => {
1455+
self.r.struct_constructors.get(&def_id).cloned().map(|(_, _, f)| f)
14771456
}
1478-
None => ("/* fields */".to_string(), Applicability::HasPlaceholders),
1479-
};
1480-
let pad = match field_ids {
1481-
Some(field_ids) if field_ids.is_empty() => "",
1482-
_ => " ",
1457+
None => Some(
1458+
self.r
1459+
.tcx
1460+
.associated_item_def_ids(def_id)
1461+
.iter()
1462+
.map(|field_id| self.r.tcx.visibility(field_id))
1463+
.collect(),
1464+
),
14831465
};
1484-
err.span_suggestion(
1485-
span,
1486-
format!("use struct {descr} syntax instead"),
1487-
format!("{path_str} {{{pad}{fields}{pad}}}"),
1488-
applicability,
1489-
);
1466+
1467+
let hidden_fields = fields.map_or(false, |fields| {
1468+
fields
1469+
.iter()
1470+
.filter(|vis| {
1471+
!self.r.is_accessible_from(**vis, self.parent_scope.module)
1472+
})
1473+
.next()
1474+
.is_some()
1475+
});
1476+
1477+
if !hidden_fields {
1478+
// If the fields of the type are private, we shouldn't be suggesting using
1479+
// the struct literal syntax at all, as that will cause a subsequent error.
1480+
let field_ids = self.r.field_def_ids(def_id);
1481+
let (fields, applicability) = match field_ids {
1482+
Some(field_ids) => {
1483+
let fields = field_ids.iter().map(|&id| self.r.tcx.item_name(id));
1484+
1485+
let fields = if let Some(old_fields) = old_fields {
1486+
fields
1487+
.enumerate()
1488+
.map(|(idx, new)| (new, old_fields.get(idx)))
1489+
.map(|(new, old)| {
1490+
let new = new.to_ident_string();
1491+
if let Some(Some(old)) = old
1492+
&& new != *old
1493+
{
1494+
format!("{new}: {old}")
1495+
} else {
1496+
new
1497+
}
1498+
})
1499+
.collect::<Vec<String>>()
1500+
} else {
1501+
fields.map(|f| format!("{f}{tail}")).collect::<Vec<String>>()
1502+
};
1503+
1504+
(fields.join(", "), applicability)
1505+
}
1506+
None => ("/* fields */".to_string(), Applicability::HasPlaceholders),
1507+
};
1508+
let pad = match field_ids {
1509+
Some(field_ids) if field_ids.is_empty() => "",
1510+
_ => " ",
1511+
};
1512+
err.span_suggestion(
1513+
span,
1514+
format!("use struct {descr} syntax instead"),
1515+
format!("{path_str} {{{pad}{fields}{pad}}}"),
1516+
applicability,
1517+
);
1518+
}
14901519
}
14911520
_ => {
14921521
err.span_label(span, fallback_label.to_string());

tests/ui/xcrate/xcrate-unit-struct.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ error[E0423]: expected value, found struct `xcrate_unit_struct::StructWithPrivFi
1313
--> $DIR/xcrate-unit-struct.rs:11:13
1414
|
1515
LL | let _ = xcrate_unit_struct::StructWithPrivFields;
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `xcrate_unit_struct::StructWithPrivFields { foo: val }`
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1717
|
1818
::: $DIR/auxiliary/xcrate_unit_struct.rs:25:1
1919
|

0 commit comments

Comments
 (0)