Skip to content

Commit fe00825

Browse files
authored
Merge branch 'rust-lang:master' into std-net-gethostname
2 parents 4d13b0a + 243d2ca commit fe00825

File tree

60 files changed

+1197
-931
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1197
-931
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3499,6 +3499,7 @@ name = "rustc_codegen_llvm"
34993499
version = "0.0.0"
35003500
dependencies = [
35013501
"bitflags",
3502+
"gimli 0.30.0",
35023503
"itertools",
35033504
"libc",
35043505
"measureme",

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_middle::mir::{
1717
};
1818
use rustc_middle::ty::adjustment::PointerCoercion;
1919
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
20+
use rustc_middle::util::CallKind;
2021
use rustc_span::{DesugaringKind, Span, Symbol, kw, sym};
2122
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
2223
use tracing::{debug, instrument};
@@ -635,6 +636,39 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
635636
// Used in a closure.
636637
(LaterUseKind::ClosureCapture, capture_kind_span, Some(path_span))
637638
}
639+
// In the case that the borrowed value (probably a temporary)
640+
// overlaps with the method's receiver, then point at the method.
641+
UseSpans::FnSelfUse {
642+
var_span: span,
643+
kind: CallKind::Normal { desugaring: None, .. },
644+
..
645+
} if span
646+
.overlaps(self.body.local_decls[borrow.assigned_place.local].source_info.span) =>
647+
{
648+
if let TerminatorKind::Call { func, call_source: CallSource::Normal, .. } =
649+
&self.body.basic_blocks[location.block].terminator().kind
650+
{
651+
// Just point to the function, to reduce the chance of overlapping spans.
652+
let function_span = match func {
653+
Operand::Constant(c) => c.span,
654+
Operand::Copy(place) | Operand::Move(place) => {
655+
if let Some(l) = place.as_local() {
656+
let local_decl = &self.body.local_decls[l];
657+
if self.local_names[l].is_none() {
658+
local_decl.source_info.span
659+
} else {
660+
span
661+
}
662+
} else {
663+
span
664+
}
665+
}
666+
};
667+
(LaterUseKind::Call, function_span, None)
668+
} else {
669+
(LaterUseKind::Other, span, None)
670+
}
671+
}
638672
UseSpans::PatUse(span)
639673
| UseSpans::OtherUse(span)
640674
| UseSpans::FnSelfUse { var_span: span, .. } => {

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -661,9 +661,6 @@ impl UseSpans<'_> {
661661
UseSpans::ClosureUse { args_span: span, .. }
662662
| UseSpans::PatUse(span)
663663
| UseSpans::OtherUse(span) => span,
664-
UseSpans::FnSelfUse { fn_call_span, kind: CallKind::DerefCoercion { .. }, .. } => {
665-
fn_call_span
666-
}
667664
UseSpans::FnSelfUse { var_span, .. } => var_span,
668665
}
669666
}
@@ -674,9 +671,6 @@ impl UseSpans<'_> {
674671
UseSpans::ClosureUse { path_span: span, .. }
675672
| UseSpans::PatUse(span)
676673
| UseSpans::OtherUse(span) => span,
677-
UseSpans::FnSelfUse { fn_call_span, kind: CallKind::DerefCoercion { .. }, .. } => {
678-
fn_call_span
679-
}
680674
UseSpans::FnSelfUse { var_span, .. } => var_span,
681675
}
682676
}
@@ -687,9 +681,6 @@ impl UseSpans<'_> {
687681
UseSpans::ClosureUse { capture_kind_span: span, .. }
688682
| UseSpans::PatUse(span)
689683
| UseSpans::OtherUse(span) => span,
690-
UseSpans::FnSelfUse { fn_call_span, kind: CallKind::DerefCoercion { .. }, .. } => {
691-
fn_call_span
692-
}
693684
UseSpans::FnSelfUse { var_span, .. } => var_span,
694685
}
695686
}

