1
Fork 0

Auto merge of #77224 - RalfJung:rollup-hdvb96c, r=RalfJung

Rollup of 12 pull requests

Successful merges:

 - #75454 (Explicitly document the size guarantees that Option makes.)
 - #76631 (Add `x.py setup`)
 - #77076 (Add missing code examples on slice iter types)
 - #77093 (merge `need_type_info_err(_const)`)
 - #77122 (Add `#![feature(const_fn_floating_point_arithmetic)]`)
 - #77127 (Update mdBook)
 - #77161 (Remove TrustedLen requirement from BuilderMethods::switch)
 - #77166 (update Miri)
 - #77181 (Add doc alias for pointer primitive)
 - #77204 (Remove stray word from `ClosureKind::extends` docs)
 - #77207 (Rename `whence` to `span`)
 - #77211 (Remove unused #[allow(...)] statements from compiler/)

Failed merges:

 - #77170 (Remove `#[rustc_allow_const_fn_ptr]` and add `#![feature(const_fn_fn_ptr_basics)]`)

r? `@ghost`
This commit is contained in:
bors 2020-09-26 17:50:26 +00:00
commit e37c99fa1c
74 changed files with 808 additions and 342 deletions

View file

@ -1848,9 +1848,9 @@ dependencies = [
[[package]] [[package]]
name = "mdbook" name = "mdbook"
version = "0.4.2" version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75e31ae4eaa0e45e17ee2b6b9e3ed969c3c6ff12bb4c2e352c42493f4ebb706" checksum = "29be448fcafb00c5a8966c4020c2a5ffbbc333e5b96d0bb5ef54b5bd0524d9ff"
dependencies = [ dependencies = [
"ammonia", "ammonia",
"anyhow", "anyhow",

View file

@ -15,7 +15,6 @@
#![feature(new_uninit)] #![feature(new_uninit)]
#![feature(maybe_uninit_slice)] #![feature(maybe_uninit_slice)]
#![cfg_attr(test, feature(test))] #![cfg_attr(test, feature(test))]
#![allow(deprecated)]
use rustc_data_structures::cold_path; use rustc_data_structures::cold_path;
use smallvec::SmallVec; use smallvec::SmallVec;

View file

@ -21,7 +21,6 @@ use rustc_target::abi::{self, Align, Size};
use rustc_target::spec::{HasTargetSpec, Target}; use rustc_target::spec::{HasTargetSpec, Target};
use std::borrow::Cow; use std::borrow::Cow;
use std::ffi::CStr; use std::ffi::CStr;
use std::iter::TrustedLen;
use std::ops::{Deref, Range}; use std::ops::{Deref, Range};
use std::ptr; use std::ptr;
use tracing::debug; use tracing::debug;
@ -179,7 +178,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
&mut self, &mut self,
v: &'ll Value, v: &'ll Value,
else_llbb: &'ll BasicBlock, else_llbb: &'ll BasicBlock,
cases: impl ExactSizeIterator<Item = (u128, &'ll BasicBlock)> + TrustedLen, cases: impl ExactSizeIterator<Item = (u128, &'ll BasicBlock)>,
) { ) {
let switch = let switch =
unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, cases.len() as c_uint) }; unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, cases.len() as c_uint) };
@ -931,7 +930,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
unsafe { llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, UNNAMED) } unsafe { llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, UNNAMED) }
} }
#[allow(dead_code)]
fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) } unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
} }

View file

@ -1,5 +1,3 @@
#![allow(non_camel_case_types, non_snake_case)]
//! Code that is useful in various codegen modules. //! Code that is useful in various codegen modules.
use crate::consts::{self, const_alloc_to_llvm}; use crate::consts::{self, const_alloc_to_llvm};

View file

