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]]
name = "mdbook"
version = "0.4.2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75e31ae4eaa0e45e17ee2b6b9e3ed969c3c6ff12bb4c2e352c42493f4ebb706"
checksum = "29be448fcafb00c5a8966c4020c2a5ffbbc333e5b96d0bb5ef54b5bd0524d9ff"
dependencies = [
"ammonia",
"anyhow",

View file

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

View file

@ -21,7 +21,6 @@ use rustc_target::abi::{self, Align, Size};
use rustc_target::spec::{HasTargetSpec, Target};
use std::borrow::Cow;
use std::ffi::CStr;
use std::iter::TrustedLen;
use std::ops::{Deref, Range};
use std::ptr;
use tracing::debug;
@ -179,7 +178,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
&mut self,
v: &'ll Value,
else_llbb: &'ll BasicBlock,
cases: impl ExactSizeIterator<Item = (u128, &'ll BasicBlock)> + TrustedLen,
cases: impl ExactSizeIterator<Item = (u128, &'ll BasicBlock)>,
) {
let switch =
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) }
}
#[allow(dead_code)]
fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
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.
use crate::consts::{self, const_alloc_to_llvm};

View file

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

View file

@ -12,7 +12,6 @@
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![feature(or_patterns)]
#![feature(trusted_len)]
#![recursion_limit = "256"]
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_target::abi::{Align, HasDataLayout, LayoutOf, Size};
#[allow(dead_code)]
fn round_pointer_up_to_alignment(
bx: &mut Builder<'a, 'll, 'tcx>,
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_hir as hir;
@ -25,7 +25,6 @@ pub enum IntPredicate {
IntSLE,
}
#[allow(dead_code)]
pub enum RealPredicate {
RealPredicateFalse,
RealOEQ,
@ -60,7 +59,6 @@ pub enum AtomicRmwBinOp {
}
pub enum AtomicOrdering {
#[allow(dead_code)]
NotAtomic,
Unordered,
Monotonic,

View file

@ -6,7 +6,6 @@
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![feature(or_patterns)]
#![feature(trusted_len)]
#![feature(associated_type_bounds)]
#![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::spec::HasTargetSpec;
use std::iter::TrustedLen;
use std::ops::Range;
#[derive(Copy, Clone)]
@ -60,7 +59,7 @@ pub trait BuilderMethods<'a, 'tcx>:
&mut self,
v: Self::Value,
else_llbb: Self::BasicBlock,
cases: impl ExactSizeIterator<Item = (u128, Self::BasicBlock)> + TrustedLen,
cases: impl ExactSizeIterator<Item = (u128, Self::BasicBlock)>,
);
fn invoke(
&mut self,

View file

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

View file

@ -584,6 +584,9 @@ declare_features! (
/// Allows non trivial generic constants which have to be manually propageted upwards.
(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
// -------------------------------------------------------------------------

View file

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

View file

@ -176,7 +176,10 @@ fn closure_return_type_suggestion(
suggestion,
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.
@ -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> {
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,
ty: Ty<'tcx>,
arg: GenericArg<'tcx>,
highlight: Option<ty::print::RegionHighlightMode>,
) -> (String, Option<Span>, Cow<'static, str>, Option<String>, Option<&'static str>) {
if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() {
let mut inner = self.inner.borrow_mut();
let ty_vars = &inner.type_variables();
let var_origin = ty_vars.var_origin(ty_vid);
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind {
let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id));
let (parent_name, parent_desc) = 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());
) -> InferenceDiagnosticsData {
match arg.unpack() {
GenericArgKind::Type(ty) => {
if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() {
let mut inner = self.inner.borrow_mut();
let ty_vars = &inner.type_variables();
let var_origin = ty_vars.var_origin(ty_vid);
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) =
var_origin.kind
{
let parent_def_id = def_id.and_then(|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());
(parent_name, Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)))
} else {
(None, None)
};
(
parent_name,
Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)),
)
} else {
(None, None)
};
if name != kw::SelfUpper {
return (
name.to_string(),
Some(var_origin.span),
"type parameter".into(),
parent_name,
parent_desc,
);
if name != kw::SelfUpper {
return InferenceDiagnosticsData {
name: name.to_string(),
span: Some(var_origin.span),
description: "type parameter".into(),
parent_name,
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);
if let Some(highlight) = highlight {
printer.region_highlight_mode = highlight;
(
parent_name,
Some(self.tcx.def_kind(parent_def_id).descr(parent_def_id)),
)
} 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 need_type_info_err(
pub fn emit_inference_failure_err(
&self,
body_id: Option<hir::BodyId>,
span: Span,
ty: Ty<'tcx>,
arg: GenericArg<'tcx>,
error_code: TypeAnnotationNeeded,
) -> DiagnosticBuilder<'tcx> {
let ty = self.resolve_vars_if_possible(&ty);
let (name, name_sp, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None);
let arg = self.resolve_vars_if_possible(&arg);
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 mut s = String::new();
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 {
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:
// error[E0282]: type annotations needed
// --> file2.rs:3:15
@ -352,7 +441,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
_ => 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
// " in `std::result::Result<i32, E>`":
// ```
@ -391,11 +480,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
&mut err,
&decl.output,
self.tcx.hir().body(body_id),
&descr,
&name,
&arg_data.description,
&arg_data.name,
&ret,
parent_name,
parent_descr,
arg_data.parent_name,
arg_data.parent_description,
);
// We don't want to give the other suggestions when the problem is the
// closure return type.
@ -409,15 +498,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// nudge them in the right direction.
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);
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);
format!(
"the explicit type `{}`, where the type parameter `{}` is specified",
ty, name,
ty, arg_data.name,
)
}
_ => "a type".to_string(),
@ -534,7 +623,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// | ^^^ cannot infer type for `S`
// |
// = 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
.span
.span_labels()
@ -545,55 +634,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// Avoid multiple labels pointing at `span`.
err.span_label(
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
}
// 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
/// needed, suggest annotating the call, otherwise point out the resulting type of the call.
fn annotate_method_call(
@ -647,7 +700,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ty: Ty<'tcx>,
) -> DiagnosticBuilder<'tcx> {
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!(
self.tcx.sess,
@ -656,18 +709,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"type inside {} must be known in this context",
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
}
fn missing_type_msg(
fn cannot_infer_msg(
kind_str: &str,
type_name: &str,
descr: &str,
parent_name: Option<String>,
parent_descr: Option<&str>,
) -> Cow<'static, str> {
) -> String {
if type_name == "_" {
"cannot infer type".into()
format!("cannot infer {}", kind_str)
} else {
let parent_desc = if let Some(parent_name) = parent_name {
let parent_type_descr = if let Some(parent_descr) = parent_descr {
@ -681,7 +744,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"".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 { .. } => {
let origin = ConstVariableOrigin {
kind: ConstVariableOriginKind::ConstParameterDefinition(param.name),
kind: ConstVariableOriginKind::ConstParameterDefinition(
param.name,
param.def_id,
),
span,
};
let const_var_id =
@ -1275,7 +1278,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
/// Gives temporary access to the region constraint data.
#[allow(non_camel_case_types)] // bug with impl trait
pub fn with_region_constraints<R>(
&self,
op: impl FnOnce(&RegionConstraintData<'tcx>) -> R,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -396,7 +396,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
) -> Option<RegionNameHighlight> {
let mut highlight = RegionHighlightMode::default();
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!(
"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() {
// Only add a label if we can confirm that a region was labelled.
Some(RegionNameHighlight::CannotMatchHirTy(span, type_name))
} else {
None
@ -646,7 +646,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let mut highlight = RegionHighlightMode::default();
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);
@ -698,7 +699,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let mut highlight = RegionHighlightMode::default();
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);

View file

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

View file

@ -144,7 +144,6 @@ impl<'tcx> fmt::Display for MovePath<'tcx> {
}
}
#[allow(unused)]
struct MovePathLinearIter<'a, 'tcx, F> {
next: Option<(MovePathIndex, &'a MovePath<'tcx>)>,
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)]
pub struct NonPrimitiveOp;
impl NonConstOp for NonPrimitiveOp {

View file

@ -540,8 +540,12 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
Rvalue::UnaryOp(_, ref operand) => {
let ty = operand.ty(self.body, self.tcx);
if !(ty.is_integral() || ty.is_bool()) {
self.check_op(ops::NonPrimitiveOp)
if is_int_bool_or_char(ty) {
// 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 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!(
op == BinOp::Eq
@ -563,12 +569,15 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
);
self.check_op(ops::RawPtrComparison);
}
if !(lhs_ty.is_integral() || lhs_ty.is_bool() || lhs_ty.is_char())
|| !(rhs_ty.is_integral() || rhs_ty.is_bool() || rhs_ty.is_char())
{
self.check_op(ops::NonPrimitiveOp)
} else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() {
self.check_op(ops::FloatingPointOp);
} else {
span_bug!(
self.span,
"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::*;
use std::borrow::Cow;

View file

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

View file

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

View file

@ -20,7 +20,6 @@ use rustc_hir::Node;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{
self, fast_reject, AdtKind, SubtypePredicate, ToPolyTraitRef, ToPredicate, Ty, TyCtxt,
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
// begin with in those cases.
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;
}
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));
if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
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;
}
match arg.unpack() {
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)
}
}
self.emit_inference_failure_err(body_id, span, arg, ErrorCode::E0282)
}
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;
// both must be type variables, or the other would've been instantiated
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) => {
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() {
// 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
} else {

View file

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

View file

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

View file

@ -2991,7 +2991,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty
} else {
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")
.emit();
}

View file

@ -653,7 +653,12 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
fn report_type_error(&self, t: Ty<'tcx>) {
if !self.tcx.sess.has_errors() {
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();
}
}
@ -661,10 +666,10 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
fn report_const_error(&self, c: &'tcx ty::Const<'tcx>) {
if !self.tcx.sess.has_errors() {
self.infcx
.need_type_info_err_const(
.emit_inference_failure_err(
Some(self.body.id()),
self.span.to_span(self.tcx),
c,
c.into(),
E0282,
)
.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/")]
#![allow(non_camel_case_types)]
#![feature(bool_to_option)]
#![feature(box_syntax)]
#![feature(crate_visibility_modifier)]

View file

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

View file

@ -70,10 +70,23 @@
//! }
//! ```
//!
//! This usage of [`Option`] to create safe nullable pointers is so
//! common that Rust does special optimizations to make the
//! representation of [`Option`]`<`[`Box<T>`]`>` a single pointer. Optional pointers
//! in Rust are stored as efficiently as any other pointer type.
//! # Representation
//!
//! Rust guarantees to optimize the following types `T` such that
//! [`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
//!

View file

@ -319,6 +319,13 @@ pub(super) trait SplitIter: DoubleEndedIterator {
///
/// 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
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # 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
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # 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
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # 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
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # Example
///
/// ```
/// let slice = [11, 22, 33, 0, 44, 55];
/// let iter = slice.rsplit(|num| *num == 0);
/// ```
///
/// [`rsplit`]: ../../std/primitive.slice.html#method.rsplit
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # 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
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # 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
/// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")]
@ -999,6 +1052,13 @@ where
///
/// 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
/// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")]
@ -1031,6 +1091,13 @@ where
///
/// 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
/// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")]
@ -1064,6 +1131,13 @@ where
///
/// 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
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # Example
///
/// ```
/// let slice = ['r', 'u', 's', 't'];
/// let iter = slice.windows(2);
/// ```
///
/// [`windows`]: ../../std/primitive.slice.html#method.windows
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # Example
///
/// ```
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.chunks(2);
/// ```
///
/// [`chunks`]: ../../std/primitive.slice.html#method.chunks
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # Example
///
/// ```
/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.chunks_mut(2);
/// ```
///
/// [`chunks_mut`]: ../../std/primitive.slice.html#method.chunks_mut
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # Example
///
/// ```
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.chunks_exact(2);
/// ```
///
/// [`chunks_exact`]: ../../std/primitive.slice.html#method.chunks_exact
/// [`remainder`]: ChunksExact::remainder
/// [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].
///
/// # 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
/// [`into_remainder`]: ChunksExactMut::into_remainder
/// [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].
///
/// # 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
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # 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
/// [`remainder`]: ArrayChunks::remainder
/// [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].
///
/// # 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
/// [`into_remainder`]: ../../std/slice/struct.ArrayChunksMut.html#method.into_remainder
/// [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].
///
/// # Example
///
/// ```
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.rchunks(2);
/// ```
///
/// [`rchunks`]: ../../std/primitive.slice.html#method.rchunks
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # Example
///
/// ```
/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.rchunks_mut(2);
/// ```
///
/// [`rchunks_mut`]: ../../std/primitive.slice.html#method.rchunks_mut
/// [slices]: ../../std/primitive.slice.html
#[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].
///
/// # Example
///
/// ```
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let iter = slice.rchunks_exact(2);
/// ```
///
/// [`rchunks_exact`]: ../../std/primitive.slice.html#method.rchunks_exact
/// [`remainder`]: ChunksExact::remainder
/// [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].
///
/// # 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
/// [`into_remainder`]: ChunksExactMut::into_remainder
/// [slices]: ../../std/primitive.slice.html

View file

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

View file

@ -384,6 +384,7 @@ mod prim_char {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_unit {}
#[doc(alias = "ptr")]
#[doc(primitive = "pointer")]
//
/// 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]
- 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)
- Optionally, download LLVM from CI on Linux and NixOS
+ [#76439](https://github.com/rust-lang/rust/pull/76349)

View file

@ -7,21 +7,34 @@
use std::env;
use bootstrap::{Build, Config};
use bootstrap::{Build, Config, Subcommand};
fn main() {
let args = env::args().skip(1).collect::<Vec<_>>();
let config = Config::parse(&args);
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);
}
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);
}
if suggest_setup || changelog_suggestion.is_some() {
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::Install { ref paths } => (Kind::Install, &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())

View file

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

View file

@ -7,6 +7,7 @@ use std::env;
use std::path::PathBuf;
use std::process;
use build_helper::t;
use getopts::Options;
use crate::builder::Builder;
@ -89,6 +90,9 @@ pub enum Subcommand {
Run {
paths: Vec<PathBuf>,
},
Setup {
path: String,
},
}
impl Default for Subcommand {
@ -199,6 +203,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
|| (s == "install")
|| (s == "run")
|| (s == "r")
|| (s == "setup")
});
let subcommand = match subcommand {
Some(s) => s,
@ -453,10 +458,21 @@ Arguments:
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
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 verbose = matches.opt_present("verbose");
@ -508,6 +524,20 @@ Arguments:
}
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);
}

View file

@ -141,6 +141,7 @@ mod metadata;
mod native;
mod run;
mod sanity;
mod setup;
mod test;
mod tool;
mod toolstate;
@ -165,7 +166,7 @@ mod job {
use crate::cache::{Interned, INTERNER};
pub use crate::config::Config;
use crate::flags::Subcommand;
pub use crate::flags::Subcommand;
const LLVM_TOOLS: &[&str] = &[
"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);
}
if let Subcommand::Setup { path: include_name } = &self.config.cmd {
return setup::setup(&self.config.src, include_name);
}
{
let builder = builder::Builder::new(&self);
if let Some(path) = builder.paths.get(0) {

View file

@ -10,7 +10,7 @@ impl Step for ExpandYamlAnchors {
/// 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.
fn run(self, builder: &Builder<'_>) {
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
// the outer `mod` item for the source code.
let whence = {
let span = {
let sm = cx.sess().source_map();
let outer = sm.lookup_char_pos(self.where_outer.lo());
let inner = sm.lookup_char_pos(self.where_inner.lo());
@ -272,7 +272,7 @@ impl Clean<Item> for doctree::Module<'_> {
Item {
name: Some(name),
attrs,
source: whence.clean(cx),
source: span.clean(cx),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
deprecation: cx.deprecation(self.id).clean(cx),
@ -912,7 +912,7 @@ impl Clean<Item> for doctree::Function<'_> {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
source: self.span.clean(cx),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
deprecation: cx.deprecation(self.id).clean(cx),
@ -1020,7 +1020,7 @@ impl Clean<Item> for doctree::Trait<'_> {
Item {
name: Some(self.name.clean(cx)),
attrs,
source: self.whence.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
@ -1044,7 +1044,7 @@ impl Clean<Item> for doctree::TraitAlias<'_> {
Item {
name: Some(self.name.clean(cx)),
attrs,
source: self.whence.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
@ -1830,7 +1830,7 @@ impl Clean<Item> for doctree::Struct<'_> {
Item {
name: Some(self.name.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(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
@ -1850,7 +1850,7 @@ impl Clean<Item> for doctree::Union<'_> {
Item {
name: Some(self.name.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(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
@ -1880,7 +1880,7 @@ impl Clean<Item> for doctree::Enum<'_> {
Item {
name: Some(self.name.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(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
@ -1899,7 +1899,7 @@ impl Clean<Item> for doctree::Variant<'_> {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
source: self.span.clean(cx),
visibility: Inherited,
stability: cx.stability(self.id).clean(cx),
deprecation: cx.deprecation(self.id).clean(cx),
@ -2047,7 +2047,7 @@ impl Clean<Item> for doctree::Typedef<'_> {
Item {
name: Some(self.name.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(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
@ -2062,7 +2062,7 @@ impl Clean<Item> for doctree::OpaqueTy<'_> {
Item {
name: Some(self.name.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(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
@ -2093,7 +2093,7 @@ impl Clean<Item> for doctree::Static<'_> {
Item {
name: Some(self.name.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(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
@ -2114,7 +2114,7 @@ impl Clean<Item> for doctree::Constant<'_> {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
source: self.span.clean(cx),
def_id: def_id.to_def_id(),
visibility: self.vis.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 {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
source: self.span.clean(cx),
def_id: def_id.to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
@ -2219,7 +2219,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
vec![Item {
name: None,
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 },
visibility: self.vis.clean(cx),
stability: None,
@ -2284,7 +2284,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
vec![Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
source: self.span.clean(cx),
def_id: DefId::local(CRATE_DEF_INDEX),
visibility: self.vis.clean(cx),
stability: None,
@ -2326,7 +2326,7 @@ impl Clean<Item> for doctree::ForeignItem<'_> {
Item {
name: Some(self.name.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(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
@ -2342,7 +2342,7 @@ impl Clean<Item> for doctree::Macro<'_> {
Item {
name: Some(name.clone()),
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
source: self.span.clean(cx),
visibility: Public,
stability: cx.stability(self.hid).clean(cx),
deprecation: cx.deprecation(self.hid).clean(cx),
@ -2367,7 +2367,7 @@ impl Clean<Item> for doctree::ProcMacro<'_> {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
source: self.span.clean(cx),
visibility: Public,
stability: cx.stability(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 attrs: &'hir [ast::Attribute],
pub fields: &'hir [hir::StructField<'hir>],
pub whence: Span,
pub span: Span,
}
pub struct Union<'hir> {
@ -100,7 +100,7 @@ pub struct Union<'hir> {
pub generics: &'hir hir::Generics<'hir>,
pub attrs: &'hir [ast::Attribute],
pub fields: &'hir [hir::StructField<'hir>],
pub whence: Span,
pub span: Span,
}
pub struct Enum<'hir> {
@ -109,7 +109,7 @@ pub struct Enum<'hir> {
pub generics: &'hir hir::Generics<'hir>,
pub attrs: &'hir [ast::Attribute],
pub id: hir::HirId,
pub whence: Span,
pub span: Span,
pub name: Symbol,
}
@ -118,7 +118,7 @@ pub struct Variant<'hir> {
pub id: hir::HirId,
pub attrs: &'hir [ast::Attribute],
pub def: &'hir hir::VariantData<'hir>,
pub whence: Span,
pub span: Span,
}
pub struct Function<'hir> {
@ -128,7 +128,7 @@ pub struct Function<'hir> {
pub name: Symbol,
pub vis: &'hir hir::Visibility<'hir>,
pub header: hir::FnHeader,
pub whence: Span,
pub span: Span,
pub generics: &'hir hir::Generics<'hir>,
pub body: hir::BodyId,
}
@ -139,7 +139,7 @@ pub struct Typedef<'hir> {
pub name: Symbol,
pub id: hir::HirId,
pub attrs: &'hir [ast::Attribute],
pub whence: Span,
pub span: Span,
pub vis: &'hir hir::Visibility<'hir>,
}
@ -148,7 +148,7 @@ pub struct OpaqueTy<'hir> {
pub name: Symbol,
pub id: hir::HirId,
pub attrs: &'hir [ast::Attribute],
pub whence: Span,
pub span: Span,
pub vis: &'hir hir::Visibility<'hir>,
}
@ -161,7 +161,7 @@ pub struct Static<'hir> {
pub attrs: &'hir [ast::Attribute],
pub vis: &'hir hir::Visibility<'hir>,
pub id: hir::HirId,
pub whence: Span,
pub span: Span,
}
pub struct Constant<'hir> {
@ -171,7 +171,7 @@ pub struct Constant<'hir> {
pub attrs: &'hir [ast::Attribute],
pub vis: &'hir hir::Visibility<'hir>,
pub id: hir::HirId,
pub whence: Span,
pub span: Span,
}
pub struct Trait<'hir> {
@ -183,7 +183,7 @@ pub struct Trait<'hir> {
pub bounds: &'hir [hir::GenericBound<'hir>],
pub attrs: &'hir [ast::Attribute],
pub id: hir::HirId,
pub whence: Span,
pub span: Span,
pub vis: &'hir hir::Visibility<'hir>,
}
@ -193,7 +193,7 @@ pub struct TraitAlias<'hir> {
pub bounds: &'hir [hir::GenericBound<'hir>],
pub attrs: &'hir [ast::Attribute],
pub id: hir::HirId,
pub whence: Span,
pub span: Span,
pub vis: &'hir hir::Visibility<'hir>,
}
@ -208,7 +208,7 @@ pub struct Impl<'hir> {
pub for_: &'hir hir::Ty<'hir>,
pub items: Vec<&'hir hir::ImplItem<'hir>>,
pub attrs: &'hir [ast::Attribute],
pub whence: Span,
pub span: Span,
pub vis: &'hir hir::Visibility<'hir>,
pub id: hir::HirId,
}
@ -219,7 +219,7 @@ pub struct ForeignItem<'hir> {
pub name: Symbol,
pub kind: &'hir hir::ForeignItemKind<'hir>,
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
@ -229,7 +229,7 @@ pub struct Macro<'hir> {
pub hid: hir::HirId,
pub def_id: hir::def_id::DefId,
pub attrs: &'hir [ast::Attribute],
pub whence: Span,
pub span: Span,
pub matchers: Vec<Span>,
pub imported_from: Option<Symbol>,
}
@ -240,7 +240,7 @@ pub struct ExternCrate<'hir> {
pub path: Option<String>,
pub vis: &'hir hir::Visibility<'hir>,
pub attrs: &'hir [ast::Attribute],
pub whence: Span,
pub span: Span,
}
pub struct Import<'hir> {
@ -250,7 +250,7 @@ pub struct Import<'hir> {
pub attrs: &'hir [ast::Attribute],
pub path: &'hir hir::Path<'hir>,
pub glob: bool,
pub whence: Span,
pub span: Span,
}
pub struct ProcMacro<'hir> {
@ -259,7 +259,7 @@ pub struct ProcMacro<'hir> {
pub kind: MacroKind,
pub helpers: Vec<Symbol>,
pub attrs: &'hir [ast::Attribute],
pub whence: Span,
pub span: Span,
}
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,
generics,
fields: sd.fields(),
whence: item.span,
span: item.span,
}
}
@ -120,7 +120,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
attrs: &item.attrs,
generics,
fields: sd.fields(),
whence: item.span,
span: item.span,
}
}
@ -142,14 +142,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
id: v.id,
attrs: &v.attrs,
def: &v.data,
whence: v.span,
span: v.span,
})
.collect(),
vis: &it.vis,
generics,
attrs: &it.attrs,
id: it.hir_id,
whence: it.span,
span: it.span,
}
}
@ -208,7 +208,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
kind,
helpers,
attrs: &item.attrs,
whence: item.span,
span: item.span,
});
}
None => {
@ -218,7 +218,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
attrs: &item.attrs,
decl,
name,
whence: item.span,
span: item.span,
generics,
header,
body,
@ -402,7 +402,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
path: orig_name.map(|x| x.to_string()),
vis: &item.vis,
attrs: &item.attrs,
whence: item.span,
span: item.span,
})
}
hir::ItemKind::Use(_, hir::UseKind::ListStem) => {}
@ -444,7 +444,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
attrs: &item.attrs,
path,
glob: is_glob,
whence: item.span,
span: item.span,
});
}
hir::ItemKind::Mod(ref m) => {
@ -476,7 +476,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
name: ident.name,
id: item.hir_id,
attrs: &item.attrs,
whence: item.span,
span: item.span,
vis: &item.vis,
};
om.typedefs.push(t);
@ -487,7 +487,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
name: ident.name,
id: item.hir_id,
attrs: &item.attrs,
whence: item.span,
span: item.span,
vis: &item.vis,
};
om.opaque_tys.push(t);
@ -500,7 +500,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
id: item.hir_id,
name: ident.name,
attrs: &item.attrs,
whence: item.span,
span: item.span,
vis: &item.vis,
};
om.statics.push(s);
@ -515,7 +515,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
id: item.hir_id,
name: ident.name,
attrs: &item.attrs,
whence: item.span,
span: item.span,
vis: &item.vis,
};
om.constants.push(s);
@ -532,7 +532,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
bounds,
id: item.hir_id,
attrs: &item.attrs,
whence: item.span,
span: item.span,
vis: &item.vis,
};
om.traits.push(t);
@ -544,7 +544,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
bounds,
id: item.hir_id,
attrs: &item.attrs,
whence: item.span,
span: item.span,
vis: &item.vis,
};
om.trait_aliases.push(t);
@ -577,7 +577,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
items,
attrs: &item.attrs,
id: item.hir_id,
whence: item.span,
span: item.span,
vis: &item.vis,
};
om.impls.push(i);
@ -603,7 +603,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
kind: &item.kind,
vis: &item.vis,
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(),
attrs: &def.attrs,
name: renamed.unwrap_or(def.ident.name),
whence: def.span,
span: def.span,
matchers,
imported_from: None,
}

