Skip to content

Commit b35ebac

Browse files
committed
Auto merge of #64466 - Centril:rollup-s3nlb9e, r=Centril
Rollup of 4 pull requests Successful merges: - #61797 (Stabilise weak_ptr_eq) - #64290 (Provide a span if main function is not present in crate) - #64406 (Ban non-extern rust intrinsics) - #64462 (feature_gate: Remove dead code from attribute checking) Failed merges: r? @ghost
2 parents ca3766e + 45e50e2 commit b35ebac

File tree

66 files changed

+433
-395
lines changed

Some content is hidden

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

66 files changed

+433
-395
lines changed

src/liballoc/rc.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1832,8 +1832,9 @@ impl<T: ?Sized> Weak<T> {
18321832
}
18331833
}
18341834

1835-
/// Returns `true` if the two `Weak`s point to the same value (not just values
1836-
/// that compare as equal).
1835+
/// Returns `true` if the two `Weak`s point to the same value (not just
1836+
/// values that compare as equal), or if both don't point to any value
1837+
/// (because they were created with `Weak::new()`).
18371838
///
18381839
/// # Notes
18391840
///
@@ -1843,7 +1844,6 @@ impl<T: ?Sized> Weak<T> {
18431844
/// # Examples
18441845
///
18451846
/// ```
1846-
/// #![feature(weak_ptr_eq)]
18471847
/// use std::rc::Rc;
18481848
///
18491849
/// let first_rc = Rc::new(5);
@@ -1861,7 +1861,6 @@ impl<T: ?Sized> Weak<T> {
18611861
/// Comparing `Weak::new`.
18621862
///
18631863
/// ```
1864-
/// #![feature(weak_ptr_eq)]
18651864
/// use std::rc::{Rc, Weak};
18661865
///
18671866
/// let first = Weak::new();
@@ -1873,7 +1872,7 @@ impl<T: ?Sized> Weak<T> {
18731872
/// assert!(!first.ptr_eq(&third));
18741873
/// ```
18751874
#[inline]
1876-
#[unstable(feature = "weak_ptr_eq", issue = "55981")]
1875+
#[stable(feature = "weak_ptr_eq", since = "1.39.0")]
18771876
pub fn ptr_eq(&self, other: &Self) -> bool {
18781877
self.ptr.as_ptr() == other.ptr.as_ptr()
18791878
}

src/liballoc/sync.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -1550,19 +1550,18 @@ impl<T: ?Sized> Weak<T> {
15501550
}
15511551
}
15521552

1553-
/// Returns `true` if the two `Weak`s point to the same value (not just values
1554-
/// that compare as equal).
1553+
/// Returns `true` if the two `Weak`s point to the same value (not just
1554+
/// values that compare as equal), or if both don't point to any value
1555+
/// (because they were created with `Weak::new()`).
15551556
///
15561557
/// # Notes
15571558
///
15581559
/// Since this compares pointers it means that `Weak::new()` will equal each
15591560
/// other, even though they don't point to any value.
15601561
///
1561-
///
15621562
/// # Examples
15631563
///
15641564
/// ```
1565-
/// #![feature(weak_ptr_eq)]
15661565
/// use std::sync::Arc;
15671566
///
15681567
/// let first_rc = Arc::new(5);
@@ -1580,7 +1579,6 @@ impl<T: ?Sized> Weak<T> {
15801579
/// Comparing `Weak::new`.
15811580
///
15821581
/// ```
1583-
/// #![feature(weak_ptr_eq)]
15841582
/// use std::sync::{Arc, Weak};
15851583
///
15861584
/// let first = Weak::new();
@@ -1592,7 +1590,7 @@ impl<T: ?Sized> Weak<T> {
15921590
/// assert!(!first.ptr_eq(&third));
15931591
/// ```
15941592
#[inline]
1595-
#[unstable(feature = "weak_ptr_eq", issue = "55981")]
1593+
#[stable(feature = "weak_ptr_eq", since = "1.39.0")]
15961594
pub fn ptr_eq(&self, other: &Self) -> bool {
15971595
self.ptr.as_ptr() == other.ptr.as_ptr()
15981596
}

src/librustc/middle/entry.rs

+44-30
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ struct EntryContext<'a, 'tcx> {
1616

1717
map: &'a hir_map::Map<'tcx>,
1818

19-
/// The top-level function called 'main'.
19+
/// The top-level function called `main`.
2020
main_fn: Option<(HirId, Span)>,
2121

22-
/// The function that has attribute named 'main'.
22+
/// The function that has attribute named `main`.
2323
attr_main_fn: Option<(HirId, Span)>,
2424

2525
/// The function that has the attribute 'start' on it.
2626
start_fn: Option<(HirId, Span)>,
2727

28-
/// The functions that one might think are 'main' but aren't, e.g.
28+
/// The functions that one might think are `main` but aren't, e.g.
2929
/// main functions not defined at the top level. For diagnostics.
3030
non_main_fns: Vec<(HirId, Span)> ,
3131
}
@@ -88,7 +88,7 @@ fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
8888
EntryPointType::MainAttr
8989
} else if item.ident.name == sym::main {
9090
if at_root {
91-
// This is a top-level function so can be 'main'.
91+
// This is a top-level function so can be `main`.
9292
EntryPointType::MainNamed
9393
} else {
9494
EntryPointType::OtherMain
@@ -109,7 +109,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
109109
ctxt.main_fn = Some((item.hir_id, item.span));
110110
} else {
111111
span_err!(ctxt.session, item.span, E0136,
112-
"multiple 'main' functions");
112+
"multiple `main` functions");
113113
}
114114
},
115115
EntryPointType::OtherMain => {
@@ -130,7 +130,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
130130
if ctxt.start_fn.is_none() {
131131
ctxt.start_fn = Some((item.hir_id, item.span));
132132
} else {
133-
struct_span_err!(ctxt.session, item.span, E0138, "multiple 'start' functions")
133+
struct_span_err!(ctxt.session, item.span, E0138, "multiple `start` functions")
134134
.span_label(ctxt.start_fn.unwrap().1, "previous `start` function here")
135135
.span_label(item.span, "multiple `start` functions")
136136
.emit();
@@ -148,34 +148,48 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De
148148
} else if let Some((hir_id, _)) = visitor.main_fn {
149149
Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main))
150150
} else {
151-
// There is no main function.
152-
let mut err = struct_err!(tcx.sess, E0601,
153-
"`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE));
154-
if !visitor.non_main_fns.is_empty() {
155-
// There were some functions named 'main' though. Try to give the user a hint.
156-
err.note("the main function must be defined at the crate level \
157-
but you have one or more functions named 'main' that are not \
158-
defined at the crate level. Either move the definition or \
159-
attach the `#[main]` attribute to override this behavior.");
160-
for &(_, span) in &visitor.non_main_fns {
161-
err.span_note(span, "here is a function named 'main'");
162-
}
163-
err.emit();
164-
} else {
165-
if let Some(ref filename) = tcx.sess.local_crate_source_file {
166-
err.note(&format!("consider adding a `main` function to `{}`", filename.display()));
167-
}
168-
if tcx.sess.teach(&err.get_code().unwrap()) {
169-
err.note("If you don't know the basics of Rust, you can go look to the Rust Book \
170-
to get started: https://doc.rust-lang.org/book/");
171-
}
172-
err.emit();
173-
}
174-
151+
no_main_err(tcx, visitor);
175152
None
176153
}
177154
}
178155

156+
fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
157+
// There is no main function.
158+
let mut err = struct_err!(tcx.sess, E0601,
159+
"`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE));
160+
let filename = &tcx.sess.local_crate_source_file;
161+
let note = if !visitor.non_main_fns.is_empty() {
162+
for &(_, span) in &visitor.non_main_fns {
163+
err.span_note(span, "here is a function named `main`");
164+
}
165+
err.note("you have one or more functions named `main` not defined at the crate level");
166+
err.help("either move the `main` function definitions or attach the `#[main]` attribute \
167+
to one of them");
168+
// There were some functions named `main` though. Try to give the user a hint.
169+
format!("the main function must be defined at the crate level{}",
170+
filename.as_ref().map(|f| format!(" (in `{}`)", f.display())).unwrap_or_default())
171+
} else if let Some(filename) = filename {
172+
format!("consider adding a `main` function to `{}`", filename.display())
173+
} else {
174+
String::from("consider adding a `main` function at the crate level")
175+
};
176+
let sp = tcx.hir().krate().span;
177+
// The file may be empty, which leads to the diagnostic machinery not emitting this
178+
// note. This is a relatively simple way to detect that case and emit a span-less
179+
// note instead.
180+
if let Ok(_) = tcx.sess.source_map().lookup_line(sp.lo()) {
181+
err.set_span(sp);
182+
err.span_label(sp, &note);
183+
} else {
184+
err.note(&note);
185+
}
186+
if tcx.sess.teach(&err.get_code().unwrap()) {
187+
err.note("If you don't know the basics of Rust, you can go look to the Rust Book \
188+
to get started: https://doc.rust-lang.org/book/");
189+
}
190+
err.emit();
191+
}
192+
179193
pub fn find_entry_point(tcx: TyCtxt<'_>) -> Option<(DefId, EntryFnType)> {
180194
tcx.entry_fn(LOCAL_CRATE)
181195
}

src/librustc_interface/passes.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ use syntax::mut_visit::MutVisitor;
4141
use syntax::parse::{self, PResult};
4242
use syntax::util::node_count::NodeCounter;
4343
use syntax::symbol::Symbol;
44-
use syntax::feature_gate::AttributeType;
4544
use syntax_pos::FileName;
4645
use syntax_ext;
4746

@@ -219,7 +218,6 @@ impl BoxedResolver {
219218

220219
pub struct PluginInfo {
221220
syntax_exts: Vec<NamedSyntaxExtension>,
222-
attributes: Vec<(Symbol, AttributeType)>,
223221
}
224222

225223
pub fn register_plugins<'a>(
@@ -312,12 +310,9 @@ pub fn register_plugins<'a>(
312310
}
313311

314312
*sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
315-
*sess.plugin_attributes.borrow_mut() = attributes.clone();
313+
*sess.plugin_attributes.borrow_mut() = attributes;
316314

317-
Ok((krate, PluginInfo {
318-
syntax_exts,
319-
attributes,
320-
}))
315+
Ok((krate, PluginInfo { syntax_exts }))
321316
}
322317

323318
fn configure_and_expand_inner<'a>(
@@ -329,7 +324,6 @@ fn configure_and_expand_inner<'a>(
329324
crate_loader: &'a mut CrateLoader<'a>,
330325
plugin_info: PluginInfo,
331326
) -> Result<(ast::Crate, Resolver<'a>)> {
332-
let attributes = plugin_info.attributes;
333327
time(sess, "pre ast expansion lint checks", || {
334328
lint::check_ast_crate(
335329
sess,
@@ -522,7 +516,6 @@ fn configure_and_expand_inner<'a>(
522516
&krate,
523517
&sess.parse_sess,
524518
&sess.features_untracked(),
525-
&attributes,
526519
sess.opts.unstable_features,
527520
);
528521
});

src/librustc_typeck/check/mod.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,8 @@ fn check_fn<'a, 'tcx>(
10881088

10891089
let span = body.value.span;
10901090

1091+
fn_maybe_err(fcx.tcx, span, fn_sig.abi);
1092+
10911093
if body.generator_kind.is_some() && can_be_generator.is_some() {
10921094
let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
10931095
kind: TypeVariableOriginKind::TypeInference,
@@ -1439,6 +1441,14 @@ fn check_opaque_for_cycles<'tcx>(
14391441
}
14401442
}
14411443

1444+
// Forbid defining intrinsics in Rust code,
1445+
// as they must always be defined by the compiler.
1446+
fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1447+
if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1448+
tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1449+
}
1450+
}
1451+
14421452
pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
14431453
debug!(
14441454
"check_item_type(it.hir_id={}, it.name={})",
@@ -1475,9 +1485,17 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
14751485
check_on_unimplemented(tcx, trait_def_id, it);
14761486
}
14771487
}
1478-
hir::ItemKind::Trait(..) => {
1488+
hir::ItemKind::Trait(_, _, _, _, ref items) => {
14791489
let def_id = tcx.hir().local_def_id(it.hir_id);
14801490
check_on_unimplemented(tcx, def_id, it);
1491+
1492+
for item in items.iter() {
1493+
let item = tcx.hir().trait_item(item.id);
1494+
if let hir::TraitItemKind::Method(sig, _) = &item.node {
1495+
let abi = sig.header.abi;
1496+
fn_maybe_err(tcx, item.ident.span, abi);
1497+
}
1498+
}
14811499
}
14821500
hir::ItemKind::Struct(..) => {
14831501
check_struct(tcx, it.hir_id, it.span);

src/libsyntax/ext/expand.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use syntax_pos::{Span, DUMMY_SP, FileName};
2626
use rustc_data_structures::fx::FxHashMap;
2727
use rustc_data_structures::sync::Lrc;
2828
use std::io::ErrorKind;
29-
use std::{iter, mem};
29+
use std::{iter, mem, slice};
3030
use std::ops::DerefMut;
3131
use std::rc::Rc;
3232
use std::path::PathBuf;
@@ -1019,7 +1019,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
10191019
fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
10201020
let features = self.cx.ecfg.features.unwrap();
10211021
for attr in attrs.iter() {
1022-
self.check_attribute_inner(attr, features);
1022+
feature_gate::check_attribute(attr, self.cx.parse_sess, features);
10231023

10241024
// macros are expanded before any lint passes so this warning has to be hardcoded
10251025
if attr.path == sym::derive {
@@ -1029,15 +1029,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
10291029
}
10301030
}
10311031
}
1032-
1033-
fn check_attribute(&mut self, at: &ast::Attribute) {
1034-
let features = self.cx.ecfg.features.unwrap();
1035-
self.check_attribute_inner(at, features);
1036-
}
1037-
1038-
fn check_attribute_inner(&mut self, at: &ast::Attribute, features: &Features) {
1039-
feature_gate::check_attribute(at, self.cx.parse_sess, features);
1040-
}
10411032
}
10421033

10431034
impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
@@ -1445,7 +1436,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
14451436

14461437
if let Some(file) = it.value_str() {
14471438
let err_count = self.cx.parse_sess.span_diagnostic.err_count();
1448-
self.check_attribute(&at);
1439+
self.check_attributes(slice::from_ref(at));
14491440
if self.cx.parse_sess.span_diagnostic.err_count() > err_count {
14501441
// avoid loading the file if they haven't enabled the feature
14511442
return noop_visit_attribute(at, self);

src/libsyntax/feature_gate/builtin_attrs.rs

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub enum AttributeType {
7979
CrateLevel,
8080
}
8181

82+
#[derive(Clone, Copy)]
8283
pub enum AttributeGate {
8384
/// Is gated by a given feature gate, reason
8485
/// and function to check if enabled

0 commit comments

Comments
 (0)