@ -1845,7 +1845,6 @@ impl<'tcx> VariantInfo<'_, 'tcx> {
None None
} }
#[allow(dead_code)]
fn is_artificial(&self) -> bool { fn is_artificial(&self) -> bool {
match self { match self {
VariantInfo::Generator { .. } => true, VariantInfo::Generator { .. } => true,

View file

@ -12,7 +12,6 @@
#![feature(in_band_lifetimes)] #![feature(in_band_lifetimes)]
#![feature(nll)] #![feature(nll)]
#![feature(or_patterns)] #![feature(or_patterns)]
#![feature(trusted_len)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
use back::write::{create_informational_target_machine, create_target_machine}; use back::write::{create_informational_target_machine, create_target_machine};

View file

@ -11,7 +11,6 @@ use rustc_middle::ty::layout::HasTyCtxt;
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size}; use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size};
#[allow(dead_code)]
fn round_pointer_up_to_alignment( fn round_pointer_up_to_alignment(
bx: &mut Builder<'a, 'll, 'tcx>, bx: &mut Builder<'a, 'll, 'tcx>,
addr: &'ll Value, addr: &'ll Value,

View file

@ -1,4 +1,4 @@
#![allow(non_camel_case_types, non_snake_case)] #![allow(non_camel_case_types)]
use rustc_errors::struct_span_err; use rustc_errors::struct_span_err;
use rustc_hir as hir; use rustc_hir as hir;
@ -25,7 +25,6 @@ pub enum IntPredicate {
IntSLE, IntSLE,
} }
#[allow(dead_code)]
pub enum RealPredicate { pub enum RealPredicate {
RealPredicateFalse, RealPredicateFalse,
RealOEQ, RealOEQ,
@ -60,7 +59,6 @@ pub enum AtomicRmwBinOp {
} }
pub enum AtomicOrdering { pub enum AtomicOrdering {
#[allow(dead_code)]
NotAtomic, NotAtomic,
Unordered, Unordered,
Monotonic, Monotonic,

View file

@ -6,7 +6,6 @@
#![feature(in_band_lifetimes)] #![feature(in_band_lifetimes)]
#![feature(nll)] #![feature(nll)]
#![feature(or_patterns)] #![feature(or_patterns)]
#![feature(trusted_len)]
#![feature(associated_type_bounds)] #![feature(associated_type_bounds)]
#![recursion_limit = "256"] #![recursion_limit = "256"]

View file

@ -18,7 +18,6 @@ use rustc_middle::ty::Ty;
use rustc_target::abi::{Abi, Align, Scalar, Size}; use rustc_target::abi::{Abi, Align, Scalar, Size};
use rustc_target::spec::HasTargetSpec; use rustc_target::spec::HasTargetSpec;
use std::iter::TrustedLen;
use std::ops::Range; use std::ops::Range;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -60,7 +59,7 @@ pub trait BuilderMethods<'a, 'tcx>:
&mut self, &mut self,
v: Self::Value, v: Self::Value,
else_llbb: Self::BasicBlock, else_llbb: Self::BasicBlock,
cases: impl ExactSizeIterator<Item = (u128, Self::BasicBlock)> + TrustedLen, cases: impl ExactSizeIterator<Item = (u128, Self::BasicBlock)>,
); );
fn invoke( fn invoke(
&mut self, &mut self,

View file

@ -7,7 +7,6 @@
//! This API is completely unstable and subject to change. //! This API is completely unstable and subject to change.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![allow(incomplete_features)]
#![feature(array_windows)] #![feature(array_windows)]
#![feature(control_flow_enum)] #![feature(control_flow_enum)]
#![feature(in_band_lifetimes)] #![feature(in_band_lifetimes)]

View file

@ -584,6 +584,9 @@ declare_features! (
/// Allows non trivial generic constants which have to be manually propageted upwards. /// Allows non trivial generic constants which have to be manually propageted upwards.
(active, const_evaluatable_checked, "1.48.0", Some(76560), None), (active, const_evaluatable_checked, "1.48.0", Some(76560), None),
/// Allows basic arithmetic on floating point types in a `const fn`.
(active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None),
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// feature-group-end: actual feature gates // feature-group-end: actual feature gates
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------

View file

@ -256,7 +256,6 @@ pub trait Visitor<'v>: Sized {
/// patterns described on `itemlikevisit::ItemLikeVisitor`. The only /// patterns described on `itemlikevisit::ItemLikeVisitor`. The only
/// reason to override this method is if you want a nested pattern /// reason to override this method is if you want a nested pattern
/// but cannot supply a `Map`; see `nested_visit_map` for advice. /// but cannot supply a `Map`; see `nested_visit_map` for advice.
#[allow(unused_variables)]
fn visit_nested_item(&mut self, id: ItemId) { fn visit_nested_item(&mut self, id: ItemId) {
let opt_item = self.nested_visit_map().inter().map(|map| map.item(id.id)); let opt_item = self.nested_visit_map().inter().map(|map| map.item(id.id));
walk_list!(self, visit_item, opt_item); walk_list!(self, visit_item, opt_item);
@ -265,7 +264,6 @@ pub trait Visitor<'v>: Sized {
/// Like `visit_nested_item()`, but for trait items. See /// Like `visit_nested_item()`, but for trait items. See
/// `visit_nested_item()` for advice on when to override this /// `visit_nested_item()` for advice on when to override this
/// method. /// method.
#[allow(unused_variables)]
fn visit_nested_trait_item(&mut self, id: TraitItemId) { fn visit_nested_trait_item(&mut self, id: TraitItemId) {
let opt_item = self.nested_visit_map().inter().map(|map| map.trait_item(id)); let opt_item = self.nested_visit_map().inter().map(|map| map.trait_item(id));
walk_list!(self, visit_trait_item, opt_item); walk_list!(self, visit_trait_item, opt_item);
@ -274,7 +272,6 @@ pub trait Visitor<'v>: Sized {
/// Like `visit_nested_item()`, but for impl items. See /// Like `visit_nested_item()`, but for impl items. See
/// `visit_nested_item()` for advice on when to override this /// `visit_nested_item()` for advice on when to override this
/// method. /// method.
#[allow(unused_variables)]
fn visit_nested_impl_item(&mut self, id: ImplItemId) { fn visit_nested_impl_item(&mut self, id: ImplItemId) {
let opt_item = self.nested_visit_map().inter().map(|map| map.impl_item(id)); let opt_item = self.nested_visit_map().inter().map(|map| map.impl_item(id));
walk_list!(self, visit_impl_item, opt_item); walk_list!(self, visit_impl_item, opt_item);

View file

@ -176,7 +176,10 @@ fn closure_return_type_suggestion(
suggestion, suggestion,
Applicability::HasPlaceholders, Applicability::HasPlaceholders,
); );
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr)); err.span_label(
span,
InferCtxt::cannot_infer_msg("type", &name, &descr, parent_name, parent_descr),
);
} }
/// Given a closure signature, return a `String` containing a list of all its argument types. /// Given a closure signature, return a `String` containing a list of all its argument types.
@ -217,65 +220,151 @@ impl Into<rustc_errors::DiagnosticId> for TypeAnnotationNeeded {
} }
} }
/// Information about a constant or a type containing inference variables.
pub struct InferenceDiagnosticsData {
pub name: String,
pub span: Option<Span>,
pub description: Cow<'static, str>,
pub parent_name: Option<String>,
pub parent_description: Option<&'static str>,
}
impl<'a, 'tcx> InferCtxt<'a, 'tcx> { impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn extract_type_name( /// Extracts data used by diagnostic for either types or constants
/// which were stuck during inference.
pub fn extract_inference_diagnostics_data(
&self, &self,
ty: Ty<'tcx>, arg: GenericArg<'tcx>,
highlight: Option<ty::print::RegionHighlightMode>, highlight: Option<ty::print::RegionHighlightMode>,
) -> (String, Option<Span>, Cow<'static, str>, Option<String>, Option<&'static str>) { ) -> InferenceDiagnosticsData {
if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() { match arg.unpack() {
let mut inner = self.inner.borrow_mut(); GenericArgKind::Type(ty) => {
let ty_vars = &inner.type_variables(); if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() {
let var_origin = ty_vars.var_origin(ty_vid); let mut inner = self.inner.borrow_mut();
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind { let ty_vars = &inner.type_variables();
let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id)); let var_origin = ty_vars.var_origin(ty_vid);
let (parent_name, parent_desc) = if let Some(parent_def_id) = parent_def_id { if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) =
let parent_name = self var_origin.kind
.tcx {
.def_key(parent_def_id) let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id));
.disambiguated_data let (parent_name, parent_description) =
.data if let Some(parent_def_id) = parent_def_id {
.get_opt_name() let parent_name = self
.map(|parent_symbol| parent_symbol.to_string()); .tcx
.def_key(parent_def_id)
.disambiguated_data
.data
.get_opt_name()
.map(|parent_symbol| parent_symbol.to_string());
(parent_name, Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id))) (
} else { parent_name,
(None, None) Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)),
}; )
} else {
(None, None)
};
if name != kw::SelfUpper { if name != kw::SelfUpper {
return ( return InferenceDiagnosticsData {
name.to_string(), name: name.to_string(),
Some(var_origin.span), span: Some(var_origin.span),
"type parameter".into(), description: "type parameter".into(),
parent_name, parent_name,
parent_desc, parent_description,
); };
}
}
}
let mut s = String::new();
let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
if let Some(highlight) = highlight {
printer.region_highlight_mode = highlight;
}
let _ = ty.print(printer);
InferenceDiagnosticsData {
name: s,
span: None,
description: ty.prefix_string(),
parent_name: None,
parent_description: None,
} }
} }
} GenericArgKind::Const(ct) => {
if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val {
let origin =
self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) =
origin.kind
{
let parent_def_id = self.tcx.parent(def_id);
let (parent_name, parent_description) =
if let Some(parent_def_id) = parent_def_id {
let parent_name = self
.tcx
.def_key(parent_def_id)
.disambiguated_data
.data
.get_opt_name()
.map(|parent_symbol| parent_symbol.to_string());
let mut s = String::new(); (
let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS); parent_name,
if let Some(highlight) = highlight { Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)),
printer.region_highlight_mode = highlight; )
} else {
(None, None)
};
return InferenceDiagnosticsData {
name: name.to_string(),
span: Some(origin.span),
description: "const parameter".into(),
parent_name,
parent_description,
};
}
debug_assert!(!origin.span.is_dummy());
let mut s = String::new();
let mut printer =
ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::ValueNS);
if let Some(highlight) = highlight {
printer.region_highlight_mode = highlight;
}
let _ = ct.print(printer);
InferenceDiagnosticsData {
name: s,
span: Some(origin.span),
description: "the constant".into(),
parent_name: None,
parent_description: None,
}
} else {
bug!("unexpect const: {:?}", ct);
}
}
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
} }
let _ = ty.print(printer);
(s, None, ty.prefix_string(), None, None)
} }
// FIXME(eddyb) generalize all of this to handle `ty::Const` inference variables as well. pub fn emit_inference_failure_err(
pub fn need_type_info_err(
&self, &self,
body_id: Option<hir::BodyId>, body_id: Option<hir::BodyId>,
span: Span, span: Span,
ty: Ty<'tcx>, arg: GenericArg<'tcx>,
error_code: TypeAnnotationNeeded, error_code: TypeAnnotationNeeded,
) -> DiagnosticBuilder<'tcx> { ) -> DiagnosticBuilder<'tcx> {
let ty = self.resolve_vars_if_possible(&ty); let arg = self.resolve_vars_if_possible(&arg);
let (name, name_sp, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None); let arg_data = self.extract_inference_diagnostics_data(arg, None);
let kind_str = match arg.unpack() {
GenericArgKind::Type(_) => "type",
GenericArgKind::Const(_) => "the value",
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
};
let mut local_visitor = FindHirNodeVisitor::new(&self, ty.into(), span); let mut local_visitor = FindHirNodeVisitor::new(&self, arg, span);
let ty_to_string = |ty: Ty<'tcx>| -> String { let ty_to_string = |ty: Ty<'tcx>| -> String {
let mut s = String::new(); let mut s = String::new();
let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS); let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
@ -305,7 +394,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
} }
let err_span = if let Some(pattern) = local_visitor.found_arg_pattern { let err_span = if let Some(pattern) = local_visitor.found_arg_pattern {
pattern.span pattern.span
} else if let Some(span) = name_sp { } else if let Some(span) = arg_data.span {
// `span` here lets us point at `sum` instead of the entire right hand side expr: // `span` here lets us point at `sum` instead of the entire right hand side expr:
// error[E0282]: type annotations needed // error[E0282]: type annotations needed
// --> file2.rs:3:15 // --> file2.rs:3:15
@ -352,7 +441,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
_ => String::new(), _ => String::new(),
}; };
// When `name` corresponds to a type argument, show the path of the full type we're // When `arg_data.name` corresponds to a type argument, show the path of the full type we're
// trying to infer. In the following example, `ty_msg` contains // trying to infer. In the following example, `ty_msg` contains
// " in `std::result::Result<i32, E>`": // " in `std::result::Result<i32, E>`":
// ``` // ```
@ -391,11 +480,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
&mut err, &mut err,
&decl.output, &decl.output,
self.tcx.hir().body(body_id), self.tcx.hir().body(body_id),
&descr, &arg_data.description,
&name, &arg_data.name,
&ret, &ret,
parent_name, arg_data.parent_name,
parent_descr, arg_data.parent_description,
); );
// We don't want to give the other suggestions when the problem is the // We don't want to give the other suggestions when the problem is the
// closure return type. // closure return type.
@ -409,15 +498,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// nudge them in the right direction. // nudge them in the right direction.
format!("a boxed closure type like `Box<dyn Fn({}) -> {}>`", args, ret) format!("a boxed closure type like `Box<dyn Fn({}) -> {}>`", args, ret)
} }
Some(ty) if is_named_and_not_impl_trait(ty) && name == "_" => { Some(ty) if is_named_and_not_impl_trait(ty) && arg_data.name == "_" => {
let ty = ty_to_string(ty); let ty = ty_to_string(ty);
format!("the explicit type `{}`, with the type parameters specified", ty) format!("the explicit type `{}`, with the type parameters specified", ty)
} }
Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != name => { Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != arg_data.name => {
let ty = ty_to_string(ty); let ty = ty_to_string(ty);
format!( format!(
"the explicit type `{}`, where the type parameter `{}` is specified", "the explicit type `{}`, where the type parameter `{}` is specified",
ty, name, ty, arg_data.name,
) )
} }
_ => "a type".to_string(), _ => "a type".to_string(),
@ -534,7 +623,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// | ^^^ cannot infer type for `S` // | ^^^ cannot infer type for `S`
// | // |
// = note: type must be known at this point // = note: type must be known at this point
let span = name_sp.unwrap_or(err_span); let span = arg_data.span.unwrap_or(err_span);
if !err if !err
.span .span
.span_labels() .span_labels()
@ -545,55 +634,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// Avoid multiple labels pointing at `span`. // Avoid multiple labels pointing at `span`.
err.span_label( err.span_label(
span, span,
InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr), InferCtxt::cannot_infer_msg(
kind_str,
&arg_data.name,
&arg_data.description,
arg_data.parent_name,
arg_data.parent_description,
),
); );
} }
err err
} }
// FIXME(const_generics): We should either try and merge this with `need_type_info_err`
// or improve the errors created here.
//
// Unlike for type inference variables, we don't yet store the origin of const inference variables.
// This is needed for to get a more relevant error span.
pub fn need_type_info_err_const(
&self,
body_id: Option<hir::BodyId>,
span: Span,
ct: &'tcx ty::Const<'tcx>,
error_code: TypeAnnotationNeeded,
) -> DiagnosticBuilder<'tcx> {
let mut local_visitor = FindHirNodeVisitor::new(&self, ct.into(), span);
if let Some(body_id) = body_id {
let expr = self.tcx.hir().expect_expr(body_id.hir_id);
local_visitor.visit_expr(expr);
}
let mut param_name = None;
let span = if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val {
let origin = self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
if let ConstVariableOriginKind::ConstParameterDefinition(param) = origin.kind {
param_name = Some(param);
}
origin.span
} else {
local_visitor.target_span
};
let error_code = error_code.into();
let mut err =
self.tcx.sess.struct_span_err_with_code(span, "type annotations needed", error_code);
if let Some(param_name) = param_name {
err.note(&format!("cannot infer the value of the const parameter `{}`", param_name));
} else {
err.note("unable to infer the value of a const parameter");
}
err
}
/// If the `FnSig` for the method call can be found and type arguments are identified as /// If the `FnSig` for the method call can be found and type arguments are identified as
/// needed, suggest annotating the call, otherwise point out the resulting type of the call. /// needed, suggest annotating the call, otherwise point out the resulting type of the call.
fn annotate_method_call( fn annotate_method_call(
@ -647,7 +700,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> DiagnosticBuilder<'tcx> { ) -> DiagnosticBuilder<'tcx> {
let ty = self.resolve_vars_if_possible(&ty); let ty = self.resolve_vars_if_possible(&ty);
let (name, _, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None); let data = self.extract_inference_diagnostics_data(ty.into(), None);
let mut err = struct_span_err!( let mut err = struct_span_err!(
self.tcx.sess, self.tcx.sess,
@ -656,18 +709,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"type inside {} must be known in this context", "type inside {} must be known in this context",
kind, kind,
); );
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr)); err.span_label(
span,
InferCtxt::cannot_infer_msg(
"type",
&data.name,
&data.description,
data.parent_name,
data.parent_description,
),
);
err err
} }
fn missing_type_msg( fn cannot_infer_msg(
kind_str: &str,
type_name: &str, type_name: &str,
descr: &str, descr: &str,
parent_name: Option<String>, parent_name: Option<String>,
parent_descr: Option<&str>, parent_descr: Option<&str>,
) -> Cow<'static, str> { ) -> String {
if type_name == "_" { if type_name == "_" {
"cannot infer type".into() format!("cannot infer {}", kind_str)
} else { } else {
let parent_desc = if let Some(parent_name) = parent_name { let parent_desc = if let Some(parent_name) = parent_name {
let parent_type_descr = if let Some(parent_descr) = parent_descr { let parent_type_descr = if let Some(parent_descr) = parent_descr {
@ -681,7 +744,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"".to_string() "".to_string()
}; };
format!("cannot infer type for {} `{}`{}", descr, type_name, parent_desc).into() // FIXME: We really shouldn't be dealing with strings here
// but instead use a sensible enum for cases like this.
let preposition = if "the value" == kind_str { "of" } else { "for" };
// For example: "cannot infer type for type parameter `T`"
format!(
"cannot infer {} {} {} `{}`{}",
kind_str, preposition, descr, type_name, parent_desc
)
.into()
} }
} }
} }

View file