compiler/rustc_codegen_gcc/src/errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub(crate) struct UnstableCTargetFeature<'a> {
2828
#[diag(codegen_gcc_forbidden_ctarget_feature)]
2929
pub(crate) struct ForbiddenCTargetFeature<'a> {
3030
pub feature: &'a str,
31+
pub enabled: &'a str,
3132
pub reason: &'a str,
3233
}
3334

compiler/rustc_codegen_gcc/src/gcc_util.rs

Lines changed: 124 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
use std::iter::FromIterator;
2+
13
#[cfg(feature = "master")]
24
use gccjit::Context;
35
use rustc_codegen_ssa::codegen_attrs::check_tied_features;
46
use rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable;
5-
use rustc_data_structures::fx::FxHashMap;
6-
use rustc_middle::bug;
7+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
8+
use rustc_data_structures::unord::UnordSet;
79
use rustc_session::Session;
810
use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
911
use smallvec::{SmallVec, smallvec};
@@ -37,82 +39,137 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
3739
let mut features = vec![];
3840

3941
// Features implied by an implicit or explicit `--target`.
40-
features.extend(
41-
sess.target
42-
.features
43-
.split(',')
44-
.filter(|v| !v.is_empty() && backend_feature_name(v).is_some())
45-
.map(String::from),
46-
);
42+
features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from));
4743

4844
// -Ctarget-features
4945
let known_features = sess.target.rust_target_features();
5046
let mut featsmap = FxHashMap::default();
51-
let feats = sess
52-
.opts
53-
.cg
54-
.target_feature
55-
.split(',')
56-
.filter_map(|s| {
57-
let enable_disable = match s.chars().next() {
58-
None => return None,
59-
Some(c @ ('+' | '-')) => c,
60-
Some(_) => {
61-
if diagnostics {
62-
sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature: s });
63-
}
64-
return None;
65-
}
66-
};
6747