View file

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

View file

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

View file

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

View file

@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/uninferred-consts.rs:14:9
|
LL | Foo.foo();
| ^^^
|
= note: cannot infer the value of the const parameter `N`
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `foo`
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() { || {} }
//~^ ERROR function pointers in const fn are unstable
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; }
//~^ 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
= 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
|
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
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= 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]: casting pointers to integers in constant functions is unstable
--> $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 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
const fn foo11_2<T: Send>(t: T) -> T { t }
//~^ 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;
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
= 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
--> $DIR/min_const_fn.rs:90:27
--> $DIR/min_const_fn.rs:82:27
|
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
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 }
| ^^^
@ -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
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 }
| ^^^^^^^^^^
@ -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
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 } }
| ^^^^^^^^^^
@ -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
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 }
| ^^^^^^^^^^
@ -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
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 } }
| ^^^^^^^^^^
@ -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
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 }
| ^
@ -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
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> {
| ^
@ -183,7 +147,7 @@ LL | impl<T: std::fmt::Debug> Foo<T> {
= help: add `#![feature(const_fn)]` to the crate attributes to enable
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> {
| ^
@ -192,7 +156,7 @@ LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
= help: add `#![feature(const_fn)]` to the crate attributes to enable
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> {
| ^
@ -201,7 +165,7 @@ LL | impl<T: Sync + Sized> Foo<T> {
= help: add `#![feature(const_fn)]` to the crate attributes to enable
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>) {}
| ^^^^^^^^^^^^^^^^^^^^
@ -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
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) {}
| ^^^^^^^^^^^^^^^^^^^^
@ -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
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) {}
| ^^
@ -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
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 { &() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -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
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 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -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
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()) {}
| ^^
@ -255,7 +219,7 @@ LL | const fn no_fn_ptrs(_x: fn()) {}
= help: add `#![feature(const_fn)]` to the crate attributes to enable
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 }
| ^^^^
@ -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
= 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.
For more information about an error, try `rustc --explain E0013`.

View file

@ -3,7 +3,7 @@
we're apparently really bad at it",
issue = "none")]
#![feature(const_fn, foo, foo2)]
#![feature(const_fn, const_fn_floating_point_arithmetic, foo, foo2)]
#![feature(staged_api)]
#[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")]
#[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 }
//~^ 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
#[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
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
|
LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }

View file

@ -3,7 +3,7 @@
we're apparently really bad at it",
issue = "none")]
#![feature(const_fn, foo, foo2)]
#![feature(const_fn, const_fn_floating_point_arithmetic, foo, foo2)]
#![feature(staged_api)]
#[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")]
// conformity is required, even with `const_fn` feature gate
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
#[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
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
|
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"
[dependencies.mdbook]
version = "0.4.0"
version = "0.4.3"
default-features = false
features = ["search"]