@ -1163,7 +1163,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
} }
GenericParamDefKind::Const { .. } => { GenericParamDefKind::Const { .. } => {
let origin = ConstVariableOrigin { let origin = ConstVariableOrigin {
kind: ConstVariableOriginKind::ConstParameterDefinition(param.name), kind: ConstVariableOriginKind::ConstParameterDefinition(
param.name,
param.def_id,
),
span, span,
}; };
let const_var_id = let const_var_id =
@ -1275,7 +1278,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
} }
/// Gives temporary access to the region constraint data. /// Gives temporary access to the region constraint data.
#[allow(non_camel_case_types)] // bug with impl trait
pub fn with_region_constraints<R>( pub fn with_region_constraints<R>(
&self, &self,
op: impl FnOnce(&RegionConstraintData<'tcx>) -> R, op: impl FnOnce(&RegionConstraintData<'tcx>) -> R,

View file

@ -1,5 +1,3 @@
#![allow(non_snake_case)]
use crate::{LateContext, LateLintPass, LintContext}; use crate::{LateContext, LateLintPass, LintContext};
use rustc_ast as ast; use rustc_ast as ast;
use rustc_attr as attr; use rustc_attr as attr;

View file

@ -21,7 +21,6 @@ impl RustString {
/// Appending to a Rust string -- used by RawRustStringOstream. /// Appending to a Rust string -- used by RawRustStringOstream.
#[no_mangle] #[no_mangle]
#[allow(improper_ctypes_definitions)]
pub unsafe extern "C" fn LLVMRustStringWriteImpl( pub unsafe extern "C" fn LLVMRustStringWriteImpl(
sr: &RustString, sr: &RustString,
ptr: *const c_char, ptr: *const c_char,

View file

@ -9,7 +9,6 @@ use syn::{
ReturnType, Token, Type, ReturnType, Token, Type,
}; };
#[allow(non_camel_case_types)]
mod kw { mod kw {
syn::custom_keyword!(query); syn::custom_keyword!(query);
} }

View file

@ -4,7 +4,6 @@ use std::collections::HashSet;
use syn::parse::{Parse, ParseStream, Result}; use syn::parse::{Parse, ParseStream, Result};
use syn::{braced, parse_macro_input, Ident, LitStr, Token}; use syn::{braced, parse_macro_input, Ident, LitStr, Token};
#[allow(non_camel_case_types)]
mod kw { mod kw {
syn::custom_keyword!(Keywords); syn::custom_keyword!(Keywords);
syn::custom_keyword!(Symbols); syn::custom_keyword!(Symbols);

View file

@ -4,8 +4,9 @@ use rustc_data_structures::undo_log::UndoLogs;
use rustc_data_structures::unify::{ use rustc_data_structures::unify::{
self, EqUnifyValue, InPlace, NoError, UnificationTable, UnifyKey, UnifyValue, self, EqUnifyValue, InPlace, NoError, UnificationTable, UnifyKey, UnifyValue,
}; };
use rustc_span::def_id::DefId;
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP}; use rustc_span::Span;
use std::cmp; use std::cmp;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -124,8 +125,7 @@ pub struct ConstVariableOrigin {
pub enum ConstVariableOriginKind { pub enum ConstVariableOriginKind {
MiscVariable, MiscVariable,
ConstInference, ConstInference,
// FIXME(const_generics): Consider storing the `DefId` of the param here. ConstParameterDefinition(Symbol, DefId),
ConstParameterDefinition(Symbol),
SubstitutionPlaceholder, SubstitutionPlaceholder,
} }
@ -176,17 +176,17 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>); type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);
fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> { fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
let val = match (value1.val, value2.val) { let (val, span) = match (value1.val, value2.val) {
(ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => { (ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => {
bug!("equating two const variables, both of which have known values") bug!("equating two const variables, both of which have known values")
} }
// If one side is known, prefer that one. // If one side is known, prefer that one.
(ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => { (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => {
Ok(value1.val) (value1.val, value1.origin.span)
} }
(ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => { (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => {
Ok(value2.val) (value2.val, value2.origin.span)
} }
// If both sides are *unknown*, it hardly matters, does it? // If both sides are *unknown*, it hardly matters, does it?
@ -200,14 +200,14 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
// universe is the minimum of the two universes, because that is // universe is the minimum of the two universes, because that is
// the one which contains the fewest names in scope. // the one which contains the fewest names in scope.
let universe = cmp::min(universe1, universe2); let universe = cmp::min(universe1, universe2);
Ok(ConstVariableValue::Unknown { universe }) (ConstVariableValue::Unknown { universe }, value1.origin.span)
} }
}?; };
Ok(ConstVarValue { Ok(ConstVarValue {
origin: ConstVariableOrigin { origin: ConstVariableOrigin {
kind: ConstVariableOriginKind::ConstInference, kind: ConstVariableOriginKind::ConstInference,
span: DUMMY_SP, span: span,
}, },
val, val,
}) })

View file

@ -2675,7 +2675,7 @@ impl<'tcx> ClosureKind {
} }
} }
/// Returns `true` if this a type that impls this closure kind /// Returns `true` if a type that impls this closure kind
/// must also implement `other`. /// must also implement `other`.
pub fn extends(self, other: ty::ClosureKind) -> bool { pub fn extends(self, other: ty::ClosureKind) -> bool {
match (self, other) { match (self, other) {

View file

@ -1,5 +1,3 @@
#![allow(non_camel_case_types)]
use rustc_data_structures::sync::Lock; use rustc_data_structures::sync::Lock;
use std::fmt::Debug; use std::fmt::Debug;

View file

@ -396,7 +396,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
) -> Option<RegionNameHighlight> { ) -> Option<RegionNameHighlight> {
let mut highlight = RegionHighlightMode::default(); let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(needle_fr, counter); highlight.highlighting_region_vid(needle_fr, counter);
let type_name = self.infcx.extract_type_name(&ty, Some(highlight)).0; let type_name =
self.infcx.extract_inference_diagnostics_data(ty.into(), Some(highlight)).name;
debug!( debug!(
"highlight_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}", "highlight_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
@ -404,7 +405,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
); );
if type_name.find(&format!("'{}", counter)).is_some() { if type_name.find(&format!("'{}", counter)).is_some() {
// Only add a label if we can confirm that a region was labelled. // Only add a label if we can confirm that a region was labelled.
Some(RegionNameHighlight::CannotMatchHirTy(span, type_name)) Some(RegionNameHighlight::CannotMatchHirTy(span, type_name))
} else { } else {
None None
@ -646,7 +646,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let mut highlight = RegionHighlightMode::default(); let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap()); highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
let type_name = self.infcx.extract_type_name(&return_ty, Some(highlight)).0; let type_name =
self.infcx.extract_inference_diagnostics_data(return_ty.into(), Some(highlight)).name;
let mir_hir_id = tcx.hir().local_def_id_to_hir_id(self.mir_def_id); let mir_hir_id = tcx.hir().local_def_id_to_hir_id(self.mir_def_id);
@ -698,7 +699,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let mut highlight = RegionHighlightMode::default(); let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap()); highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
let type_name = self.infcx.extract_type_name(&yield_ty, Some(highlight)).0; let type_name =
self.infcx.extract_inference_diagnostics_data(yield_ty.into(), Some(highlight)).name;
let mir_hir_id = tcx.hir().local_def_id_to_hir_id(self.mir_def_id); let mir_hir_id = tcx.hir().local_def_id_to_hir_id(self.mir_def_id);

View file

@ -33,7 +33,6 @@ pub(super) struct Prefixes<'cx, 'tcx> {
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[allow(dead_code)]
pub(super) enum PrefixSet { pub(super) enum PrefixSet {
/// Doesn't stop until it returns the base case (a Local or /// Doesn't stop until it returns the base case (a Local or
/// Static prefix). /// Static prefix).

View file

@ -144,7 +144,6 @@ impl<'tcx> fmt::Display for MovePath<'tcx> {
} }
} }
#[allow(unused)]
struct MovePathLinearIter<'a, 'tcx, F> { struct MovePathLinearIter<'a, 'tcx, F> {
next: Option<(MovePathIndex, &'a MovePath<'tcx>)>, next: Option<(MovePathIndex, &'a MovePath<'tcx>)>,
fetch_next: F, fetch_next: F,

View file

@ -112,6 +112,30 @@ impl NonConstOp for Abort {
} }
} }
#[derive(Debug)]
pub struct FloatingPointOp;
impl NonConstOp for FloatingPointOp {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
if ccx.const_kind() == hir::ConstContext::ConstFn {
Status::Unstable(sym::const_fn_floating_point_arithmetic)
} else {
Status::Allowed
}
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_floating_point_arithmetic,
span,
&format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
)
.emit();
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct NonPrimitiveOp; pub struct NonPrimitiveOp;
impl NonConstOp for NonPrimitiveOp { impl NonConstOp for NonPrimitiveOp {

View file

@ -540,8 +540,12 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
Rvalue::UnaryOp(_, ref operand) => { Rvalue::UnaryOp(_, ref operand) => {
let ty = operand.ty(self.body, self.tcx); let ty = operand.ty(self.body, self.tcx);
if !(ty.is_integral() || ty.is_bool()) { if is_int_bool_or_char(ty) {
self.check_op(ops::NonPrimitiveOp) // Int, bool, and char operations are fine.
} else if ty.is_floating_point() {
self.check_op(ops::FloatingPointOp);
} else {
span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
} }
} }
@ -550,7 +554,9 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
let lhs_ty = lhs.ty(self.body, self.tcx); let lhs_ty = lhs.ty(self.body, self.tcx);
let rhs_ty = rhs.ty(self.body, self.tcx); let rhs_ty = rhs.ty(self.body, self.tcx);
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs_ty.kind() { if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
// Int, bool, and char operations are fine.
} else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
assert_eq!(lhs_ty, rhs_ty); assert_eq!(lhs_ty, rhs_ty);
assert!( assert!(
op == BinOp::Eq op == BinOp::Eq
@ -563,12 +569,15 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
); );
self.check_op(ops::RawPtrComparison); self.check_op(ops::RawPtrComparison);
} } else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() {
self.check_op(ops::FloatingPointOp);
if !(lhs_ty.is_integral() || lhs_ty.is_bool() || lhs_ty.is_char()) } else {
|| !(rhs_ty.is_integral() || rhs_ty.is_bool() || rhs_ty.is_char()) span_bug!(
{ self.span,
self.check_op(ops::NonPrimitiveOp) "non-primitive type in `Rvalue::BinaryOp`: {:?} ⚬ {:?}",
lhs_ty,
rhs_ty
);
} }
} }
} }
@ -867,3 +876,7 @@ fn place_as_reborrow(
} }
}) })
} }
fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
ty.is_bool() || ty.is_integral() || ty.is_char()
}

View file

@ -1,5 +1,3 @@
#![allow(non_camel_case_types)]
pub use self::FileMatch::*; pub use self::FileMatch::*;
use std::borrow::Cow; use std::borrow::Cow;

View file