68-
// Get the backend feature name, if any.
69-
// This excludes rustc-specific features, that do not get passed down to GCC.
70-
let feature = backend_feature_name(s)?;
71-
// Warn against use of GCC specific feature names on the CLI.
48+
// Ensure that all ABI-required features are enabled, and the ABI-forbidden ones
49+
// are disabled.
50+
let abi_feature_constraints = sess.target.abi_required_features();
51+
let abi_incompatible_set =
52+
FxHashSet::from_iter(abi_feature_constraints.incompatible.iter().copied());
53+
54+
// Compute implied features
55+
let mut all_rust_features = vec![];
56+
for feature in sess.opts.cg.target_feature.split(',') {
57+
if let Some(feature) = feature.strip_prefix('+') {
58+
all_rust_features.extend(
59+
UnordSet::from(sess.target.implied_target_features(std::iter::once(feature)))
60+
.to_sorted_stable_ord()
61+
.iter()
62+
.map(|&&s| (true, s)),
63+
)
64+
} else if let Some(feature) = feature.strip_prefix('-') {
65+
// FIXME: Why do we not remove implied features on "-" here?
66+
// We do the equivalent above in `target_features_cfg`.
67+
// See <https://github.com/rust-lang/rust/issues/134792>.
68+
all_rust_features.push((false, feature));
69+
} else if !feature.is_empty() {
7270
if diagnostics {
73-
let feature_state = known_features.iter().find(|&&(v, _, _)| v == feature);
74-
match feature_state {
75-
None => {
76-
let rust_feature =
77-
known_features.iter().find_map(|&(rust_feature, _, _)| {
78-
let gcc_features = to_gcc_features(sess, rust_feature);
79-
if gcc_features.contains(&feature)
80-
&& !gcc_features.contains(&rust_feature)
81-
{
82-
Some(rust_feature)
83-
} else {
84-
None
85-
}
86-
});
87-
let unknown_feature = if let Some(rust_feature) = rust_feature {
88-
UnknownCTargetFeature {
89-
feature,
90-
rust_feature: PossibleFeature::Some { rust_feature },
91-
}
92-
} else {
93-
UnknownCTargetFeature { feature, rust_feature: PossibleFeature::None }
94-
};
95-
sess.dcx().emit_warn(unknown_feature);
96-
}
97-
Some((_, stability, _)) => {
98-
if let Err(reason) =
99-
stability.toggle_allowed(&sess.target, enable_disable == '+')
71+
sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature });
72+
}
73+
}
74+
}
75+
// Remove features that are meant for rustc, not codegen.
76+
all_rust_features.retain(|(_, feature)| {
77+
// Retain if it is not a rustc feature
78+
!RUSTC_SPECIFIC_FEATURES.contains(feature)
79+
});
80+
81+
// Check feature validity.
82+
if diagnostics {
83+
for &(enable, feature) in &all_rust_features {
84+
let feature_state = known_features.iter().find(|&&(v, _, _)| v == feature);
85+
match feature_state {
86+
None => {
87+
let rust_feature = known_features.iter().find_map(|&(rust_feature, _, _)| {
88+
let gcc_features = to_gcc_features(sess, rust_feature);
89+
if gcc_features.contains(&feature) && !gcc_features.contains(&rust_feature)
10090
{
101-
sess.dcx().emit_warn(ForbiddenCTargetFeature { feature, reason });
102-
} else if stability.requires_nightly().is_some() {
103-
// An unstable feature. Warn about using it. (It makes little sense
104-
// to hard-error here since we just warn about fully unknown
105-
// features above).
106-
sess.dcx().emit_warn(UnstableCTargetFeature { feature });
91+
Some(rust_feature)
92+
} else {
93+
None
10794
}
95+
});
96+
let unknown_feature = if let Some(rust_feature) = rust_feature {
97+
UnknownCTargetFeature {
98+
feature,
99+
rust_feature: PossibleFeature::Some { rust_feature },
100+
}
101+
} else {
102+
UnknownCTargetFeature { feature, rust_feature: PossibleFeature::None }
103+
};
104+
sess.dcx().emit_warn(unknown_feature);
105+
}
106+
Some((_, stability, _)) => {
107+
if let Err(reason) = stability.toggle_allowed() {
108+
sess.dcx().emit_warn(ForbiddenCTargetFeature {
109+
feature,
110+
enabled: if enable { "enabled" } else { "disabled" },
111+
reason,
112+
});
113+
} else if stability.requires_nightly().is_some() {
114+
// An unstable feature. Warn about using it. (It makes little sense
115+
// to hard-error here since we just warn about fully unknown
116+
// features above).
117+
sess.dcx().emit_warn(UnstableCTargetFeature { feature });
108118
}
109119
}
120+
}
110121

111-
// FIXME(nagisa): figure out how to not allocate a full hashset here.
112-
featsmap.insert(feature, enable_disable == '+');
122+
// Ensure that the features we enable/disable are compatible with the ABI.
123+
if enable {
124+
if abi_incompatible_set.contains(feature) {
125+
sess.dcx().emit_warn(ForbiddenCTargetFeature {
126+
feature,
127+
enabled: "enabled",
128+
reason: "this feature is incompatible with the target ABI",
129+
});
130+
}
131+
} else {
132+
// FIXME: we have to request implied features here since
133+
// negative features do not handle implied features above.
134+
for &required in abi_feature_constraints.required.iter() {
135+
let implied = sess.target.implied_target_features(std::iter::once(required));
136+
if implied.contains(feature) {
137+
sess.dcx().emit_warn(ForbiddenCTargetFeature {
138+
feature,
139+
enabled: "disabled",
140+
reason: "this feature is required by the target ABI",
141+
});
142+
}
143+
}
113144
}
114145

115-
// ... otherwise though we run through `to_gcc_features` when
146+
// FIXME(nagisa): figure out how to not allocate a full hashset here.
147+
featsmap.insert(feature, enable);
148+
}
149+
}
150+
151+
// To be sure the ABI-relevant features are all in the right state, we explicitly
152+
// (un)set them here. This means if the target spec sets those features wrong,
153+
// we will silently correct them rather than silently producing wrong code.
154+
// (The target sanity check tries to catch this, but we can't know which features are
155+
// enabled in GCC by default so we can't be fully sure about that check.)
156+
// We add these at the beginning of the list so that `-Ctarget-features` can
157+
// still override it... that's unsound, but more compatible with past behavior.
158+
all_rust_features.splice(
159+
0..0,
160+
abi_feature_constraints
161+
.required
162+
.iter()
163+
.map(|&f| (true, f))
164+
.chain(abi_feature_constraints.incompatible.iter().map(|&f| (false, f))),
165+
);
166+
167+
// Translate this into GCC features.
168+
let feats = all_rust_features
169+
.iter()
170+
.filter_map(|&(enable, feature)| {
171+
let enable_disable = if enable { '+' } else { '-' };
172+
// We run through `to_gcc_features` when
116173
// passing requests down to GCC. This means that all in-language
117174
// features also work on the command line instead of having two
118175
// different names when the GCC name and the Rust name differ.
@@ -146,26 +203,12 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
146203
features
147204
}
148205

149-
/// Returns a feature name for the given `+feature` or `-feature` string.
150-
///
151-
/// Only allows features that are backend specific (i.e. not [`RUSTC_SPECIFIC_FEATURES`].)
152-
fn backend_feature_name(s: &str) -> Option<&str> {
153-
// features must start with a `+` or `-`.
154-
let feature = s.strip_prefix(&['+', '-'][..]).unwrap_or_else(|| {
155-
bug!("target feature `{}` must begin with a `+` or `-`", s);
156-
});
157-
// Rustc-specific feature requests like `+crt-static` or `-crt-static`
158-
// are not passed down to GCC.
159-
if RUSTC_SPECIFIC_FEATURES.contains(&feature) {
160-
return None;
161-
}
162-
Some(feature)
163-
}
164-
165206
// To find a list of GCC's names, check https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
166207
pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> {
167208
let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch };
168209
match (arch, s) {
210+
// FIXME: seems like x87 does not exist?
211+
("x86", "x87") => smallvec![],
169212
("x86", "sse4.2") => smallvec!["sse4.2", "crc32"],
170213
("x86", "pclmulqdq") => smallvec!["pclmul"],
171214
("x86", "rdrand") => smallvec!["rdrnd"],

compiler/rustc_codegen_llvm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ test = false
99
[dependencies]
1010
# tidy-alphabetical-start
1111
bitflags = "2.4.1"
12+
gimli = "0.30"
1213
itertools = "0.12"
1314
libc = "0.2"
1415
measureme = "11"

compiler/rustc_codegen_llvm/messages.ftl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ codegen_llvm_dynamic_linking_with_lto =
1010
codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture
1111
1212
codegen_llvm_forbidden_ctarget_feature =
13-
target feature `{$feature}` cannot be toggled with `-Ctarget-feature`: {$reason}
13+
target feature `{$feature}` cannot be {$enabled} with `-Ctarget-feature`: {$reason}
1414
.note = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
1515
codegen_llvm_forbidden_ctarget_feature_issue = for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
1616
@@ -24,8 +24,6 @@ codegen_llvm_invalid_minimum_alignment_not_power_of_two =
2424
codegen_llvm_invalid_minimum_alignment_too_large =
2525
invalid minimum global alignment: {$align} is too large
2626
27-
codegen_llvm_invalid_target_feature_prefix = target feature `{$feature}` must begin with a `+` or `-`"
28-
2927
codegen_llvm_load_bitcode = failed to load bitcode of module "{$name}"
3028
codegen_llvm_load_bitcode_with_llvm_err = failed to load bitcode of module "{$name}": {$llvm_err}
3129

0 commit comments

Comments
 (0)