syntax: Feature gate #[start] and #[main]

These two attributes are used to change the entry point into a Rust program, but
for now they're being put behind feature gates until we have a chance to think
about them a little more. The #[start] attribute specifically may have its
signature changed.

This is a breaking change to due the usage of these attributes generating errors
by default now. If your crate is using these attributes, add this to your crate
root:

    #![feature(start)] // if you're using the #[start] attribute
    #![feature(main)]  // if you're using the #[main] attribute

cc #20064
This commit is contained in:
Alex Crichton 2015-01-16 10:55:24 -08:00
parent ee2bfae011
commit 38cb91e66c
26 changed files with 71 additions and 13 deletions

View file

@ -447,7 +447,7 @@ in the same format as C:
```
#![no_std]
#![feature(lang_items)]
#![feature(lang_items, start)]
// Pull in the system libc library for what crt0.o likely requires
extern crate libc;
@ -475,7 +475,7 @@ compiler's name mangling too:
```ignore
#![no_std]
#![no_main]
#![feature(lang_items)]
#![feature(lang_items, start)]
extern crate libc;
@ -529,7 +529,7 @@ vectors provided from C, using idiomatic Rust practices.
```
#![no_std]
#![feature(lang_items)]
#![feature(lang_items, start)]
# extern crate libc;
extern crate core;
@ -653,7 +653,7 @@ sugar for dynamic allocations via `malloc` and `free`:
```
#![no_std]
#![feature(lang_items, box_syntax)]
#![feature(lang_items, box_syntax, start)]
extern crate libc;

View file

@ -77,6 +77,8 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
("while_let", Accepted),
("plugin", Active),
("start", Active),
("main", Active),
// A temporary feature gate used to enable parser extensions needed
// to bootstrap fix for #5723.
@ -276,6 +278,18 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
self.gate_feature("plugin_registrar", i.span,
"compiler plugins are experimental and possibly buggy");
}
if attr::contains_name(&i.attrs[], "start") {
self.gate_feature("start", i.span,
"a #[start] function is an experimental \
feature whose signature may change \
over time");
}
if attr::contains_name(&i.attrs[], "main") {
self.gate_feature("main", i.span,
"declaration of a nonstandard #[main] \
function may change over time, for now \
a top-level `fn main()` is required");
}
}
ast::ItemStruct(..) => {

View file

@ -0,0 +1,12 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[main]
fn foo() {} //~ ERROR: declaration of a nonstandard #[main] function may change over time

View file

@ -0,0 +1,13 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[start]
fn foo() {} //~ ERROR: a #[start] function is an experimental feature

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(start)]
#[start]
fn start(argc: isize, argv: *const *const u8, crate_map: *const u8) -> isize {
//~^ ERROR incorrect number of function parameters

View file

@ -14,6 +14,7 @@
// error-pattern: requires `sized` lang_item
#![no_std]
#![feature(start)]
#[start]
fn start(argc: isize, argv: *const *const u8) -> isize {

View file

@ -10,6 +10,7 @@
#![allow(unused_variables)]
#![deny(dead_code)]
#![feature(main, start)]
struct Foo;

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(main)]
#[main]
fn bar() {
}

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(main)]
#[main]
fn main1() {
}

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(lang_items)]
#![feature(lang_items, start)]
#![no_std] // makes debugging this test *a lot* easier (during resolve)
#[lang="sized"]

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(start)]
#![no_std] // makes debugging this test *a lot* easier (during resolve)
// Test to make sure that globs don't leak in regular `use` statements.

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(start)]
#![no_std] // makes debugging this test *a lot* easier (during resolve)
// Test to make sure that private items imported through globs remain private

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(lang_items)]
#![feature(lang_items, start)]
#![no_std] // makes debugging this test *a lot* easier (during resolve)
#[lang = "sized"] pub trait Sized {}

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(main)]
pub fn main() {
panic!()

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(main)]
#[main]
fn foo() {

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(start)]
#[start]
fn start(_argc: int, _argv: *const *const u8) -> int {

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(main)]
#[main]
fn foo() {
}

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(intrinsics)]
#![feature(intrinsics, main)]
mod rusti {
extern "rust-intrinsic" {

View file

@ -9,6 +9,7 @@
// except according to those terms.
// compile-flags:--test
// no-pretty-expanded
// This verifies that the test generation doesn't crash when we have
// no tests - for more information, see PR #16892.

View file

@ -9,6 +9,7 @@
// except according to those terms.
// compile-flags: --test
// no-pretty-expanded
#![deny(unstable)]

View file

@ -13,7 +13,7 @@
// ignore-windows #13361
#![no_std]
#![feature(lang_items)]
#![feature(lang_items, start)]
extern crate "lang-item-public" as lang_lib;

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(start)]
#[start]
pub fn main(_: int, _: *const *const u8) -> int {

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(start)]
use std::ffi;
use std::io::process::{Command, ProcessOutput};
use std::os;

View file

@ -13,7 +13,7 @@
// Smallest "hello world" with a libc runtime
#![no_std]
#![feature(intrinsics, lang_items)]
#![feature(intrinsics, lang_items, start)]
extern crate libc;

View file

@ -9,14 +9,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(unused_imports)]
#![feature(start)]
#![no_std]
extern crate std;
extern crate "std" as zed;
use std::str;
use zed::str as x;
mod baz {

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(lang_items)]
#![feature(lang_items, start)]
#![no_std]
extern crate "std" as other;