@ -352,6 +352,7 @@ symbols! {
const_evaluatable_checked, const_evaluatable_checked,
const_extern_fn, const_extern_fn,
const_fn, const_fn,
const_fn_floating_point_arithmetic,
const_fn_transmute, const_fn_transmute,
const_fn_union, const_fn_union,
const_generics, const_generics,

View file

@ -32,6 +32,7 @@ pub enum AutoTraitResult<A> {
NegativeImpl, NegativeImpl,
} }
#[allow(dead_code)]
impl<A> AutoTraitResult<A> { impl<A> AutoTraitResult<A> {
fn is_auto(&self) -> bool { fn is_auto(&self) -> bool {
match *self { match *self {

View file

@ -20,7 +20,6 @@ use rustc_hir::Node;
use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, fast_reject, AdtKind, SubtypePredicate, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, self, fast_reject, AdtKind, SubtypePredicate, ToPolyTraitRef, ToPredicate, Ty, TyCtxt,
TypeFoldable, WithConstness, TypeFoldable, WithConstness,
@ -1513,10 +1512,21 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
// check upstream for type errors and don't add the obligations to // check upstream for type errors and don't add the obligations to
// begin with in those cases. // begin with in those cases.
if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit(); self.emit_inference_failure_err(
body_id,
span,
self_ty.into(),
ErrorCode::E0282,
)
.emit();
return; return;
} }
let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283); let mut err = self.emit_inference_failure_err(
body_id,
span,
self_ty.into(),
ErrorCode::E0283,
);
err.note(&format!("cannot satisfy `{}`", predicate)); err.note(&format!("cannot satisfy `{}`", predicate));
if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code { if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
@ -1580,17 +1590,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
return; return;
} }
match arg.unpack() { self.emit_inference_failure_err(body_id, span, arg, ErrorCode::E0282)
GenericArgKind::Lifetime(lt) => {
span_bug!(span, "unexpected well formed predicate: {:?}", lt)
}
GenericArgKind::Type(ty) => {
self.need_type_info_err(body_id, span, ty, ErrorCode::E0282)
}
GenericArgKind::Const(ct) => {
self.need_type_info_err_const(body_id, span, ct, ErrorCode::E0282)
}
}
} }
ty::PredicateAtom::Subtype(data) => { ty::PredicateAtom::Subtype(data) => {
@ -1601,7 +1601,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
let SubtypePredicate { a_is_expected: _, a, b } = data; let SubtypePredicate { a_is_expected: _, a, b } = data;
// both must be type variables, or the other would've been instantiated // both must be type variables, or the other would've been instantiated
assert!(a.is_ty_var() && b.is_ty_var()); assert!(a.is_ty_var() && b.is_ty_var());
self.need_type_info_err(body_id, span, a, ErrorCode::E0282) self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282)
} }
ty::PredicateAtom::Projection(data) => { ty::PredicateAtom::Projection(data) => {
let trait_ref = ty::Binder::bind(data).to_poly_trait_ref(self.tcx); let trait_ref = ty::Binder::bind(data).to_poly_trait_ref(self.tcx);
@ -1612,7 +1612,12 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
} }
if self_ty.needs_infer() && ty.needs_infer() { if self_ty.needs_infer() && ty.needs_infer() {
// We do this for the `foo.collect()?` case to produce a suggestion. // We do this for the `foo.collect()?` case to produce a suggestion.
let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284); let mut err = self.emit_inference_failure_err(
body_id,
span,
self_ty.into(),
ErrorCode::E0284,
);
err.note(&format!("cannot satisfy `{}`", predicate)); err.note(&format!("cannot satisfy `{}`", predicate));
err err
} else { } else {

View file

@ -2,7 +2,6 @@
//! //!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html
#[allow(dead_code)]
pub mod auto_trait; pub mod auto_trait;
mod chalk_fulfill; mod chalk_fulfill;
pub mod codegen; pub mod codegen;

View file

@ -2148,7 +2148,6 @@ trait TraitObligationExt<'tcx> {
} }
impl<'tcx> TraitObligationExt<'tcx> for TraitObligation<'tcx> { impl<'tcx> TraitObligationExt<'tcx> for TraitObligation<'tcx> {
#[allow(unused_comparisons)]
fn derived_cause( fn derived_cause(
&self, &self,
variant: fn(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>, variant: fn(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>,

View file

@ -2991,7 +2991,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty ty
} else { } else {
if !self.is_tainted_by_errors() { if !self.is_tainted_by_errors() {
self.need_type_info_err((**self).body_id, sp, ty, E0282) self.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282)
.note("type must be known at this point") .note("type must be known at this point")
.emit(); .emit();
} }

View file

@ -653,7 +653,12 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
fn report_type_error(&self, t: Ty<'tcx>) { fn report_type_error(&self, t: Ty<'tcx>) {
if !self.tcx.sess.has_errors() { if !self.tcx.sess.has_errors() {
self.infcx self.infcx
.need_type_info_err(Some(self.body.id()), self.span.to_span(self.tcx), t, E0282) .emit_inference_failure_err(
Some(self.body.id()),
self.span.to_span(self.tcx),
t.into(),
E0282,
)
.emit(); .emit();
} }
} }
@ -661,10 +666,10 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
fn report_const_error(&self, c: &'tcx ty::Const<'tcx>) { fn report_const_error(&self, c: &'tcx ty::Const<'tcx>) {
if !self.tcx.sess.has_errors() { if !self.tcx.sess.has_errors() {
self.infcx self.infcx
.need_type_info_err_const( .emit_inference_failure_err(
Some(self.body.id()), Some(self.body.id()),
self.span.to_span(self.tcx), self.span.to_span(self.tcx),
c, c.into(),
E0282, E0282,
) )
.emit(); .emit();

View file

@ -56,7 +56,6 @@ This API is completely unstable and subject to change.
*/ */
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![allow(non_camel_case_types)]
#![feature(bool_to_option)] #![feature(bool_to_option)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]

View file

@ -82,6 +82,7 @@
#![feature(const_pin)] #![feature(const_pin)]
#![feature(const_fn_union)] #![feature(const_fn_union)]
#![feature(const_fn)] #![feature(const_fn)]
#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
#![feature(const_generics)] #![feature(const_generics)]
#![feature(const_option)] #![feature(const_option)]
#![feature(const_precise_live_drops)] #![feature(const_precise_live_drops)]

View file

@ -70,10 +70,23 @@
//! } //! }
//! ``` //! ```
//! //!
//! This usage of [`Option`] to create safe nullable pointers is so //! # Representation
//! common that Rust does special optimizations to make the //!
//! representation of [`Option`]`<`[`Box<T>`]`>` a single pointer. Optional pointers //! Rust guarantees to optimize the following types `T` such that
//! in Rust are stored as efficiently as any other pointer type. //! [`Option<T>`] has the same size as `T`:
//!
//! * [`Box<U>`]
//! * `&U`
//! * `&mut U`
//! * `fn`, `extern "C" fn`
//! * [`num::NonZero*`]
//! * [`ptr::NonNull<U>`]
//! * `#[repr(transparent)]` struct around one of the types in this list.
//!
//! It is further guaranteed that, for the cases above, one can
//! [`mem::transmute`] from all valid values of `T` to `Option<T>` and
//! from `Some::<T>(_)` to `T` (but transmuting `None::<T>` to `T`
//! is undefined behaviour).
//! //!
//! # Examples //! # Examples
//! //!

View file

@ -319,6 +319,13 @@ pub(super) trait SplitIter: DoubleEndedIterator {
/// ///
/// This struct is created by the [`split`] method on [slices]. /// This struct is created by the [`split`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let slice = [10, 40, 33, 20];
/// let mut iter = slice.split(|num| num % 3 == 0);
/// ```
///
/// [`split`]: ../../std/primitive.slice.html#method.split /// [`split`]: ../../std/primitive.slice.html#method.split
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -434,6 +441,15 @@ impl<T, P> FusedIterator for Split<'_, T, P> where P: FnMut(&T) -> bool {}
/// ///
/// This struct is created by the [`split_inclusive`] method on [slices]. /// This struct is created by the [`split_inclusive`] method on [slices].
/// ///
/// # Example
///
/// ```
/// #![feature(split_inclusive)]
///
/// let slice = [10, 40, 33, 20];
/// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
/// ```
///
/// [`split_inclusive`]: ../../std/primitive.slice.html#method.split_inclusive /// [`split_inclusive`]: ../../std/primitive.slice.html#method.split_inclusive
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[unstable(feature = "split_inclusive", issue = "72360")] #[unstable(feature = "split_inclusive", issue = "72360")]
@ -539,6 +555,13 @@ impl<T, P> FusedIterator for SplitInclusive<'_, T, P> where P: FnMut(&T) -> bool
/// ///
/// This struct is created by the [`split_mut`] method on [slices]. /// This struct is created by the [`split_mut`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let mut v = [10, 40, 30, 20, 60, 50];
/// let iter = v.split_mut(|num| *num % 3 == 0);
/// ```
///
/// [`split_mut`]: ../../std/primitive.slice.html#method.split_mut /// [`split_mut`]: ../../std/primitive.slice.html#method.split_mut
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -661,6 +684,15 @@ impl<T, P> FusedIterator for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
/// ///
/// This struct is created by the [`split_inclusive_mut`] method on [slices]. /// This struct is created by the [`split_inclusive_mut`] method on [slices].
/// ///
/// # Example
///
/// ```
/// #![feature(split_inclusive)]
///
/// let mut v = [10, 40, 30, 20, 60, 50];
/// let iter = v.split_inclusive_mut(|num| *num % 3 == 0);
/// ```
///
/// [`split_inclusive_mut`]: ../../std/primitive.slice.html#method.split_inclusive_mut /// [`split_inclusive_mut`]: ../../std/primitive.slice.html#method.split_inclusive_mut
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[unstable(feature = "split_inclusive", issue = "72360")] #[unstable(feature = "split_inclusive", issue = "72360")]
@ -775,6 +807,13 @@ impl<T, P> FusedIterator for SplitInclusiveMut<'_, T, P> where P: FnMut(&T) -> b
/// ///
/// This struct is created by the [`rsplit`] method on [slices]. /// This struct is created by the [`rsplit`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let slice = [11, 22, 33, 0, 44, 55];
/// let iter = slice.rsplit(|num| *num == 0);
/// ```
///
/// [`rsplit`]: ../../std/primitive.slice.html#method.rsplit /// [`rsplit`]: ../../std/primitive.slice.html#method.rsplit
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[stable(feature = "slice_rsplit", since = "1.27.0")] #[stable(feature = "slice_rsplit", since = "1.27.0")]
@ -854,6 +893,13 @@ impl<T, P> FusedIterator for RSplit<'_, T, P> where P: FnMut(&T) -> bool {}
/// ///
/// This struct is created by the [`rsplit_mut`] method on [slices]. /// This struct is created by the [`rsplit_mut`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let mut slice = [11, 22, 33, 0, 44, 55];
/// let iter = slice.rsplit_mut(|num| *num == 0);
/// ```
///
/// [`rsplit_mut`]: ../../std/primitive.slice.html#method.rsplit_mut /// [`rsplit_mut`]: ../../std/primitive.slice.html#method.rsplit_mut
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[stable(feature = "slice_rsplit", since = "1.27.0")] #[stable(feature = "slice_rsplit", since = "1.27.0")]
@ -966,6 +1012,13 @@ impl<T, I: SplitIter<Item = T>> Iterator for GenericSplitN<I> {
/// ///
/// This struct is created by the [`splitn`] method on [slices]. /// This struct is created by the [`splitn`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let slice = [10, 40, 30, 20, 60, 50];
/// let iter = slice.splitn(2, |num| *num % 3 == 0);
/// ```
///
/// [`splitn`]: ../../std/primitive.slice.html#method.splitn /// [`splitn`]: ../../std/primitive.slice.html#method.splitn
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -999,6 +1052,13 @@ where
/// ///
/// This struct is created by the [`rsplitn`] method on [slices]. /// This struct is created by the [`rsplitn`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let slice = [10, 40, 30, 20, 60, 50];
/// let iter = slice.rsplitn(2, |num| *num % 3 == 0);
/// ```
///
/// [`rsplitn`]: ../../std/primitive.slice.html#method.rsplitn /// [`rsplitn`]: ../../std/primitive.slice.html#method.rsplitn
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -1031,6 +1091,13 @@ where
/// ///
/// This struct is created by the [`splitn_mut`] method on [slices]. /// This struct is created by the [`splitn_mut`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let mut slice = [10, 40, 30, 20, 60, 50];
/// let iter = slice.splitn_mut(2, |num| *num % 3 == 0);
/// ```
///
/// [`splitn_mut`]: ../../std/primitive.slice.html#method.splitn_mut /// [`splitn_mut`]: ../../std/primitive.slice.html#method.splitn_mut
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -1064,6 +1131,13 @@ where
/// ///
/// This struct is created by the [`rsplitn_mut`] method on [slices]. /// This struct is created by the [`rsplitn_mut`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let mut slice = [10, 40, 30, 20, 60, 50];
/// let iter = slice.rsplitn_mut(2, |num| *num % 3 == 0);
/// ```
///
/// [`rsplitn_mut`]: ../../std/primitive.slice.html#method.rsplitn_mut /// [`rsplitn_mut`]: ../../std/primitive.slice.html#method.rsplitn_mut
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -1100,6 +1174,13 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] }
/// ///
/// This struct is created by the [`windows`] method on [slices]. /// This struct is created by the [`windows`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let slice = ['r', 'u', 's', 't'];
/// let iter = slice.windows(2);
/// ```
///
/// [`windows`]: ../../std/primitive.slice.html#method.windows /// [`windows`]: ../../std/primitive.slice.html#method.windows
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[derive(Debug)] #[derive(Debug)]
@ -1239,6 +1320,13 @@ unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {
/// ///
/// This struct is created by the [`chunks`] method on [slices]. /// This struct is created by the [`chunks`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.chunks(2);
/// ```
///
/// [`chunks`]: ../../std/primitive.slice.html#method.chunks /// [`chunks`]: ../../std/primitive.slice.html#method.chunks
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[derive(Debug)] #[derive(Debug)]
@ -1400,6 +1488,13 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
/// ///
/// This struct is created by the [`chunks_mut`] method on [slices]. /// This struct is created by the [`chunks_mut`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.chunks_mut(2);
/// ```
///
/// [`chunks_mut`]: ../../std/primitive.slice.html#method.chunks_mut /// [`chunks_mut`]: ../../std/primitive.slice.html#method.chunks_mut
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[derive(Debug)] #[derive(Debug)]
@ -1559,6 +1654,13 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
/// ///
/// This struct is created by the [`chunks_exact`] method on [slices]. /// This struct is created by the [`chunks_exact`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.chunks_exact(2);
/// ```
///
/// [`chunks_exact`]: ../../std/primitive.slice.html#method.chunks_exact /// [`chunks_exact`]: ../../std/primitive.slice.html#method.chunks_exact
/// [`remainder`]: ChunksExact::remainder /// [`remainder`]: ChunksExact::remainder
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
@ -1708,6 +1810,13 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
/// ///
/// This struct is created by the [`chunks_exact_mut`] method on [slices]. /// This struct is created by the [`chunks_exact_mut`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.chunks_exact_mut(2);
/// ```
///
/// [`chunks_exact_mut`]: ../../std/primitive.slice.html#method.chunks_exact_mut /// [`chunks_exact_mut`]: ../../std/primitive.slice.html#method.chunks_exact_mut
/// [`into_remainder`]: ChunksExactMut::into_remainder /// [`into_remainder`]: ChunksExactMut::into_remainder
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
@ -1850,6 +1959,15 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
/// ///
/// This struct is created by the [`array_windows`] method on [slices]. /// This struct is created by the [`array_windows`] method on [slices].
/// ///
/// # Example
///
/// ```
/// #![feature(array_windows)]
///
/// let slice = [0, 1, 2, 3];
/// let iter = slice.array_windows::<2>();
/// ```
///
/// [`array_windows`]: ../../std/primitive.slice.html#method.array_windows /// [`array_windows`]: ../../std/primitive.slice.html#method.array_windows
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -1962,6 +2080,15 @@ impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
/// ///
/// This struct is created by the [`array_chunks`] method on [slices]. /// This struct is created by the [`array_chunks`] method on [slices].
/// ///
/// # Example
///
/// ```
/// #![feature(array_chunks)]
///
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.array_chunks::<2>();
/// ```
///
/// [`array_chunks`]: ../../std/primitive.slice.html#method.array_chunks /// [`array_chunks`]: ../../std/primitive.slice.html#method.array_chunks
/// [`remainder`]: ArrayChunks::remainder /// [`remainder`]: ArrayChunks::remainder
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
@ -2080,6 +2207,15 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N>
/// ///
/// This struct is created by the [`array_chunks_mut`] method on [slices]. /// This struct is created by the [`array_chunks_mut`] method on [slices].
/// ///
/// # Example
///
/// ```
/// #![feature(array_chunks)]
///
/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.array_chunks_mut::<2>();
/// ```
///
/// [`array_chunks_mut`]: ../../std/primitive.slice.html#method.array_chunks_mut /// [`array_chunks_mut`]: ../../std/primitive.slice.html#method.array_chunks_mut
/// [`into_remainder`]: ../../std/slice/struct.ArrayChunksMut.html#method.into_remainder /// [`into_remainder`]: ../../std/slice/struct.ArrayChunksMut.html#method.into_remainder
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
@ -2190,6 +2326,13 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunksMut<'a, T,
/// ///
/// This struct is created by the [`rchunks`] method on [slices]. /// This struct is created by the [`rchunks`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.rchunks(2);
/// ```
///
/// [`rchunks`]: ../../std/primitive.slice.html#method.rchunks /// [`rchunks`]: ../../std/primitive.slice.html#method.rchunks
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[derive(Debug)] #[derive(Debug)]
@ -2347,6 +2490,13 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
/// ///
/// This struct is created by the [`rchunks_mut`] method on [slices]. /// This struct is created by the [`rchunks_mut`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.rchunks_mut(2);
/// ```
///
/// [`rchunks_mut`]: ../../std/primitive.slice.html#method.rchunks_mut /// [`rchunks_mut`]: ../../std/primitive.slice.html#method.rchunks_mut
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
#[derive(Debug)] #[derive(Debug)]
@ -2504,6 +2654,13 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
/// ///
/// This struct is created by the [`rchunks_exact`] method on [slices]. /// This struct is created by the [`rchunks_exact`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.rchunks_exact(2);
/// ```
///
/// [`rchunks_exact`]: ../../std/primitive.slice.html#method.rchunks_exact /// [`rchunks_exact`]: ../../std/primitive.slice.html#method.rchunks_exact
/// [`remainder`]: ChunksExact::remainder /// [`remainder`]: ChunksExact::remainder
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html
@ -2657,6 +2814,13 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
/// ///
/// This struct is created by the [`rchunks_exact_mut`] method on [slices]. /// This struct is created by the [`rchunks_exact_mut`] method on [slices].
/// ///
/// # Example
///
/// ```
/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.rchunks_exact_mut(2);
/// ```
///
/// [`rchunks_exact_mut`]: ../../std/primitive.slice.html#method.rchunks_exact_mut /// [`rchunks_exact_mut`]: ../../std/primitive.slice.html#method.rchunks_exact_mut
/// [`into_remainder`]: ChunksExactMut::into_remainder /// [`into_remainder`]: ChunksExactMut::into_remainder
/// [slices]: ../../std/primitive.slice.html /// [slices]: ../../std/primitive.slice.html

View file

@ -236,6 +236,7 @@
#![feature(clamp)] #![feature(clamp)]
#![feature(concat_idents)] #![feature(concat_idents)]
#![feature(const_cstr_unchecked)] #![feature(const_cstr_unchecked)]
#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
#![feature(const_fn_transmute)] #![feature(const_fn_transmute)]
#![feature(const_fn)] #![feature(const_fn)]
#![feature(const_ip)] #![feature(const_ip)]

View file

@ -384,6 +384,7 @@ mod prim_char {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
mod prim_unit {} mod prim_unit {}
#[doc(alias = "ptr")]
#[doc(primitive = "pointer")] #[doc(primitive = "pointer")]
// //
/// Raw, unsafe pointers, `*const T`, and `*mut T`. /// Raw, unsafe pointers, `*const T`, and `*mut T`.

View file

@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Non-breaking changes since the last major version] ## [Non-breaking changes since the last major version]
- Add `x.py setup` [#76631](https://github.com/rust-lang/rust/pull/76631)
- Add a changelog for x.py [#76626](https://github.com/rust-lang/rust/pull/76626) - Add a changelog for x.py [#76626](https://github.com/rust-lang/rust/pull/76626)
- Optionally, download LLVM from CI on Linux and NixOS - Optionally, download LLVM from CI on Linux and NixOS
+ [#76439](https://github.com/rust-lang/rust/pull/76349) + [#76439](https://github.com/rust-lang/rust/pull/76349)

View file

@ -7,21 +7,34 @@
use std::env; use std::env;
use bootstrap::{Build, Config}; use bootstrap::{Build, Config, Subcommand};
fn main() { fn main() {
let args = env::args().skip(1).collect::<Vec<_>>(); let args = env::args().skip(1).collect::<Vec<_>>();
let config = Config::parse(&args); let config = Config::parse(&args);
let changelog_suggestion = check_version(&config); let changelog_suggestion = check_version(&config);
if let Some(suggestion) = &changelog_suggestion {
// NOTE: Since `./configure` generates a `config.toml`, distro maintainers will see the
// changelog warning, not the `x.py setup` message.
let suggest_setup = !config.config.exists() && !matches!(config.cmd, Subcommand::Setup { .. });
if suggest_setup {
println!("warning: you have not made a `config.toml`");
println!("help: consider running `x.py setup` or copying `config.toml.example`");
} else if let Some(suggestion) = &changelog_suggestion {
println!("{}", suggestion); println!("{}", suggestion);
} }
Build::new(config).build(); Build::new(config).build();
if let Some(suggestion) = changelog_suggestion { if suggest_setup {
println!("warning: you have not made a `config.toml`");
println!("help: consider running `x.py setup` or copying `config.toml.example`");
} else if let Some(suggestion) = &changelog_suggestion {
println!("{}", suggestion); println!("{}", suggestion);
}
if suggest_setup || changelog_suggestion.is_some() {
println!("note: this message was printed twice to make it more likely to be seen"); println!("note: this message was printed twice to make it more likely to be seen");
} }
} }

View file

@ -549,7 +549,9 @@ impl<'a> Builder<'a> {
Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]), Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]),
Subcommand::Install { ref paths } => (Kind::Install, &paths[..]), Subcommand::Install { ref paths } => (Kind::Install, &paths[..]),
Subcommand::Run { ref paths } => (Kind::Run, &paths[..]), Subcommand::Run { ref paths } => (Kind::Run, &paths[..]),
Subcommand::Format { .. } | Subcommand::Clean { .. } => panic!(), Subcommand::Format { .. } | Subcommand::Clean { .. } | Subcommand::Setup { .. } => {
panic!()
}
}; };
Self::new_internal(build, kind, paths.to_owned()) Self::new_internal(build, kind, paths.to_owned())

View file

@ -73,6 +73,8 @@ pub struct Config {
pub keep_stage: Vec<u32>, pub keep_stage: Vec<u32>,
pub keep_stage_std: Vec<u32>, pub keep_stage_std: Vec<u32>,
pub src: PathBuf, pub src: PathBuf,
// defaults to `config.toml`
pub config: PathBuf,
pub jobs: Option<u32>, pub jobs: Option<u32>,
pub cmd: Subcommand, pub cmd: Subcommand,
pub incremental: bool, pub incremental: bool,
@ -513,6 +515,7 @@ impl Config {
config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")]; config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")];
config.deny_warnings = true; config.deny_warnings = true;
config.missing_tools = false; config.missing_tools = false;
config.config = PathBuf::from("config.toml");
// set by bootstrap.py // set by bootstrap.py
config.build = TargetSelection::from_user(&env!("BUILD_TRIPLE")); config.build = TargetSelection::from_user(&env!("BUILD_TRIPLE"));
@ -558,7 +561,7 @@ impl Config {
let get_toml = |file: PathBuf| { let get_toml = |file: PathBuf| {
use std::process; use std::process;
let contents = t!(fs::read_to_string(&file), "configuration file did not exist"); let contents = t!(fs::read_to_string(&file), "`include` config not found");
match toml::from_str(&contents) { match toml::from_str(&contents) {
Ok(table) => table, Ok(table) => table,
Err(err) => { Err(err) => {
@ -644,6 +647,7 @@ impl Config {
| Subcommand::Clippy { .. } | Subcommand::Clippy { .. }
| Subcommand::Fix { .. } | Subcommand::Fix { .. }
| Subcommand::Run { .. } | Subcommand::Run { .. }
| Subcommand::Setup { .. }
| Subcommand::Format { .. } => flags.stage.unwrap_or(0), | Subcommand::Format { .. } => flags.stage.unwrap_or(0),
}; };
@ -668,6 +672,7 @@ impl Config {
| Subcommand::Clippy { .. } | Subcommand::Clippy { .. }
| Subcommand::Fix { .. } | Subcommand::Fix { .. }
| Subcommand::Run { .. } | Subcommand::Run { .. }
| Subcommand::Setup { .. }
| Subcommand::Format { .. } => {} | Subcommand::Format { .. } => {}
} }
} }

View file

@ -7,6 +7,7 @@ use std::env;
use std::path::PathBuf; use std::path::PathBuf;
use std::process; use std::process;
use build_helper::t;
use getopts::Options; use getopts::Options;
use crate::builder::Builder; use crate::builder::Builder;
@ -89,6 +90,9 @@ pub enum Subcommand {
Run { Run {
paths: Vec<PathBuf>, paths: Vec<PathBuf>,
}, },
Setup {
path: String,
},
} }
impl Default for Subcommand { impl Default for Subcommand {
@ -199,6 +203,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
|| (s == "install") || (s == "install")
|| (s == "run") || (s == "run")
|| (s == "r") || (s == "r")
|| (s == "setup")
}); });
let subcommand = match subcommand { let subcommand = match subcommand {
Some(s) => s, Some(s) => s,
@ -453,10 +458,21 @@ Arguments:
At least a tool needs to be called.", At least a tool needs to be called.",
); );
} }
"setup" => {
subcommand_help.push_str(
"\n
Arguments:
This subcommand accepts a 'profile' to use for builds. For example:
./x.py setup library
The profile is optional and you will be prompted interactively if it is not given.",
);
}
_ => {} _ => {}
}; };
// Get any optional paths which occur after the subcommand // Get any optional paths which occur after the subcommand
let paths = matches.free[1..].iter().map(|p| p.into()).collect::<Vec<PathBuf>>(); let mut paths = matches.free[1..].iter().map(|p| p.into()).collect::<Vec<PathBuf>>();
let cfg_file = env::var_os("BOOTSTRAP_CONFIG").map(PathBuf::from); let cfg_file = env::var_os("BOOTSTRAP_CONFIG").map(PathBuf::from);
let verbose = matches.opt_present("verbose"); let verbose = matches.opt_present("verbose");
@ -508,6 +524,20 @@ Arguments:
} }
Subcommand::Run { paths } Subcommand::Run { paths }
} }
"setup" => {
let path = if paths.len() > 1 {
println!("\nat most one profile can be passed to setup\n");
usage(1, &opts, verbose, &subcommand_help)
} else if let Some(path) = paths.pop() {
t!(path.into_os_string().into_string().map_err(|path| format!(
"{} is not a valid UTF8 string",
path.to_string_lossy()
)))
} else {
t!(crate::setup::interactive_path())
};
Subcommand::Setup { path }
}
_ => { _ => {
usage(1, &opts, verbose, &subcommand_help); usage(1, &opts, verbose, &subcommand_help);
} }

View file

@ -141,6 +141,7 @@ mod metadata;
mod native; mod native;
mod run; mod run;
mod sanity; mod sanity;
mod setup;
mod test; mod test;
mod tool; mod tool;
mod toolstate; mod toolstate;
@ -165,7 +166,7 @@ mod job {
use crate::cache::{Interned, INTERNER}; use crate::cache::{Interned, INTERNER};
pub use crate::config::Config; pub use crate::config::Config;
use crate::flags::Subcommand; pub use crate::flags::Subcommand;
const LLVM_TOOLS: &[&str] = &[ const LLVM_TOOLS: &[&str] = &[
"llvm-nm", // used to inspect binaries; it shows symbol names, their sizes and visibility "llvm-nm", // used to inspect binaries; it shows symbol names, their sizes and visibility
@ -470,6 +471,10 @@ impl Build {
return clean::clean(self, all); return clean::clean(self, all);
} }
if let Subcommand::Setup { path: include_name } = &self.config.cmd {
return setup::setup(&self.config.src, include_name);
}
{ {
let builder = builder::Builder::new(&self); let builder = builder::Builder::new(&self);
if let Some(path) = builder.paths.get(0) { if let Some(path) = builder.paths.get(0) {

View file

@ -10,7 +10,7 @@ impl Step for ExpandYamlAnchors {
/// Runs the `expand-yaml_anchors` tool. /// Runs the `expand-yaml_anchors` tool.
/// ///
/// This tool in `src/tools` read the CI configuration files written in YAML and expands the /// This tool in `src/tools` reads the CI configuration files written in YAML and expands the
/// anchors in them, since GitHub Actions doesn't support them. /// anchors in them, since GitHub Actions doesn't support them.
fn run(self, builder: &Builder<'_>) { fn run(self, builder: &Builder<'_>) {
builder.info("Expanding YAML anchors in the GitHub Actions configuration"); builder.info("Expanding YAML anchors in the GitHub Actions configuration");

88
src/bootstrap/setup.rs Normal file
View file

@ -0,0 +1,88 @@
use crate::t;
use std::path::{Path, PathBuf};
use std::{
env, fs,
io::{self, Write},
};
pub fn setup(src_path: &Path, include_name: &str) {
let cfg_file = env::var_os("BOOTSTRAP_CONFIG").map(PathBuf::from);
if cfg_file.as_ref().map_or(false, |f| f.exists()) {
let file = cfg_file.unwrap();
println!(
"error: you asked `x.py` to setup a new config file, but one already exists at `{}`",
file.display()
);
println!(
"help: try adding `profile = \"{}\"` at the top of {}",
include_name,
file.display()
);
println!(
"note: this will use the configuration in {}/src/bootstrap/defaults/config.toml.{}",
src_path.display(),
include_name
);
std::process::exit(1);
}
let path = cfg_file.unwrap_or_else(|| src_path.join("config.toml"));
let settings = format!(
"# Includes one of the default files in src/bootstrap/defaults\n\
profile = \"{}\"\n",
include_name
);
t!(fs::write(path, settings));
let include_path =
format!("{}/src/bootstrap/defaults/config.toml.{}", src_path.display(), include_name);
println!("`x.py` will now use the configuration at {}", include_path);
let suggestions = match include_name {
"codegen" | "compiler" => &["check", "build", "test"][..],
"library" => &["check", "build", "test library/std", "doc"],
"user" => &["dist", "build"],
_ => return,
};
println!("To get started, try one of the following commands:");
for cmd in suggestions {
println!("- `x.py {}`", cmd);
}
if include_name != "user" {
println!(
"For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html"
);
}
}
// Used to get the path for `Subcommand::Setup`
pub fn interactive_path() -> io::Result<String> {
let mut input = String::new();
println!(
"Welcome to the Rust project! What do you want to do with x.py?
a) Contribute to the standard library
b) Contribute to the compiler
c) Contribute to the compiler, and also modify LLVM or codegen
d) Install Rust from source"
);
let template = loop {
print!("Please choose one (a/b/c/d): ");
io::stdout().flush()?;
io::stdin().read_line(&mut input)?;
break match input.trim().to_lowercase().as_str() {
"a" | "lib" | "library" => "library",
"b" | "compiler" => "compiler",
"c" | "llvm" => "llvm",
"d" | "user" | "maintainer" => "maintainer",
_ => {
println!("error: unrecognized option '{}'", input.trim());
println!("note: press Ctrl+C to exit");
continue;
}
};
};
Ok(template.to_owned())
}

View file

@ -256,7 +256,7 @@ impl Clean<Item> for doctree::Module<'_> {
// determine if we should display the inner contents or // determine if we should display the inner contents or
// the outer `mod` item for the source code. // the outer `mod` item for the source code.
let whence = { let span = {
let sm = cx.sess().source_map(); let sm = cx.sess().source_map();
let outer = sm.lookup_char_pos(self.where_outer.lo()); let outer = sm.lookup_char_pos(self.where_outer.lo());
let inner = sm.lookup_char_pos(self.where_inner.lo()); let inner = sm.lookup_char_pos(self.where_inner.lo());
@ -272,7 +272,7 @@ impl Clean<Item> for doctree::Module<'_> {
Item { Item {
name: Some(name), name: Some(name),
attrs, attrs,
source: whence.clean(cx), source: span.clean(cx),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
deprecation: cx.deprecation(self.id).clean(cx), deprecation: cx.deprecation(self.id).clean(cx),
@ -912,7 +912,7 @@ impl Clean<Item> for doctree::Function<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
deprecation: cx.deprecation(self.id).clean(cx), deprecation: cx.deprecation(self.id).clean(cx),
@ -1020,7 +1020,7 @@ impl Clean<Item> for doctree::Trait<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs, attrs,
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -1044,7 +1044,7 @@ impl Clean<Item> for doctree::TraitAlias<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs, attrs,
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -1830,7 +1830,7 @@ impl Clean<Item> for doctree::Struct<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -1850,7 +1850,7 @@ impl Clean<Item> for doctree::Union<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -1880,7 +1880,7 @@ impl Clean<Item> for doctree::Enum<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -1899,7 +1899,7 @@ impl Clean<Item> for doctree::Variant<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
visibility: Inherited, visibility: Inherited,
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
deprecation: cx.deprecation(self.id).clean(cx), deprecation: cx.deprecation(self.id).clean(cx),
@ -2047,7 +2047,7 @@ impl Clean<Item> for doctree::Typedef<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -2062,7 +2062,7 @@ impl Clean<Item> for doctree::OpaqueTy<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -2093,7 +2093,7 @@ impl Clean<Item> for doctree::Static<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -2114,7 +2114,7 @@ impl Clean<Item> for doctree::Constant<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: def_id.to_def_id(), def_id: def_id.to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -2168,7 +2168,7 @@ impl Clean<Vec<Item>> for doctree::Impl<'_> {
let make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| Item { let make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| Item {
name: None, name: None,
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: def_id.to_def_id(), def_id: def_id.to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -2219,7 +2219,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
vec![Item { vec![Item {
name: None, name: None,
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX }, def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX },
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: None, stability: None,
@ -2284,7 +2284,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
vec![Item { vec![Item {
name: None, name: None,
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: DefId::local(CRATE_DEF_INDEX), def_id: DefId::local(CRATE_DEF_INDEX),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: None, stability: None,
@ -2326,7 +2326,7 @@ impl Clean<Item> for doctree::ForeignItem<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
@ -2342,7 +2342,7 @@ impl Clean<Item> for doctree::Macro<'_> {
Item { Item {
name: Some(name.clone()), name: Some(name.clone()),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
visibility: Public, visibility: Public,
stability: cx.stability(self.hid).clean(cx), stability: cx.stability(self.hid).clean(cx),
deprecation: cx.deprecation(self.hid).clean(cx), deprecation: cx.deprecation(self.hid).clean(cx),
@ -2367,7 +2367,7 @@ impl Clean<Item> for doctree::ProcMacro<'_> {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
source: self.whence.clean(cx), source: self.span.clean(cx),
visibility: Public, visibility: Public,
stability: cx.stability(self.id).clean(cx), stability: cx.stability(self.id).clean(cx),
deprecation: cx.deprecation(self.id).clean(cx), deprecation: cx.deprecation(self.id).clean(cx),

View file

@ -89,7 +89,7 @@ pub struct Struct<'hir> {
pub generics: &'hir hir::Generics<'hir>, pub generics: &'hir hir::Generics<'hir>,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub fields: &'hir [hir::StructField<'hir>], pub fields: &'hir [hir::StructField<'hir>],
pub whence: Span, pub span: Span,
} }
pub struct Union<'hir> { pub struct Union<'hir> {
@ -100,7 +100,7 @@ pub struct Union<'hir> {
pub generics: &'hir hir::Generics<'hir>, pub generics: &'hir hir::Generics<'hir>,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub fields: &'hir [hir::StructField<'hir>], pub fields: &'hir [hir::StructField<'hir>],
pub whence: Span, pub span: Span,
} }
pub struct Enum<'hir> { pub struct Enum<'hir> {
@ -109,7 +109,7 @@ pub struct Enum<'hir> {
pub generics: &'hir hir::Generics<'hir>, pub generics: &'hir hir::Generics<'hir>,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub id: hir::HirId, pub id: hir::HirId,
pub whence: Span, pub span: Span,
pub name: Symbol, pub name: Symbol,
} }
@ -118,7 +118,7 @@ pub struct Variant<'hir> {
pub id: hir::HirId, pub id: hir::HirId,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub def: &'hir hir::VariantData<'hir>, pub def: &'hir hir::VariantData<'hir>,
pub whence: Span, pub span: Span,
} }
pub struct Function<'hir> { pub struct Function<'hir> {
@ -128,7 +128,7 @@ pub struct Function<'hir> {
pub name: Symbol, pub name: Symbol,
pub vis: &'hir hir::Visibility<'hir>, pub vis: &'hir hir::Visibility<'hir>,
pub header: hir::FnHeader, pub header: hir::FnHeader,
pub whence: Span, pub span: Span,
pub generics: &'hir hir::Generics<'hir>, pub generics: &'hir hir::Generics<'hir>,
pub body: hir::BodyId, pub body: hir::BodyId,
} }
@ -139,7 +139,7 @@ pub struct Typedef<'hir> {
pub name: Symbol, pub name: Symbol,
pub id: hir::HirId, pub id: hir::HirId,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub whence: Span, pub span: Span,
pub vis: &'hir hir::Visibility<'hir>, pub vis: &'hir hir::Visibility<'hir>,
} }
@ -148,7 +148,7 @@ pub struct OpaqueTy<'hir> {
pub name: Symbol, pub name: Symbol,
pub id: hir::HirId, pub id: hir::HirId,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub whence: Span, pub span: Span,
pub vis: &'hir hir::Visibility<'hir>, pub vis: &'hir hir::Visibility<'hir>,
} }
@ -161,7 +161,7 @@ pub struct Static<'hir> {
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub vis: &'hir hir::Visibility<'hir>, pub vis: &'hir hir::Visibility<'hir>,
pub id: hir::HirId, pub id: hir::HirId,
pub whence: Span, pub span: Span,
} }
pub struct Constant<'hir> { pub struct Constant<'hir> {
@ -171,7 +171,7 @@ pub struct Constant<'hir> {
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub vis: &'hir hir::Visibility<'hir>, pub vis: &'hir hir::Visibility<'hir>,
pub id: hir::HirId, pub id: hir::HirId,
pub whence: Span, pub span: Span,
} }
pub struct Trait<'hir> { pub struct Trait<'hir> {
@ -183,7 +183,7 @@ pub struct Trait<'hir> {
pub bounds: &'hir [hir::GenericBound<'hir>], pub bounds: &'hir [hir::GenericBound<'hir>],
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub id: hir::HirId, pub id: hir::HirId,
pub whence: Span, pub span: Span,
pub vis: &'hir hir::Visibility<'hir>, pub vis: &'hir hir::Visibility<'hir>,
} }
@ -193,7 +193,7 @@ pub struct TraitAlias<'hir> {
pub bounds: &'hir [hir::GenericBound<'hir>], pub bounds: &'hir [hir::GenericBound<'hir>],
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub id: hir::HirId, pub id: hir::HirId,
pub whence: Span, pub span: Span,
pub vis: &'hir hir::Visibility<'hir>, pub vis: &'hir hir::Visibility<'hir>,
} }
@ -208,7 +208,7 @@ pub struct Impl<'hir> {
pub for_: &'hir hir::Ty<'hir>, pub for_: &'hir hir::Ty<'hir>,
pub items: Vec<&'hir hir::ImplItem<'hir>>, pub items: Vec<&'hir hir::ImplItem<'hir>>,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub whence: Span, pub span: Span,
pub vis: &'hir hir::Visibility<'hir>, pub vis: &'hir hir::Visibility<'hir>,
pub id: hir::HirId, pub id: hir::HirId,
} }
@ -219,7 +219,7 @@ pub struct ForeignItem<'hir> {
pub name: Symbol, pub name: Symbol,
pub kind: &'hir hir::ForeignItemKind<'hir>, pub kind: &'hir hir::ForeignItemKind<'hir>,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub whence: Span, pub span: Span,
} }
// For Macro we store the DefId instead of the NodeId, since we also create // For Macro we store the DefId instead of the NodeId, since we also create
@ -229,7 +229,7 @@ pub struct Macro<'hir> {
pub hid: hir::HirId, pub hid: hir::HirId,
pub def_id: hir::def_id::DefId, pub def_id: hir::def_id::DefId,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub whence: Span, pub span: Span,
pub matchers: Vec<Span>, pub matchers: Vec<Span>,
pub imported_from: Option<Symbol>, pub imported_from: Option<Symbol>,
} }
@ -240,7 +240,7 @@ pub struct ExternCrate<'hir> {
pub path: Option<String>, pub path: Option<String>,
pub vis: &'hir hir::Visibility<'hir>, pub vis: &'hir hir::Visibility<'hir>,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub whence: Span, pub span: Span,
} }
pub struct Import<'hir> { pub struct Import<'hir> {
@ -250,7 +250,7 @@ pub struct Import<'hir> {
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub path: &'hir hir::Path<'hir>, pub path: &'hir hir::Path<'hir>,
pub glob: bool, pub glob: bool,
pub whence: Span, pub span: Span,
} }
pub struct ProcMacro<'hir> { pub struct ProcMacro<'hir> {
@ -259,7 +259,7 @@ pub struct ProcMacro<'hir> {
pub kind: MacroKind, pub kind: MacroKind,
pub helpers: Vec<Symbol>, pub helpers: Vec<Symbol>,
pub attrs: &'hir [ast::Attribute], pub attrs: &'hir [ast::Attribute],
pub whence: Span, pub span: Span,
} }
pub fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType { pub fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType {

View file

@ -99,7 +99,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
attrs: &item.attrs, attrs: &item.attrs,
generics, generics,
fields: sd.fields(), fields: sd.fields(),
whence: item.span, span: item.span,
} }
} }
@ -120,7 +120,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
attrs: &item.attrs, attrs: &item.attrs,
generics, generics,
fields: sd.fields(), fields: sd.fields(),
whence: item.span, span: item.span,
} }
} }
@ -142,14 +142,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
id: v.id, id: v.id,
attrs: &v.attrs, attrs: &v.attrs,
def: &v.data, def: &v.data,
whence: v.span, span: v.span,
}) })
.collect(), .collect(),
vis: &it.vis, vis: &it.vis,
generics, generics,
attrs: &it.attrs, attrs: &it.attrs,
id: it.hir_id, id: it.hir_id,
whence: it.span, span: it.span,
} }
} }
@ -208,7 +208,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
kind, kind,
helpers, helpers,
attrs: &item.attrs, attrs: &item.attrs,
whence: item.span, span: item.span,
}); });
} }
None => { None => {
@ -218,7 +218,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
attrs: &item.attrs, attrs: &item.attrs,
decl, decl,
name, name,
whence: item.span, span: item.span,
generics, generics,
header, header,
body, body,
@ -402,7 +402,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
path: orig_name.map(|x| x.to_string()), path: orig_name.map(|x| x.to_string()),
vis: &item.vis, vis: &item.vis,
attrs: &item.attrs, attrs: &item.attrs,
whence: item.span, span: item.span,
}) })
} }
hir::ItemKind::Use(_, hir::UseKind::ListStem) => {} hir::ItemKind::Use(_, hir::UseKind::ListStem) => {}
@ -444,7 +444,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
attrs: &item.attrs, attrs: &item.attrs,
path, path,
glob: is_glob, glob: is_glob,
whence: item.span, span: item.span,
}); });
} }
hir::ItemKind::Mod(ref m) => { hir::ItemKind::Mod(ref m) => {
@ -476,7 +476,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
name: ident.name, name: ident.name,
id: item.hir_id, id: item.hir_id,
attrs: &item.attrs, attrs: &item.attrs,
whence: item.span, span: item.span,
vis: &item.vis, vis: &item.vis,
}; };
om.typedefs.push(t); om.typedefs.push(t);
@ -487,7 +487,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
name: ident.name, name: ident.name,
id: item.hir_id, id: item.hir_id,
attrs: &item.attrs, attrs: &item.attrs,
whence: item.span, span: item.span,
vis: &item.vis, vis: &item.vis,
}; };
om.opaque_tys.push(t); om.opaque_tys.push(t);
@ -500,7 +500,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
id: item.hir_id, id: item.hir_id,
name: ident.name, name: ident.name,
attrs: &item.attrs, attrs: &item.attrs,
whence: item.span, span: item.span,
vis: &item.vis, vis: &item.vis,
}; };
om.statics.push(s); om.statics.push(s);
@ -515,7 +515,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
id: item.hir_id, id: item.hir_id,
name: ident.name, name: ident.name,
attrs: &item.attrs, attrs: &item.attrs,
whence: item.span, span: item.span,
vis: &item.vis, vis: &item.vis,
}; };
om.constants.push(s); om.constants.push(s);
@ -532,7 +532,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
bounds, bounds,
id: item.hir_id, id: item.hir_id,
attrs: &item.attrs, attrs: &item.attrs,
whence: item.span, span: item.span,
vis: &item.vis, vis: &item.vis,
}; };
om.traits.push(t); om.traits.push(t);
@ -544,7 +544,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
bounds, bounds,
id: item.hir_id, id: item.hir_id,
attrs: &item.attrs, attrs: &item.attrs,
whence: item.span, span: item.span,
vis: &item.vis, vis: &item.vis,
}; };
om.trait_aliases.push(t); om.trait_aliases.push(t);
@ -577,7 +577,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
items, items,
attrs: &item.attrs, attrs: &item.attrs,
id: item.hir_id, id: item.hir_id,
whence: item.span, span: item.span,
vis: &item.vis, vis: &item.vis,
}; };
om.impls.push(i); om.impls.push(i);
@ -603,7 +603,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
kind: &item.kind, kind: &item.kind,
vis: &item.vis, vis: &item.vis,
attrs: &item.attrs, attrs: &item.attrs,
whence: item.span, span: item.span,
}); });
} }
@ -623,7 +623,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
def_id: self.cx.tcx.hir().local_def_id(def.hir_id).to_def_id(), def_id: self.cx.tcx.hir().local_def_id(def.hir_id).to_def_id(),
attrs: &def.attrs, attrs: &def.attrs,
name: renamed.unwrap_or(def.ident.name), name: renamed.unwrap_or(def.ident.name),
whence: def.span, span: def.span,
matchers, matchers,
imported_from: None, imported_from: None,
} }

View file

@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/cannot-infer-const-args.rs:12:5 --> $DIR/cannot-infer-const-args.rs:12:5
| |
LL | foo(); LL | foo();
| ^^^ | ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
|
= note: cannot infer the value of the const parameter `X`
error: aborting due to previous error error: aborting due to previous error

View file

@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/cannot-infer-const-args.rs:12:5 --> $DIR/cannot-infer-const-args.rs:12:5
| |
LL | foo(); LL | foo();
| ^^^ | ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
|
= note: cannot infer the value of the const parameter `X`
error: aborting due to previous error error: aborting due to previous error

View file

@ -0,0 +1,16 @@
#![feature(min_const_generics)]
use std::convert::TryInto;
fn take_array_from_mut<T, const N: usize>(data: &mut [T], start: usize) -> &mut [T; N] {
(&mut data[start .. start + N]).try_into().unwrap()
}
fn main() {
let mut arr = [0, 1, 2, 3, 4, 5, 6, 7, 8];
for i in 1 .. 4 {
println!("{:?}", take_array_from_mut(&mut arr, i));
//~^ ERROR type annotations needed
}
}

View file

@ -0,0 +1,9 @@
error[E0282]: type annotations needed
--> $DIR/issue-77092.rs:13:26
|
LL | println!("{:?}", take_array_from_mut(&mut arr, i));
| ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `{_: usize}`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.

View file

@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/method-chain.rs:21:33 --> $DIR/method-chain.rs:21:33
| |
LL | Foo.bar().bar().bar().bar().baz(); LL | Foo.bar().bar().bar().bar().baz();
| ^^^ | ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
|
= note: cannot infer the value of the const parameter `N`
error: aborting due to previous error error: aborting due to previous error

View file

@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/method-chain.rs:21:33 --> $DIR/method-chain.rs:21:33
| |
LL | Foo.bar().bar().bar().bar().baz(); LL | Foo.bar().bar().bar().bar().baz();
| ^^^ | ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
|
= note: cannot infer the value of the const parameter `N`
error: aborting due to previous error error: aborting due to previous error

View file

@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/uninferred-consts.rs:14:9 --> $DIR/uninferred-consts.rs:14:9
| |
LL | Foo.foo(); LL | Foo.foo();
| ^^^ | ^^^ cannot infer the value of const parameter `N` declared on the associated function `foo`
|
= note: cannot infer the value of the const parameter `N`
error: aborting due to previous error error: aborting due to previous error

View file

@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/uninferred-consts.rs:14:9 --> $DIR/uninferred-consts.rs:14:9
| |
LL | Foo.foo(); LL | Foo.foo();
| ^^^ | ^^^ cannot infer the value of const parameter `N` declared on the associated function `foo`
|
= note: cannot infer the value of the const parameter `N`
error: aborting due to previous error error: aborting due to previous error

View file

@ -4,7 +4,7 @@ const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
const unsafe extern "C" fn closure() -> fn() { || {} } const unsafe extern "C" fn closure() -> fn() { || {} }
//~^ ERROR function pointers in const fn are unstable //~^ ERROR function pointers in const fn are unstable
const unsafe extern fn use_float() { 1.0 + 1.0; } const unsafe extern fn use_float() { 1.0 + 1.0; }
//~^ ERROR only int, `bool` and `char` operations are stable in const fn //~^ ERROR floating point arithmetic
const extern "C" fn ptr_cast(val: *const u8) { val as usize; } const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
//~^ ERROR casting pointers to integers //~^ ERROR casting pointers to integers

View file

@ -7,14 +7,14 @@ LL | const unsafe extern "C" fn closure() -> fn() { || {} }
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: only int, `bool` and `char` operations are stable in const fn error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const-extern-fn-min-const-fn.rs:6:38 --> $DIR/const-extern-fn-min-const-fn.rs:6:38
| |
LL | const unsafe extern fn use_float() { 1.0 + 1.0; } LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
| ^^^^^^^^^ | ^^^^^^^^^
| |
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
error[E0658]: casting pointers to integers in constant functions is unstable error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/const-extern-fn-min-const-fn.rs:8:48 --> $DIR/const-extern-fn-min-const-fn.rs:8:48

View file

@ -0,0 +1,8 @@
error: fatal error triggered by #[rustc_error]
--> $DIR/const_fn_floating_point_arithmetic.rs:20:1
|
LL | fn main() {}
| ^^^^^^^^^
error: aborting due to previous error

View file

@ -0,0 +1,20 @@
// gate-test-const_fn_floating_point_arithmetic
// revisions: stock gated
#![feature(rustc_attrs)]
#![cfg_attr(gated, feature(const_fn_floating_point_arithmetic))]
const fn add(f: f32) -> f32 { f + 2.0 }
//[stock]~^ floating point arithmetic
const fn sub(f: f32) -> f32 { 2.0 - f }
//[stock]~^ floating point arithmetic
const fn mul(f: f32, g: f32) -> f32 { f * g }
//[stock]~^ floating point arithmetic
const fn div(f: f32, g: f32) -> f32 { f / g }
//[stock]~^ floating point arithmetic
const fn neg(f: f32) -> f32 { -f }
//[stock]~^ floating point arithmetic
#[rustc_error]
fn main() {} //[gated]~ fatal error triggered by #[rustc_error]

View file

@ -0,0 +1,48 @@
error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const_fn_floating_point_arithmetic.rs:8:31
|
LL | const fn add(f: f32) -> f32 { f + 2.0 }
| ^^^^^^^
|
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const_fn_floating_point_arithmetic.rs:10:31
|
LL | const fn sub(f: f32) -> f32 { 2.0 - f }
| ^^^^^^^
|
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const_fn_floating_point_arithmetic.rs:12:39
|
LL | const fn mul(f: f32, g: f32) -> f32 { f * g }
| ^^^^^
|
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const_fn_floating_point_arithmetic.rs:14:39
|
LL | const fn div(f: f32, g: f32) -> f32 { f / g }
| ^^^^^
|
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const_fn_floating_point_arithmetic.rs:16:31
|
LL | const fn neg(f: f32) -> f32 { -f }
| ^^
|
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,6 +1,6 @@
// build-pass (FIXME(62277): could be check-pass?) // run-pass
#![feature(const_fn)] #![feature(const_fn_floating_point_arithmetic)]
struct Foo<T>(T); struct Foo<T>(T);
struct Bar<T> { x: T } struct Bar<T> { x: T }

View file

@ -77,14 +77,6 @@ const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable //~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
const fn foo11_2<T: Send>(t: T) -> T { t } const fn foo11_2<T: Send>(t: T) -> T { t }
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable //~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
const fn foo19(f: f32) -> f32 { f * 2.0 }
//~^ ERROR int, `bool` and `char` operations
const fn foo19_2(f: f32) -> f32 { 2.0 - f }
//~^ ERROR int, `bool` and `char` operations
const fn foo19_3(f: f32) -> f32 { -f }
//~^ ERROR int, `bool` and `char` operations
const fn foo19_4(f: f32, g: f32) -> f32 { f / g }
//~^ ERROR int, `bool` and `char` operations
static BAR: u32 = 42; static BAR: u32 = 42;
const fn foo25() -> u32 { BAR } //~ ERROR cannot refer to statics const fn foo25() -> u32 { BAR } //~ ERROR cannot refer to statics

View file

@ -76,44 +76,8 @@ LL | const fn foo11_2<T: Send>(t: T) -> T { t }
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: only int, `bool` and `char` operations are stable in const fn
--> $DIR/min_const_fn.rs:80:33
|
LL | const fn foo19(f: f32) -> f32 { f * 2.0 }
| ^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: only int, `bool` and `char` operations are stable in const fn
--> $DIR/min_const_fn.rs:82:35
|
LL | const fn foo19_2(f: f32) -> f32 { 2.0 - f }
| ^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: only int, `bool` and `char` operations are stable in const fn
--> $DIR/min_const_fn.rs:84:35
|
LL | const fn foo19_3(f: f32) -> f32 { -f }
| ^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: only int, `bool` and `char` operations are stable in const fn
--> $DIR/min_const_fn.rs:86:43
|
LL | const fn foo19_4(f: f32, g: f32) -> f32 { f / g }
| ^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0013]: constant functions cannot refer to statics error[E0013]: constant functions cannot refer to statics
--> $DIR/min_const_fn.rs:90:27 --> $DIR/min_const_fn.rs:82:27
| |
LL | const fn foo25() -> u32 { BAR } LL | const fn foo25() -> u32 { BAR }
| ^^^ | ^^^
@ -121,7 +85,7 @@ LL | const fn foo25() -> u32 { BAR }
= help: consider extracting the value of the `static` to a `const`, and referring to that = help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0013]: constant functions cannot refer to statics error[E0013]: constant functions cannot refer to statics
--> $DIR/min_const_fn.rs:91:37 --> $DIR/min_const_fn.rs:83:37
| |
LL | const fn foo26() -> &'static u32 { &BAR } LL | const fn foo26() -> &'static u32 { &BAR }
| ^^^ | ^^^
@ -129,7 +93,7 @@ LL | const fn foo26() -> &'static u32 { &BAR }
= help: consider extracting the value of the `static` to a `const`, and referring to that = help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0658]: casting pointers to integers in constant functions is unstable error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/min_const_fn.rs:92:42 --> $DIR/min_const_fn.rs:84:42
| |
LL | const fn foo30(x: *const u32) -> usize { x as usize } LL | const fn foo30(x: *const u32) -> usize { x as usize }
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -138,7 +102,7 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize }
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
error[E0658]: casting pointers to integers in constant functions is unstable error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/min_const_fn.rs:94:63 --> $DIR/min_const_fn.rs:86:63
| |
LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } } LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -147,7 +111,7 @@ LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize }
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
error[E0658]: casting pointers to integers in constant functions is unstable error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/min_const_fn.rs:96:42 --> $DIR/min_const_fn.rs:88:42
| |
LL | const fn foo30_2(x: *mut u32) -> usize { x as usize } LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -156,7 +120,7 @@ LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
error[E0658]: casting pointers to integers in constant functions is unstable error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/min_const_fn.rs:98:63 --> $DIR/min_const_fn.rs:90:63
| |
LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -165,7 +129,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize }
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
error[E0658]: mutable references are not allowed in constant functions error[E0658]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:101:14 --> $DIR/min_const_fn.rs:93:14
| |
LL | const fn inc(x: &mut i32) { *x += 1 } LL | const fn inc(x: &mut i32) { *x += 1 }
| ^ | ^
@ -174,7 +138,7 @@ LL | const fn inc(x: &mut i32) { *x += 1 }
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:110:6 --> $DIR/min_const_fn.rs:102:6
| |
LL | impl<T: std::fmt::Debug> Foo<T> { LL | impl<T: std::fmt::Debug> Foo<T> {
| ^ | ^
@ -183,7 +147,7 @@ LL | impl<T: std::fmt::Debug> Foo<T> {
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:115:6 --> $DIR/min_const_fn.rs:107:6
| |
LL | impl<T: std::fmt::Debug + Sized> Foo<T> { LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
| ^ | ^
@ -192,7 +156,7 @@ LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:120:6 --> $DIR/min_const_fn.rs:112:6
| |
LL | impl<T: Sync + Sized> Foo<T> { LL | impl<T: Sync + Sized> Foo<T> {
| ^ | ^
@ -201,7 +165,7 @@ LL | impl<T: Sync + Sized> Foo<T> {
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:126:34 --> $DIR/min_const_fn.rs:118:34
| |
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {} LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -210,7 +174,7 @@ LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:128:22 --> $DIR/min_const_fn.rs:120:22
| |
LL | const fn no_apit(_x: impl std::fmt::Debug) {} LL | const fn no_apit(_x: impl std::fmt::Debug) {}
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -219,7 +183,7 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {}
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:129:23 --> $DIR/min_const_fn.rs:121:23
| |
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
| ^^ | ^^
@ -228,7 +192,7 @@ LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:130:32 --> $DIR/min_const_fn.rs:122:32
| |
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -237,7 +201,7 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
--> $DIR/min_const_fn.rs:135:41 --> $DIR/min_const_fn.rs:127:41
| |
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -246,7 +210,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: function pointers in const fn are unstable error[E0723]: function pointers in const fn are unstable
--> $DIR/min_const_fn.rs:138:21 --> $DIR/min_const_fn.rs:130:21
| |
LL | const fn no_fn_ptrs(_x: fn()) {} LL | const fn no_fn_ptrs(_x: fn()) {}
| ^^ | ^^
@ -255,7 +219,7 @@ LL | const fn no_fn_ptrs(_x: fn()) {}
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: function pointers in const fn are unstable error[E0723]: function pointers in const fn are unstable
--> $DIR/min_const_fn.rs:140:27 --> $DIR/min_const_fn.rs:132:27
| |
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
| ^^^^ | ^^^^
@ -263,7 +227,7 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable = help: add `#![feature(const_fn)]` to the crate attributes to enable
error: aborting due to 30 previous errors error: aborting due to 26 previous errors
Some errors have detailed explanations: E0013, E0493, E0658, E0723. Some errors have detailed explanations: E0013, E0493, E0658, E0723.
For more information about an error, try `rustc --explain E0013`. For more information about an error, try `rustc --explain E0013`.

View file

@ -3,7 +3,7 @@
we're apparently really bad at it", we're apparently really bad at it",
issue = "none")] issue = "none")]
#![feature(const_fn, foo, foo2)] #![feature(const_fn, const_fn_floating_point_arithmetic, foo, foo2)]
#![feature(staged_api)] #![feature(staged_api)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -25,9 +25,9 @@ const fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// conformity is required, even with `const_fn` feature gate // Const-stable functions cannot rely on unstable const-eval features.
const fn bar3() -> u32 { (5f32 + 6f32) as u32 } const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
//~^ ERROR const-stable function cannot use `#[feature(const_fn)]` //~^ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
// check whether this function cannot be called even with the feature gate active // check whether this function cannot be called even with the feature gate active
#[unstable(feature = "foo2", issue = "none")] #[unstable(feature = "foo2", issue = "none")]

View file

@ -14,7 +14,7 @@ LL | const fn bar2() -> u32 { foo2() }
| |
= help: Const-stable functions can only call other const-stable functions = help: Const-stable functions can only call other const-stable functions
error: const-stable function cannot use `#[feature(const_fn)]` error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
--> $DIR/min_const_fn_libstd_stability.rs:29:26 --> $DIR/min_const_fn_libstd_stability.rs:29:26
| |
LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 } LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }

View file

@ -3,7 +3,7 @@
we're apparently really bad at it", we're apparently really bad at it",
issue = "none")] issue = "none")]
#![feature(const_fn, foo, foo2)] #![feature(const_fn, const_fn_floating_point_arithmetic, foo, foo2)]
#![feature(staged_api)] #![feature(staged_api)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -27,7 +27,7 @@ const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR not yet stable as
#[rustc_const_stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// conformity is required, even with `const_fn` feature gate // conformity is required, even with `const_fn` feature gate
const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
//~^ ERROR const-stable function cannot use `#[feature(const_fn)]` //~^ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
// check whether this function cannot be called even with the feature gate active // check whether this function cannot be called even with the feature gate active
#[unstable(feature = "foo2", issue = "none")] #[unstable(feature = "foo2", issue = "none")]

View file

@ -14,7 +14,7 @@ LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } }
| |
= help: Const-stable functions can only call other const-stable functions = help: Const-stable functions can only call other const-stable functions
error: const-stable function cannot use `#[feature(const_fn)]` error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
--> $DIR/min_const_unsafe_fn_libstd_stability.rs:29:33 --> $DIR/min_const_unsafe_fn_libstd_stability.rs:29:33
| |
LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }

@ -1 +1 @@
Subproject commit 02a33d411d8e385942776760a99535d69826349b Subproject commit 2f84bfc57dd0ef22269bb84dae10f71e5e23e85d

View file

@ -9,6 +9,6 @@ edition = "2018"
clap = "2.25.0" clap = "2.25.0"
[dependencies.mdbook] [dependencies.mdbook]
version = "0.4.0" version = "0.4.3"
default-features = false default-features = false
features = ["search"] features = ["search"]