crate use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
crate use region_name::{RegionName, RegionNameSource};
crate use rustc_const_eval::util::CallKind;
+use rustc_middle::mir::tcx::PlaceTy;
pub(super) struct IncludingDowncast(pub(super) bool);
/// End-user visible description of the `field`nth field of `base`
fn describe_field(&self, place: PlaceRef<'tcx>, field: Field) -> String {
- // FIXME Place2 Make this work iteratively
- match place {
- PlaceRef { local, projection: [] } => {
- let local = &self.body.local_decls[local];
- self.describe_field_from_ty(local.ty, field, None)
- }
+ let place_ty = match place {
+ PlaceRef { local, projection: [] } => PlaceTy::from_ty(self.body.local_decls[local].ty),
PlaceRef { local, projection: [proj_base @ .., elem] } => match elem {
- ProjectionElem::Deref => {
- self.describe_field(PlaceRef { local, projection: proj_base }, field)
- }
- ProjectionElem::Downcast(_, variant_index) => {
- let base_ty = place.ty(self.body, self.infcx.tcx).ty;
- self.describe_field_from_ty(base_ty, field, Some(*variant_index))
- }
- ProjectionElem::Field(_, field_type) => {
- self.describe_field_from_ty(*field_type, field, None)
- }
- ProjectionElem::Index(..)
+ ProjectionElem::Deref
+ | ProjectionElem::Index(..)
| ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Subslice { .. } => {
- self.describe_field(PlaceRef { local, projection: proj_base }, field)
+ PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx)
}
+ ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx),
+ ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type),
},
- }
+ };
+ self.describe_field_from_ty(place_ty.ty, field, place_ty.variant_index)
}
/// End-user visible description of the `field_index`nth field of `ty`
/// instead of a `&DiagnosticBuilder<'a>`. This `forward!` macro makes
/// it easy to declare such methods on the builder.
macro_rules! forward {
- // Forward pattern for &self -> &Self
- (
- $(#[$attrs:meta])*
- pub fn $n:ident(&self, $($name:ident: $ty:ty),* $(,)?) -> &Self
- ) => {
- $(#[$attrs])*
- #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")]
- pub fn $n(&self, $($name: $ty),*) -> &Self {
- self.diagnostic.$n($($name),*);
- self
- }
- };
-
// Forward pattern for &mut self -> &mut Self
(
$(#[$attrs:meta])*
/// This is different from a normal transmute because dataflow analysis will treat the box as
/// initialized but its content as uninitialized. Like other pointer casts, this in general
/// affects alias analysis.
- ///
- /// Disallowed after drop elaboration.
ShallowInitBox(Operand<'tcx>, Ty<'tcx>),
}
use rustc_span::Span;
use rustc_target::abi::VariantIdx;
use smallvec::SmallVec;
+use std::borrow::Cow;
use std::cell::Cell;
use std::fmt::{self, Debug};
#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
pub enum UnsafetyViolationDetails {
- CallToUnsafeFunction,
+ CallToUnsafeFunction(Option<DefId>),
UseOfInlineAssembly,
InitializingTypeWith,
CastOfPointerToInt,
AccessToUnionField,
MutationOfLayoutConstrainedField,
BorrowOfLayoutConstrainedField,
- CallToFunctionWith,
+ CallToFunctionWith(DefId),
}
impl UnsafetyViolationDetails {
- pub fn description_and_note(&self) -> (&'static str, &'static str) {
+ pub fn simple_description(&self) -> &'static str {
+ use UnsafetyViolationDetails::*;
+
+ match self {
+ CallToUnsafeFunction(..) => "call to unsafe function",
+ UseOfInlineAssembly => "use of inline assembly",
+ InitializingTypeWith => "initializing type with `rustc_layout_scalar_valid_range` attr",
+ CastOfPointerToInt => "cast of pointer to int",
+ UseOfMutableStatic => "use of mutable static",
+ UseOfExternStatic => "use of extern static",
+ DerefOfRawPointer => "dereference of raw pointer",
+ AssignToDroppingUnionField => "assignment to union field that might need dropping",
+ AccessToUnionField => "access to union field",
+ MutationOfLayoutConstrainedField => "mutation of layout constrained field",
+ BorrowOfLayoutConstrainedField => {
+ "borrow of layout constrained field with interior mutability"
+ }
+ CallToFunctionWith(..) => "call to function with `#[target_feature]`",
+ }
+ }
+
+ pub fn description_and_note(&self, tcx: TyCtxt<'_>) -> (Cow<'static, str>, &'static str) {
use UnsafetyViolationDetails::*;
match self {
- CallToUnsafeFunction => (
- "call to unsafe function",
+ CallToUnsafeFunction(did) => (
+ if let Some(did) = did {
+ Cow::from(format!("call to unsafe function `{}`", tcx.def_path_str(*did)))
+ } else {
+ Cow::Borrowed(self.simple_description())
+ },
"consult the function's documentation for information on how to avoid undefined \
behavior",
),
UseOfInlineAssembly => (
- "use of inline assembly",
+ Cow::Borrowed(self.simple_description()),
"inline assembly is entirely unchecked and can cause undefined behavior",
),
InitializingTypeWith => (
- "initializing type with `rustc_layout_scalar_valid_range` attr",
+ Cow::Borrowed(self.simple_description()),
"initializing a layout restricted type's field with a value outside the valid \
range is undefined behavior",
),
- CastOfPointerToInt => {
- ("cast of pointer to int", "casting pointers to integers in constants")
- }
+ CastOfPointerToInt => (
+ Cow::Borrowed(self.simple_description()),
+ "casting pointers to integers in constants",
+ ),
UseOfMutableStatic => (
- "use of mutable static",
+ Cow::Borrowed(self.simple_description()),
"mutable statics can be mutated by multiple threads: aliasing violations or data \
races will cause undefined behavior",
),
UseOfExternStatic => (
- "use of extern static",
+ Cow::Borrowed(self.simple_description()),
"extern statics are not controlled by the Rust type system: invalid data, \
aliasing violations or data races will cause undefined behavior",
),
DerefOfRawPointer => (
- "dereference of raw pointer",
+ Cow::Borrowed(self.simple_description()),
"raw pointers may be null, dangling or unaligned; they can violate aliasing rules \
and cause data races: all of these are undefined behavior",
),
AssignToDroppingUnionField => (
- "assignment to union field that might need dropping",
+ Cow::Borrowed(self.simple_description()),
"the previous content of the field will be dropped, which causes undefined \
behavior if the field was not properly initialized",
),
AccessToUnionField => (
- "access to union field",
+ Cow::Borrowed(self.simple_description()),
"the field may not be properly initialized: using uninitialized data will cause \
undefined behavior",
),
MutationOfLayoutConstrainedField => (
- "mutation of layout constrained field",
+ Cow::Borrowed(self.simple_description()),
"mutating layout constrained fields cannot statically be checked for valid values",
),
BorrowOfLayoutConstrainedField => (
- "borrow of layout constrained field with interior mutability",
+ Cow::Borrowed(self.simple_description()),
"references to fields of layout constrained fields lose the constraints. Coupled \
with interior mutability, the field can be changed to invalid values",
),
- CallToFunctionWith => (
- "call to function with `#[target_feature]`",
+ CallToFunctionWith(did) => (
+ Cow::from(format!(
+ "call to function `{}` with `#[target_feature]`",
+ tcx.def_path_str(*did)
+ )),
"can only be called if the required target features are available",
),
}
}
}
};
- ([$ignore:ident $(, $attrs:ident)*]$args:tt) => {
- impl_arena_allocatable_decoder!([$($attrs),*]$args);
- };
}
macro_rules! impl_arena_allocatable_decoders {
pointee_info
}
+
+ fn is_adt(this: TyAndLayout<'tcx>) -> bool {
+ matches!(this.ty.kind(), ty::Adt(..))
+ }
+
+ fn is_never(this: TyAndLayout<'tcx>) -> bool {
+ this.ty.kind() == &ty::Never
+ }
+
+ fn is_tuple(this: TyAndLayout<'tcx>) -> bool {
+ matches!(this.ty.kind(), ty::Tuple(..))
+ }
+
+ fn is_unit(this: TyAndLayout<'tcx>) -> bool {
+ matches!(this.ty.kind(), ty::Tuple(list) if list.len() == 0)
+ }
}
impl<'tcx> ty::Instance<'tcx> {
static EMPTY_SLICE: InOrder<usize, MaxAlign> = InOrder(0, MaxAlign);
unsafe { &*(&EMPTY_SLICE as *const _ as *const List<T>) }
}
+
+ pub fn len(&self) -> usize {
+ self.len
+ }
}
impl<T: Copy> List<T> {
use rustc_span::symbol::Symbol;
use rustc_span::Span;
+use std::borrow::Cow;
use std::ops::Bound;
struct UnsafetyVisitor<'a, 'tcx> {
}
fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) {
- let (description, note) = kind.description_and_note();
let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed();
match self.safety_context {
SafetyContext::BuiltinUnsafeBlock => {}
}
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
SafetyContext::UnsafeFn => {
+ let (description, note) = kind.description_and_note(self.tcx);
// unsafe_op_in_unsafe_fn is disallowed
self.tcx.struct_span_lint_hir(
UNSAFE_OP_IN_UNSAFE_FN,
"{} is unsafe and requires unsafe block (error E0133)",
description,
))
- .span_label(span, description)
+ .span_label(span, kind.simple_description())
.note(note)
.emit();
},
)
}
SafetyContext::Safe => {
+ let (description, note) = kind.description_and_note(self.tcx);
let fn_sugg = if unsafe_op_in_unsafe_fn_allowed { " function or" } else { "" };
struct_span_err!(
self.tcx.sess,
description,
fn_sugg,
)
- .span_label(span, description)
+ .span_label(span, kind.simple_description())
.note(note)
.emit();
}
}
ExprKind::Call { fun, ty: _, args: _, from_hir_call: _, fn_span: _ } => {
if self.thir[fun].ty.fn_sig(self.tcx).unsafety() == hir::Unsafety::Unsafe {
- self.requires_unsafe(expr.span, CallToUnsafeFunction);
+ let func_id = if let ty::FnDef(func_id, _) = self.thir[fun].ty.kind() {
+ Some(*func_id)
+ } else {
+ None
+ };
+ self.requires_unsafe(expr.span, CallToUnsafeFunction(func_id));
} else if let &ty::FnDef(func_did, _) = self.thir[fun].ty.kind() {
// If the called function has target features the calling function hasn't,
// the call requires `unsafe`. Don't check this on wasm
.iter()
.all(|feature| self.body_target_features.contains(feature))
{
- self.requires_unsafe(expr.span, CallToFunctionWith);
+ self.requires_unsafe(expr.span, CallToFunctionWith(func_did));
}
}
}
#[derive(Clone, Copy, PartialEq)]
enum UnsafeOpKind {
- CallToUnsafeFunction,
+ CallToUnsafeFunction(Option<DefId>),
UseOfInlineAssembly,
InitializingTypeWith,
UseOfMutableStatic,
AccessToUnionField,
MutationOfLayoutConstrainedField,
BorrowOfLayoutConstrainedField,
- CallToFunctionWith,
+ CallToFunctionWith(DefId),
}
use UnsafeOpKind::*;
impl UnsafeOpKind {
- pub fn description_and_note(&self) -> (&'static str, &'static str) {
+ pub fn simple_description(&self) -> &'static str {
match self {
- CallToUnsafeFunction => (
- "call to unsafe function",
+ CallToUnsafeFunction(..) => "call to unsafe function",
+ UseOfInlineAssembly => "use of inline assembly",
+ InitializingTypeWith => "initializing type with `rustc_layout_scalar_valid_range` attr",
+ UseOfMutableStatic => "use of mutable static",
+ UseOfExternStatic => "use of extern static",
+ DerefOfRawPointer => "dereference of raw pointer",
+ AssignToDroppingUnionField => "assignment to union field that might need dropping",
+ AccessToUnionField => "access to union field",
+ MutationOfLayoutConstrainedField => "mutation of layout constrained field",
+ BorrowOfLayoutConstrainedField => {
+ "borrow of layout constrained field with interior mutability"
+ }
+ CallToFunctionWith(..) => "call to function with `#[target_feature]`",
+ }
+ }
+
+ pub fn description_and_note(&self, tcx: TyCtxt<'_>) -> (Cow<'static, str>, &'static str) {
+ match self {
+ CallToUnsafeFunction(did) => (
+ if let Some(did) = did {
+ Cow::from(format!("call to unsafe function `{}`", tcx.def_path_str(*did)))
+ } else {
+ Cow::Borrowed(self.simple_description())
+ },
"consult the function's documentation for information on how to avoid undefined \
behavior",
),
UseOfInlineAssembly => (
- "use of inline assembly",
+ Cow::Borrowed(self.simple_description()),
"inline assembly is entirely unchecked and can cause undefined behavior",
),
InitializingTypeWith => (
- "initializing type with `rustc_layout_scalar_valid_range` attr",
+ Cow::Borrowed(self.simple_description()),
"initializing a layout restricted type's field with a value outside the valid \
range is undefined behavior",
),
UseOfMutableStatic => (
- "use of mutable static",
+ Cow::Borrowed(self.simple_description()),
"mutable statics can be mutated by multiple threads: aliasing violations or data \
races will cause undefined behavior",
),
UseOfExternStatic => (
- "use of extern static",
+ Cow::Borrowed(self.simple_description()),
"extern statics are not controlled by the Rust type system: invalid data, \
aliasing violations or data races will cause undefined behavior",
),
DerefOfRawPointer => (
- "dereference of raw pointer",
+ Cow::Borrowed(self.simple_description()),
"raw pointers may be null, dangling or unaligned; they can violate aliasing rules \
and cause data races: all of these are undefined behavior",
),
AssignToDroppingUnionField => (
- "assignment to union field that might need dropping",
+ Cow::Borrowed(self.simple_description()),
"the previous content of the field will be dropped, which causes undefined \
behavior if the field was not properly initialized",
),
AccessToUnionField => (
- "access to union field",
+ Cow::Borrowed(self.simple_description()),
"the field may not be properly initialized: using uninitialized data will cause \
undefined behavior",
),
MutationOfLayoutConstrainedField => (
- "mutation of layout constrained field",
+ Cow::Borrowed(self.simple_description()),
"mutating layout constrained fields cannot statically be checked for valid values",
),
BorrowOfLayoutConstrainedField => (
- "borrow of layout constrained field with interior mutability",
+ Cow::Borrowed(self.simple_description()),
"references to fields of layout constrained fields lose the constraints. Coupled \
with interior mutability, the field can be changed to invalid values",
),
- CallToFunctionWith => (
- "call to function with `#[target_feature]`",
+ CallToFunctionWith(did) => (
+ Cow::from(format!(
+ "call to function `{}` with `#[target_feature]`",
+ tcx.def_path_str(*did)
+ )),
"can only be called if the required target features are available",
),
}
TerminatorKind::Call { ref func, .. } => {
let func_ty = func.ty(self.body, self.tcx);
+ let func_id =
+ if let ty::FnDef(func_id, _) = func_ty.kind() { Some(func_id) } else { None };
let sig = func_ty.fn_sig(self.tcx);
if let hir::Unsafety::Unsafe = sig.unsafety() {
self.require_unsafe(
UnsafetyViolationKind::General,
- UnsafetyViolationDetails::CallToUnsafeFunction,
+ UnsafetyViolationDetails::CallToUnsafeFunction(func_id.copied()),
)
}
- if let ty::FnDef(func_id, _) = func_ty.kind() {
+ if let Some(func_id) = func_id {
self.check_target_features(*func_id);
}
}
if !callee_features.iter().all(|feature| self_features.contains(feature)) {
self.require_unsafe(
UnsafetyViolationKind::General,
- UnsafetyViolationDetails::CallToFunctionWith,
+ UnsafetyViolationDetails::CallToFunctionWith(func_did),
)
}
}
let UnsafetyCheckResult { violations, unused_unsafes, .. } = tcx.unsafety_check_result(def_id);
for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() {
- let (description, note) = details.description_and_note();
+ let (description, note) =
+ ty::print::with_no_trimmed_paths!(details.description_and_note(tcx));
// Report an error.
let unsafe_fn_msg =
description,
unsafe_fn_msg,
)
- .span_label(source_info.span, description)
+ .span_label(source_info.span, details.simple_description())
.note(note)
.emit();
}
return Ok(true);
} else if self.look_ahead(0, |t| {
t == &token::CloseDelim(token::Brace)
- || (
- t.can_begin_expr() && t != &token::Semi && t != &token::Pound
- // Avoid triggering with too many trailing `#` in raw string.
- )
+ || (t.can_begin_expr() && t != &token::Semi && t != &token::Pound)
+ // Avoid triggering with too many trailing `#` in raw string.
+ || (sm.is_multiline(
+ self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo())
+ ) && t == &token::Pound)
}) {
// Missing semicolon typo. This is triggered if the next token could either start a
// new statement or is a block close. For example:
}
if self.check_too_many_raw_str_terminators(&mut err) {
- return Err(err);
+ if expected.contains(&TokenType::Token(token::Semi)) && self.eat(&token::Semi) {
+ err.emit();
+ return Ok(true);
+ } else {
+ return Err(err);
+ }
}
if self.prev_token.span == DUMMY_SP {
}
fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool {
+ let sm = self.sess.source_map();
match (&self.prev_token.kind, &self.token.kind) {
(
TokenKind::Literal(Lit {
..
}),
TokenKind::Pound,
- ) => {
+ ) if !sm.is_multiline(
+ self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo()),
+ ) =>
+ {
+ let n_hashes: u8 = *n_hashes;
err.set_primary_message("too many `#` when terminating raw string");
+ let str_span = self.prev_token.span;
+ let mut span = self.token.span;
+ let mut count = 0;
+ while self.token.kind == TokenKind::Pound
+ && !sm.is_multiline(span.shrink_to_hi().until(self.token.span.shrink_to_lo()))
+ {
+ span = span.with_hi(self.token.span.hi());
+ self.bump();
+ count += 1;
+ }
+ err.set_span(span);
err.span_suggestion(
- self.token.span,
- "remove the extra `#`",
+ span,
+ &format!("remove the extra `#`{}", pluralize!(count)),
String::new(),
Applicability::MachineApplicable,
);
- err.note(&format!("the raw string started with {n_hashes} `#`s"));
+ err.span_label(
+ str_span,
+ &format!("this raw string started with {n_hashes} `#`{}", pluralize!(n_hashes)),
+ );
true
}
_ => false,
/// Therefore, the recursion depth is the binary logarithm of the number of
/// tokens to count, and the expanded tree is likewise very small.
macro_rules! count {
- () => (0usize);
($one:tt) => (1usize);
($($pairs:tt $_p:tt)*) => (count!($($pairs)*) << 1usize);
($odd:tt $($rest:tt)*) => (count!($($rest)*) | 1usize);
"sparc" => sparc::compute_abi_info(cx, self),
"sparc64" => sparc64::compute_abi_info(cx, self),
"nvptx" => nvptx::compute_abi_info(self),
- "nvptx64" => nvptx64::compute_abi_info(self),
+ "nvptx64" => {
+ if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::PtxKernel {
+ nvptx64::compute_ptx_kernel_abi_info(cx, self)
+ } else {
+ nvptx64::compute_abi_info(self)
+ }
+ }
"hexagon" => hexagon::compute_abi_info(self),
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
"wasm32" | "wasm64" => {
-// Reference: PTX Writer's Guide to Interoperability
-// https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability
-
-use crate::abi::call::{ArgAbi, FnAbi};
+use crate::abi::call::{ArgAbi, FnAbi, PassMode, Reg, Size, Uniform};
+use crate::abi::{HasDataLayout, TyAbiInterface};
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 {
ret.make_indirect();
- } else {
- ret.extend_integer_width_to(64);
}
}
fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 {
arg.make_indirect();
- } else {
- arg.extend_integer_width_to(64);
+ }
+}
+
+fn classify_arg_kernel<'a, Ty, C>(_cx: &C, arg: &mut ArgAbi<'a, Ty>)
+where
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
+{
+ if matches!(arg.mode, PassMode::Pair(..)) && (arg.layout.is_adt() || arg.layout.is_tuple()) {
+ let align_bytes = arg.layout.align.abi.bytes();
+
+ let unit = match align_bytes {
+ 1 => Reg::i8(),
+ 2 => Reg::i16(),
+ 4 => Reg::i32(),
+ 8 => Reg::i64(),
+ 16 => Reg::i128(),
+ _ => unreachable!("Align is given as power of 2 no larger than 16 bytes"),
+ };
+ arg.cast_to(Uniform { unit, total: Size::from_bytes(2 * align_bytes) });
}
}
classify_arg(arg);
}
}
+
+pub fn compute_ptx_kernel_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+where
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
+{
+ if !fn_abi.ret.layout.is_unit() && !fn_abi.ret.layout.is_never() {
+ panic!("Kernels should not return anything other than () or !");
+ }
+
+ for arg in &mut fn_abi.args {
+ if arg.is_ignore() {
+ continue;
+ }
+ classify_arg_kernel(cx, arg);
+ }
+}
cx: &C,
offset: Size,
) -> Option<PointeeInfo>;
+ fn is_adt(this: TyAndLayout<'a, Self>) -> bool;
+ fn is_never(this: TyAndLayout<'a, Self>) -> bool;
+ fn is_tuple(this: TyAndLayout<'a, Self>) -> bool;
+ fn is_unit(this: TyAndLayout<'a, Self>) -> bool;
}
impl<'a, Ty> TyAndLayout<'a, Ty> {
_ => false,
}
}
+
+ pub fn is_adt<C>(self) -> bool
+ where
+ Ty: TyAbiInterface<'a, C>,
+ {
+ Ty::is_adt(self)
+ }
+
+ pub fn is_never<C>(self) -> bool
+ where
+ Ty: TyAbiInterface<'a, C>,
+ {
+ Ty::is_never(self)
+ }
+
+ pub fn is_tuple<C>(self) -> bool
+ where
+ Ty: TyAbiInterface<'a, C>,
+ {
+ Ty::is_tuple(self)
+ }
+
+ pub fn is_unit<C>(self) -> bool
+ where
+ Ty: TyAbiInterface<'a, C>,
+ {
+ Ty::is_unit(self)
+ }
}
impl<'a, Ty> TyAndLayout<'a, Ty> {
let name = (stringify!($attr)).replace("_", "-");
d.insert(name, self.$attr.to_json());
}};
- ($attr:ident, $key_name:expr) => {{
- let name = $key_name;
- d.insert(name.into(), self.$attr.to_json());
- }};
}
macro_rules! target_option_val {
} else if cat_a == cat_b {
match (a.kind(), b.kind()) {
(ty::Adt(def_a, _), ty::Adt(def_b, _)) => def_a == def_b,
+ (ty::Foreign(def_a), ty::Foreign(def_b)) => def_a == def_b,
// Matching on references results in a lot of unhelpful
// suggestions, so let's just not do that for now.
//
// While we don't allow *arbitrary* coercions here, we *do* allow
// coercions from ! to `expected`.
if ty.is_never() {
- assert!(
- !self.typeck_results.borrow().adjustments().contains_key(expr.hir_id),
- "expression with never type wound up being adjusted"
- );
+ if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
+ self.tcx().sess.delay_span_bug(
+ expr.span,
+ "expression with never type wound up being adjusted",
+ );
+ return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] {
+ target.to_owned()
+ } else {
+ self.tcx().ty_error()
+ };
+ }
+
let adj_ty = self.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::AdjustmentType,
span: expr.span,
// try to add a suggestion in case the field is a nested field of a field of the Adt
if let Some((fields, substs)) = self.get_field_candidates(span, expr_t) {
for candidate_field in fields.iter() {
- if let Some(field_path) = self.check_for_nested_field(
+ if let Some(mut field_path) = self.check_for_nested_field_satisfying(
span,
- field,
+ &|candidate_field, _| candidate_field.ident(self.tcx()) == field,
candidate_field,
substs,
vec![],
self.tcx.parent_module(id).to_def_id(),
) {
+ // field_path includes `field` that we're looking for, so pop it.
+ field_path.pop();
+
let field_path_str = field_path
.iter()
.map(|id| id.name.to_ident_string())
err
}
- fn get_field_candidates(
+ crate fn get_field_candidates(
&self,
span: Span,
base_t: Ty<'tcx>,
/// This method is called after we have encountered a missing field error to recursively
/// search for the field
- fn check_for_nested_field(
+ crate fn check_for_nested_field_satisfying(
&self,
span: Span,
- target_field: Ident,
+ matches: &impl Fn(&ty::FieldDef, Ty<'tcx>) -> bool,
candidate_field: &ty::FieldDef,
subst: SubstsRef<'tcx>,
mut field_path: Vec<Ident>,
id: DefId,
) -> Option<Vec<Ident>> {
debug!(
- "check_for_nested_field(span: {:?}, candidate_field: {:?}, field_path: {:?}",
+ "check_for_nested_field_satisfying(span: {:?}, candidate_field: {:?}, field_path: {:?}",
span, candidate_field, field_path
);
- if candidate_field.ident(self.tcx) == target_field {
- Some(field_path)
- } else if field_path.len() > 3 {
+ if field_path.len() > 3 {
// For compile-time reasons and to avoid infinite recursion we only check for fields
// up to a depth of three
None
} else {
// recursively search fields of `candidate_field` if it's a ty::Adt
-
field_path.push(candidate_field.ident(self.tcx).normalize_to_macros_2_0());
let field_ty = candidate_field.ty(self.tcx, subst);
if let Some((nested_fields, subst)) = self.get_field_candidates(span, field_ty) {
for field in nested_fields.iter() {
- let accessible = field.vis.is_accessible_from(id, self.tcx);
- if accessible {
- let ident = field.ident(self.tcx).normalize_to_macros_2_0();
- if ident == target_field {
+ if field.vis.is_accessible_from(id, self.tcx) {
+ if matches(candidate_field, field_ty) {
return Some(field_path);
- }
- let field_path = field_path.clone();
- if let Some(path) = self.check_for_nested_field(
+ } else if let Some(field_path) = self.check_for_nested_field_satisfying(
span,
- target_field,
+ matches,
field,
subst,
- field_path,
+ field_path.clone(),
id,
) {
- return Some(path);
+ return Some(field_path);
}
}
}
use std::cmp::Ordering;
use std::iter;
-use super::probe::Mode;
+use super::probe::{Mode, ProbeScope};
use super::{CandidateSource, MethodError, NoMatchData};
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
label_span_not_found();
}
+ if let SelfSource::MethodCall(expr) = source
+ && let Some((fields, substs)) = self.get_field_candidates(span, actual)
+ {
+ let call_expr =
+ self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
+ for candidate_field in fields.iter() {
+ if let Some(field_path) = self.check_for_nested_field_satisfying(
+ span,
+ &|_, field_ty| {
+ self.lookup_probe(
+ span,
+ item_name,
+ field_ty,
+ call_expr,
+ ProbeScope::AllTraits,
+ )
+ .is_ok()
+ },
+ candidate_field,
+ substs,
+ vec![],
+ self.tcx.parent_module(expr.hir_id).to_def_id(),
+ ) {
+ let field_path_str = field_path
+ .iter()
+ .map(|id| id.name.to_ident_string())
+ .collect::<Vec<String>>()
+ .join(".");
+ debug!("field_path_str: {:?}", field_path_str);
+
+ err.span_suggestion_verbose(
+ item_name.span.shrink_to_lo(),
+ "one of the expressions' fields has a method of the same name",
+ format!("{field_path_str}."),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
+ }
+
bound_spans.sort();
bound_spans.dedup();
for (span, msg) in bound_spans.into_iter() {
};
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::TyKind::{Adt, Array, Char, FnDef, Never, Ref, Str, Tuple, Uint};
-use rustc_middle::ty::{
- self, suggest_constraining_type_param, Ty, TyCtxt, TypeFoldable, TypeVisitor,
-};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_trait_selection::infer::InferCtxtExt;
+use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt as _;
use rustc_trait_selection::traits::{FulfillmentError, TraitEngine, TraitEngineExt};
use std::ops::ControlFlow;
Err(_) if lhs_ty.references_error() || rhs_ty.references_error() => self.tcx.ty_error(),
Err(errors) => {
let source_map = self.tcx.sess.source_map();
- let (mut err, missing_trait, use_output) = match is_assign {
+ let (mut err, missing_trait, _use_output) = match is_assign {
IsAssign::Yes => {
let mut err = struct_span_err!(
self.tcx.sess,
// concatenation (e.g., "Hello " + "World!"). This means
// we don't want the note in the else clause to be emitted
} else if let [ty] = &visitor.0[..] {
- if let ty::Param(p) = *ty.kind() {
- // Check if the method would be found if the type param wasn't
- // involved. If so, it means that adding a trait bound to the param is
- // enough. Otherwise we do not give the suggestion.
- let mut eraser = TypeParamEraser(self, expr.span);
- let needs_bound = self
- .lookup_op_method(
- eraser.fold_ty(lhs_ty),
- Some(eraser.fold_ty(rhs_ty)),
- Some(rhs_expr),
- Op::Binary(op, is_assign),
- )
- .is_ok();
- if needs_bound {
- suggest_constraining_param(
- self.tcx,
- self.body_id,
+ // Look for a TraitPredicate in the Fulfillment errors,
+ // and use it to generate a suggestion.
+ //
+ // Note that lookup_op_method must be called again but
+ // with a specific rhs_ty instead of a placeholder so
+ // the resulting predicate generates a more specific
+ // suggestion for the user.
+ let errors = self
+ .lookup_op_method(
+ lhs_ty,
+ Some(rhs_ty),
+ Some(rhs_expr),
+ Op::Binary(op, is_assign),
+ )
+ .unwrap_err();
+ let predicates = errors
+ .into_iter()
+ .filter_map(|error| error.obligation.predicate.to_opt_poly_trait_pred())
+ .collect::<Vec<_>>();
+ if !predicates.is_empty() {
+ for pred in predicates {
+ self.infcx.suggest_restricting_param_bound(
&mut err,
- *ty,
- rhs_ty,
- missing_trait,
- p,
- use_output,
+ pred,
+ self.body_id,
);
- } else if *ty != lhs_ty {
- // When we know that a missing bound is responsible, we don't show
- // this note as it is redundant.
- err.note(&format!(
- "the trait `{missing_trait}` is not implemented for `{lhs_ty}`"
- ));
}
- } else {
- bug!("type param visitor stored a non type param: {:?}", ty.kind());
+ } else if *ty != lhs_ty {
+ // When we know that a missing bound is responsible, we don't show
+ // this note as it is redundant.
+ err.note(&format!(
+ "the trait `{missing_trait}` is not implemented for `{lhs_ty}`"
+ ));
}
}
}
ex.span,
format!("cannot apply unary operator `{}`", op.as_str()),
);
- let missing_trait = match op {
- hir::UnOp::Deref => unreachable!("check unary op `-` or `!` only"),
- hir::UnOp::Not => "std::ops::Not",
- hir::UnOp::Neg => "std::ops::Neg",
- };
+
let mut visitor = TypeParamVisitor(vec![]);
visitor.visit_ty(operand_ty);
- if let [ty] = &visitor.0[..] && let ty::Param(p) = *operand_ty.kind() {
- suggest_constraining_param(
- self.tcx,
- self.body_id,
- &mut err,
- *ty,
- operand_ty,
- missing_trait,
- p,
- true,
- );
+ if let [_] = &visitor.0[..] && let ty::Param(_) = *operand_ty.kind() {
+ let predicates = errors
+ .iter()
+ .filter_map(|error| {
+ error.obligation.predicate.clone().to_opt_poly_trait_pred()
+ });
+ for pred in predicates {
+ self.infcx.suggest_restricting_param_bound(
+ &mut err,
+ pred,
+ self.body_id,
+ );
+ }
}
let sp = self.tcx.sess.source_map().start_point(ex.span);
}
}
-fn suggest_constraining_param(
- tcx: TyCtxt<'_>,
- body_id: hir::HirId,
- mut err: &mut Diagnostic,
- lhs_ty: Ty<'_>,
- rhs_ty: Ty<'_>,
- missing_trait: &str,
- p: ty::ParamTy,
- set_output: bool,
-) {
- let hir = tcx.hir();
- let msg = &format!("`{lhs_ty}` might need a bound for `{missing_trait}`");
- // Try to find the def-id and details for the parameter p. We have only the index,
- // so we have to find the enclosing function's def-id, then look through its declared
- // generic parameters to get the declaration.
- let def_id = hir.body_owner_def_id(hir::BodyId { hir_id: body_id });
- let generics = tcx.generics_of(def_id);
- let param_def_id = generics.type_param(&p, tcx).def_id;
- if let Some(generics) = param_def_id
- .as_local()
- .map(|id| hir.local_def_id_to_hir_id(id))
- .and_then(|id| hir.find_by_def_id(hir.get_parent_item(id)))
- .as_ref()
- .and_then(|node| node.generics())
- {
- let output = if set_output { format!("<Output = {rhs_ty}>") } else { String::new() };
- suggest_constraining_type_param(
- tcx,
- generics,
- &mut err,
- &lhs_ty.to_string(),
- &format!("{missing_trait}{output}"),
- None,
- );
- } else {
- let span = tcx.def_span(param_def_id);
- err.span_label(span, msg);
- }
-}
-
struct TypeParamVisitor<'tcx>(Vec<Ty<'tcx>>);
impl<'tcx> TypeVisitor<'tcx> for TypeParamVisitor<'tcx> {
///
/// # Examples
///
- /// Calling `into_owned` on a `Cow::Borrowed` clones the underlying data
- /// and becomes a `Cow::Owned`:
+ /// Calling `into_owned` on a `Cow::Borrowed` returns a clone of the borrowed data:
///
/// ```
/// use std::borrow::Cow;
/// );
/// ```
///
- /// Calling `into_owned` on a `Cow::Owned` is a no-op:
+ /// Calling `into_owned` on a `Cow::Owned` returns the owned data. The data is moved out of the
+ /// `Cow` without being cloned.
///
/// ```
/// use std::borrow::Cow;
/// Returns `true` if the `LinkedList` contains an element equal to the
/// given value.
///
- /// This operation should compute in *O*(*n*) time.
+ /// This operation should compute linearly in *O*(*n*) time.
///
/// # Examples
///
/// Appends an element to the front of the cursor's parent list. The node
/// that the cursor points to is unchanged, even if it is the "ghost" node.
///
- /// This operation should compute in O(1) time.
+ /// This operation should compute in *O*(1) time.
// `push_front` continues to point to "ghost" when it addes a node to mimic
// the behavior of `insert_before` on an empty list.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
/// Appends an element to the back of the cursor's parent list. The node
/// that the cursor points to is unchanged, even if it is the "ghost" node.
///
- /// This operation should compute in O(1) time.
+ /// This operation should compute in *O*(1) time.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn push_back(&mut self, elt: T) {
// Safety: We know that `push_back` does not change the position in
/// unchanged, unless it was pointing to the front element. In that case, it
/// points to the new front element.
///
- /// This operation should compute in O(1) time.
+ /// This operation should compute in *O*(1) time.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn pop_front(&mut self) -> Option<T> {
// We can't check if current is empty, we must check the list directly.
/// unchanged, unless it was pointing to the back element. In that case, it
/// points to the "ghost" element.
///
- /// This operation should compute in O(1) time.
+ /// This operation should compute in *O*(1) time.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn pop_back(&mut self) -> Option<T> {
if self.list.is_empty() {
/// Returns `true` if the deque contains an element equal to the
/// given value.
///
+ /// This operation is *O*(*n*).
+ ///
+ /// Note that if you have a sorted `VecDeque`, [`binary_search`] may be faster.
+ ///
+ /// [`binary_search`]: VecDeque::binary_search
+ ///
/// # Examples
///
/// ```
}
}
- /// Binary searches the sorted deque for a given element.
+ /// Binary searches this `VecDeque` for a given element.
+ /// This behaves similarly to [`contains`] if this `VecDeque` is sorted.
///
/// If the value is found then [`Result::Ok`] is returned, containing the
/// index of the matching element. If there are multiple matches, then any
///
/// See also [`binary_search_by`], [`binary_search_by_key`], and [`partition_point`].
///
+ /// [`contains`]: VecDeque::contains
/// [`binary_search_by`]: VecDeque::binary_search_by
/// [`binary_search_by_key`]: VecDeque::binary_search_by_key
/// [`partition_point`]: VecDeque::partition_point
self.binary_search_by(|e| e.cmp(x))
}
- /// Binary searches the sorted deque with a comparator function.
+ /// Binary searches this `VecDeque` with a comparator function.
+ /// This behaves similarly to [`contains`] if this `VecDeque` is sorted.
///
/// The comparator function should implement an order consistent
/// with the sort order of the deque, returning an order code that
///
/// See also [`binary_search`], [`binary_search_by_key`], and [`partition_point`].
///
+ /// [`contains`]: VecDeque::contains
/// [`binary_search`]: VecDeque::binary_search
/// [`binary_search_by_key`]: VecDeque::binary_search_by_key
/// [`partition_point`]: VecDeque::partition_point
}
}
- /// Binary searches the sorted deque with a key extraction function.
+ /// Binary searches this `VecDeque` with a key extraction function.
+ /// This behaves similarly to [`contains`] if this `VecDeque` is sorted.
///
/// Assumes that the deque is sorted by the key, for instance with
/// [`make_contiguous().sort_by_key()`] using the same key extraction function.
///
/// See also [`binary_search`], [`binary_search_by`], and [`partition_point`].
///
+ /// [`contains`]: VecDeque::contains
/// [`make_contiguous().sort_by_key()`]: VecDeque::make_contiguous
/// [`binary_search`]: VecDeque::binary_search
/// [`binary_search_by`]: VecDeque::binary_search_by
// implements the unary operator "op &T"
// based on "op T" where T is expected to be `Copy`able
macro_rules! forward_ref_unop {
- (impl $imp:ident, $method:ident for $t:ty) => {
- forward_ref_unop!(impl $imp, $method for $t,
- #[stable(feature = "rust1", since = "1.0.0")]);
- };
(impl const $imp:ident, $method:ident for $t:ty) => {
forward_ref_unop!(impl const $imp, $method for $t,
#[stable(feature = "rust1", since = "1.0.0")]);
// implements binary operators "&T op U", "T op &U", "&T op &U"
// based on "T op U" where T and U are expected to be `Copy`able
macro_rules! forward_ref_binop {
- (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
- forward_ref_binop!(impl $imp, $method for $t, $u,
- #[stable(feature = "rust1", since = "1.0.0")]);
- };
(impl const $imp:ident, $method:ident for $t:ty, $u:ty) => {
forward_ref_binop!(impl const $imp, $method for $t, $u,
#[stable(feature = "rust1", since = "1.0.0")]);
}
};
- // match if/else chains lacking a final `else`
- (
- if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
- $(
- else if #[cfg( $e_meta:meta )] { $( $e_tokens:tt )* }
- )*
- ) => {
- cfg_if! {
- @__items () ;
- (( $i_meta ) ( $( $i_tokens )* )) ,
- $(
- (( $e_meta ) ( $( $e_tokens )* )) ,
- )*
- }
- };
-
// Internal and recursive macro to emit all the items
//
// Collects all the previous cfgs in a list at the beginning, so they can be
}
}
+#[stable(feature = "assertunwindsafe_default", since = "1.62.0")]
+impl<T: Default> Default for AssertUnwindSafe<T> {
+ fn default() -> Self {
+ Self(Default::default())
+ }
+}
+
#[stable(feature = "futures_api", since = "1.36.0")]
impl<F: Future> Future for AssertUnwindSafe<F> {
type Output = F::Output;
/// Returns `true` if the slice contains an element with the given value.
///
+ /// This operation is *O*(*n*).
+ ///
+ /// Note that if you have a sorted slice, [`binary_search`] may be faster.
+ ///
+ /// [`binary_search`]: slice::binary_search
+ ///
/// # Examples
///
/// ```
None
}
- /// Binary searches this sorted slice for a given element.
+ /// Binary searches this slice for a given element.
+ /// This behaves similary to [`contains`] if this slice is sorted.
///
/// If the value is found then [`Result::Ok`] is returned, containing the
/// index of the matching element. If there are multiple matches, then any
///
/// See also [`binary_search_by`], [`binary_search_by_key`], and [`partition_point`].
///
+ /// [`contains`]: slice::contains
/// [`binary_search_by`]: slice::binary_search_by
/// [`binary_search_by_key`]: slice::binary_search_by_key
/// [`partition_point`]: slice::partition_point
self.binary_search_by(|p| p.cmp(x))
}
- /// Binary searches this sorted slice with a comparator function.
+ /// Binary searches this slice with a comparator function.
+ /// This behaves similarly to [`contains`] if this slice is sorted.
///
/// The comparator function should implement an order consistent
/// with the sort order of the underlying slice, returning an
///
/// See also [`binary_search`], [`binary_search_by_key`], and [`partition_point`].
///
+ /// [`contains`]: slice::contains
/// [`binary_search`]: slice::binary_search
/// [`binary_search_by_key`]: slice::binary_search_by_key
/// [`partition_point`]: slice::partition_point
Err(left)
}
- /// Binary searches this sorted slice with a key extraction function.
+ /// Binary searches this slice with a key extraction function.
+ /// This behaves similarly to [`contains`] if this slice is sorted.
///
/// Assumes that the slice is sorted by the key, for instance with
/// [`sort_by_key`] using the same key extraction function.
///
/// See also [`binary_search`], [`binary_search_by`], and [`partition_point`].
///
+ /// [`contains`]: slice::contains
/// [`sort_by_key`]: slice::sort_by_key
/// [`binary_search`]: slice::binary_search
/// [`binary_search_by`]: slice::binary_search_by
}
macro_rules! test_op {
- ($fn_name:ident, $op:ident::$method:ident($lhs:literal, $rhs:literal), $result:literal, $($t:ty),+) => {
- #[test]
- fn $fn_name() {
- impls_defined!($op, $method($lhs, $rhs), $result, $($t),+);
- }
- };
- ($fn_name:ident, $op:ident::$method:ident(&mut $lhs:literal, $rhs:literal), $result:literal, $($t:ty),+) => {
- #[test]
- fn $fn_name() {
- impls_defined!($op, $method(&mut $lhs, $rhs), $result, $($t),+);
- }
- };
($fn_name:ident, $op:ident::$method:ident($lhs:literal), $result:literal, $($t:ty),+) => {
#[test]
fn $fn_name() {
({$($t:tt)*}) => { Group::new(Delimiter::Brace, quote!($($t)*)) };
(,) => { Punct::new(',', Spacing::Alone) };
(.) => { Punct::new('.', Spacing::Alone) };
- (:) => { Punct::new(':', Spacing::Alone) };
(;) => { Punct::new(';', Spacing::Alone) };
(!) => { Punct::new('!', Spacing::Alone) };
(<) => { Punct::new('<', Spacing::Alone) };
static FILES_UNVERSIONED: Lazy<FxHashMap<&str, &[u8]>> = Lazy::new(|| {
map! {
- "FiraSans-Regular.woff2" => static_files::fira_sans::REGULAR2,
- "FiraSans-Medium.woff2" => static_files::fira_sans::MEDIUM2,
- "FiraSans-Regular.woff" => static_files::fira_sans::REGULAR,
- "FiraSans-Medium.woff" => static_files::fira_sans::MEDIUM,
+ "FiraSans-Regular.woff2" => static_files::fira_sans::REGULAR,
+ "FiraSans-Medium.woff2" => static_files::fira_sans::MEDIUM,
"FiraSans-LICENSE.txt" => static_files::fira_sans::LICENSE,
- "SourceSerif4-Regular.ttf.woff2" => static_files::source_serif_4::REGULAR2,
- "SourceSerif4-Bold.ttf.woff2" => static_files::source_serif_4::BOLD2,
- "SourceSerif4-It.ttf.woff2" => static_files::source_serif_4::ITALIC2,
- "SourceSerif4-Regular.ttf.woff" => static_files::source_serif_4::REGULAR,
- "SourceSerif4-Bold.ttf.woff" => static_files::source_serif_4::BOLD,
- "SourceSerif4-It.ttf.woff" => static_files::source_serif_4::ITALIC,
+ "SourceSerif4-Regular.ttf.woff2" => static_files::source_serif_4::REGULAR,
+ "SourceSerif4-Bold.ttf.woff2" => static_files::source_serif_4::BOLD,
+ "SourceSerif4-It.ttf.woff2" => static_files::source_serif_4::ITALIC,
"SourceSerif4-LICENSE.md" => static_files::source_serif_4::LICENSE,
- "SourceCodePro-Regular.ttf.woff2" => static_files::source_code_pro::REGULAR2,
- "SourceCodePro-Semibold.ttf.woff2" => static_files::source_code_pro::SEMIBOLD2,
- "SourceCodePro-It.ttf.woff2" => static_files::source_code_pro::ITALIC2,
- "SourceCodePro-Regular.ttf.woff" => static_files::source_code_pro::REGULAR,
- "SourceCodePro-Semibold.ttf.woff" => static_files::source_code_pro::SEMIBOLD,
- "SourceCodePro-It.ttf.woff" => static_files::source_code_pro::ITALIC,
+ "SourceCodePro-Regular.ttf.woff2" => static_files::source_code_pro::REGULAR,
+ "SourceCodePro-Semibold.ttf.woff2" => static_files::source_code_pro::SEMIBOLD,
+ "SourceCodePro-It.ttf.woff2" => static_files::source_code_pro::ITALIC,
"SourceCodePro-LICENSE.txt" => static_files::source_code_pro::LICENSE,
- "NanumBarunGothic.ttf.woff2" => static_files::nanum_barun_gothic::REGULAR2,
- "NanumBarunGothic.ttf.woff" => static_files::nanum_barun_gothic::REGULAR,
+ "NanumBarunGothic.ttf.woff2" => static_files::nanum_barun_gothic::REGULAR,
"NanumBarunGothic-LICENSE.txt" => static_files::nanum_barun_gothic::LICENSE,
"LICENSE-MIT.txt" => static_files::LICENSE_MIT,
"LICENSE-APACHE.txt" => static_files::LICENSE_APACHE,
file applies only to those resources. The following third party resources are
included, and carry their own copyright notices and license terms:
-* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2,
- FiraSans-Regular.woff, FiraSans-Medium.woff):
+* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2):
Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
with Reserved Font Name Fira Sans.
Licensed under the MIT license (see LICENSE-MIT.txt).
* Source Code Pro (SourceCodePro-Regular.ttf.woff2,
- SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2,
- SourceCodePro-Regular.ttf.woff, SourceCodePro-Semibold.ttf.woff,
- SourceCodePro-It.ttf.woff):
+ SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2):
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/),
with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark
See SourceCodePro-LICENSE.txt.
* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2,
- SourceSerif4-It.ttf.woff2, SourceSerif4-Regular.ttf.woff,
- SourceSerif4-Bold.ttf.woff, SourceSerif4-It.ttf.woff):
+ SourceSerif4-It.ttf.woff2):
Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name
'Source'. All Rights Reserved. Source is a trademark of Adobe in the United
font-style: normal;
font-weight: 400;
src: local('Fira Sans'),
- url("FiraSans-Regular.woff2") format("woff2"),
- url("FiraSans-Regular.woff") format('woff');
+ url("FiraSans-Regular.woff2") format("woff2");
font-display: swap;
}
@font-face {
font-style: normal;
font-weight: 500;
src: local('Fira Sans Medium'),
- url("FiraSans-Medium.woff2") format("woff2"),
- url("FiraSans-Medium.woff") format('woff');
+ url("FiraSans-Medium.woff2") format("woff2");
font-display: swap;
}
font-style: normal;
font-weight: 400;
src: local('Source Serif 4'),
- url("SourceSerif4-Regular.ttf.woff2") format("woff2"),
- url("SourceSerif4-Regular.ttf.woff") format("woff");
+ url("SourceSerif4-Regular.ttf.woff2") format("woff2");
font-display: swap;
}
@font-face {
font-style: italic;
font-weight: 400;
src: local('Source Serif 4 Italic'),
- url("SourceSerif4-It.ttf.woff2") format("woff2"),
- url("SourceSerif4-It.ttf.woff") format("woff");
+ url("SourceSerif4-It.ttf.woff2") format("woff2");
font-display: swap;
}
@font-face {
font-style: normal;
font-weight: 700;
src: local('Source Serif 4 Bold'),
- url("SourceSerif4-Bold.ttf.woff2") format("woff2"),
- url("SourceSerif4-Bold.ttf.woff") format("woff");
+ url("SourceSerif4-Bold.ttf.woff2") format("woff2");
font-display: swap;
}
font-weight: 400;
/* Avoid using locally installed font because bad versions are in circulation:
* see https://github.com/rust-lang/rust/issues/24355 */
- src: url("SourceCodePro-Regular.ttf.woff2") format("woff2"),
- url("SourceCodePro-Regular.ttf.woff") format("woff");
+ src: url("SourceCodePro-Regular.ttf.woff2") format("woff2");
font-display: swap;
}
@font-face {
font-family: 'Source Code Pro';
font-style: italic;
font-weight: 400;
- src: url("SourceCodePro-It.ttf.woff2") format("woff2"),
- url("SourceCodePro-It.ttf.woff") format("woff");
+ src: url("SourceCodePro-It.ttf.woff2") format("woff2");
font-display: swap;
}
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 600;
- src: url("SourceCodePro-Semibold.ttf.woff2") format("woff2"),
- url("SourceCodePro-Semibold.ttf.woff") format("woff");
+ src: url("SourceCodePro-Semibold.ttf.woff2") format("woff2");
font-display: swap;
}
/* Avoid using legacy CJK serif fonts in Windows like Batang. */
@font-face {
font-family: 'NanumBarunGothic';
- src: url("NanumBarunGothic.ttf.woff2") format("woff2"),
- url("NanumBarunGothic.ttf.woff") format("woff");
+ src: url("NanumBarunGothic.ttf.woff2") format("woff2");
font-display: swap;
unicode-range: U+AC00-D7AF, U+1100-11FF, U+3130-318F, U+A960-A97F, U+D7B0-D7FF;
}
+/* eslint-env es6 */
+/* eslint no-var: "error" */
+/* eslint prefer-const: "error" */
/* global addClass, getNakedUrl, getSettingValue, hasOwnPropertyRustdoc, initSearch, onEach */
/* global onEachLazy, removeClass, searchState, hasClass */
(function() {
// This mapping table should match the discriminants of
// `rustdoc::formats::item_type::ItemType` type in Rust.
-var itemTypes = [
+const itemTypes = [
"mod",
"externcrate",
"import",
];
// used for special search precedence
-var TY_PRIMITIVE = itemTypes.indexOf("primitive");
-var TY_KEYWORD = itemTypes.indexOf("keyword");
+const TY_PRIMITIVE = itemTypes.indexOf("primitive");
+const TY_KEYWORD = itemTypes.indexOf("keyword");
// In the search display, allows to switch between tabs.
function printTab(nb) {
if (nb === 0 || nb === 1 || nb === 2) {
searchState.currentTab = nb;
}
- var nb_copy = nb;
+ let nb_copy = nb;
onEachLazy(document.getElementById("titles").childNodes, function(elem) {
if (nb_copy === 0) {
addClass(elem, "selected");
* This code is an unmodified version of the code written by Marco de Wit
* and was found at https://stackoverflow.com/a/18514751/745719
*/
-var levenshtein_row2 = [];
+const levenshtein_row2 = [];
function levenshtein(s1, s2) {
if (s1 === s2) {
return 0;
}
- var s1_len = s1.length, s2_len = s2.length;
+ const s1_len = s1.length, s2_len = s2.length;
if (s1_len && s2_len) {
- var i1 = 0, i2 = 0, a, b, c, c2, row = levenshtein_row2;
+ let i1 = 0, i2 = 0, a, b, c, c2;
+ const row = levenshtein_row2;
while (i1 < s1_len) {
row[i1] = ++i1;
}
}
window.initSearch = function(rawSearchIndex) {
- var MAX_LEV_DISTANCE = 3;
- var MAX_RESULTS = 200;
- var GENERICS_DATA = 2;
- var NAME = 0;
- var INPUTS_DATA = 0;
- var OUTPUT_DATA = 1;
- var NO_TYPE_FILTER = -1;
+ const MAX_LEV_DISTANCE = 3;
+ const MAX_RESULTS = 200;
+ const GENERICS_DATA = 2;
+ const NAME = 0;
+ const INPUTS_DATA = 0;
+ const OUTPUT_DATA = 1;
+ const NO_TYPE_FILTER = -1;
/**
* @type {Array<Row>}
*/
- var searchIndex;
+ let searchIndex;
/**
* @type {Array<string>}
*/
- var searchWords;
- var currentResults;
- var ALIASES = {};
- var params = searchState.getQueryStringParams();
+ let searchWords = [];
+ let currentResults;
+ const ALIASES = {};
+ const params = searchState.getQueryStringParams();
// Populate search bar with query string search term when provided,
// but only if the input bar is empty. This avoid the obnoxious issue
}
function itemTypeFromName(typename) {
- for (var i = 0, len = itemTypes.length; i < len; ++i) {
+ for (let i = 0, len = itemTypes.length; i < len; ++i) {
if (itemTypes[i] === typename) {
return i;
}
throw new Error("Cannot use literal search when there is more than one element");
}
parserState.pos += 1;
- var start = parserState.pos;
- var end = getIdentEndPosition(parserState);
+ const start = parserState.pos;
+ const end = getIdentEndPosition(parserState);
if (parserState.pos >= parserState.length) {
throw new Error("Unclosed `\"`");
} else if (parserState.userQuery[end] !== "\"") {
if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) {
throw new Error("You cannot have more than one element if you use quotes");
}
- var pathSegments = name.split("::");
+ const pathSegments = name.split("::");
if (pathSegments.length > 1) {
- for (var i = 0, len = pathSegments.length; i < len; ++i) {
- var pathSegment = pathSegments[i];
+ for (let i = 0, len = pathSegments.length; i < len; ++i) {
+ const pathSegment = pathSegments[i];
if (pathSegment.length === 0) {
if (i === 0) {
* @return {integer}
*/
function getIdentEndPosition(parserState) {
- var end = parserState.pos;
+ let end = parserState.pos;
while (parserState.pos < parserState.length) {
- var c = parserState.userQuery[parserState.pos];
+ const c = parserState.userQuery[parserState.pos];
if (!isIdentCharacter(c)) {
if (isErrorCharacter(c)) {
throw new Error(`Unexpected \`${c}\``);
* @param {boolean} isInGenerics
*/
function getNextElem(query, parserState, elems, isInGenerics) {
- var generics = [];
+ const generics = [];
- var start = parserState.pos;
- var end;
+ let start = parserState.pos;
+ let end;
// We handle the strings on their own mostly to make code easier to follow.
if (parserState.userQuery[parserState.pos] === "\"") {
start += 1;
* character.
*/
function getItemsBefore(query, parserState, elems, endChar) {
- var foundStopChar = true;
+ let foundStopChar = true;
while (parserState.pos < parserState.length) {
- var c = parserState.userQuery[parserState.pos];
+ const c = parserState.userQuery[parserState.pos];
if (c === endChar) {
break;
} else if (isSeparatorCharacter(c)) {
} else if (c === ":" && isPathStart(parserState)) {
throw new Error("Unexpected `::`: paths cannot start with `::`");
} else if (c === ":" || isEndCharacter(c)) {
- var extra = "";
+ let extra = "";
if (endChar === ">") {
extra = "`<`";
} else if (endChar === "") {
}
throw new Error(`Expected \`,\` or \` \`, found \`${c}\``);
}
- var posBefore = parserState.pos;
+ const posBefore = parserState.pos;
getNextElem(query, parserState, elems, endChar === ">");
// This case can be encountered if `getNextElem` encounted a "stop character" right from
// the start. For example if you have `,,` or `<>`. In this case, we simply move up the
* @param {ParserState} parserState
*/
function checkExtraTypeFilterCharacters(parserState) {
- var query = parserState.userQuery;
+ const query = parserState.userQuery;
- for (var pos = 0; pos < parserState.pos; ++pos) {
+ for (let pos = 0; pos < parserState.pos; ++pos) {
if (!isIdentCharacter(query[pos]) && !isWhitespaceCharacter(query[pos])) {
throw new Error(`Unexpected \`${query[pos]}\` in type filter`);
}
* @param {ParserState} parserState
*/
function parseInput(query, parserState) {
- var c, before;
- var foundStopChar = true;
+ let c, before;
+ let foundStopChar = true;
while (parserState.pos < parserState.length) {
c = parserState.userQuery[parserState.pos];
* @return {string}
*/
function buildUrl(search, filterCrates) {
- var extra = "?search=" + encodeURIComponent(search);
+ let extra = "?search=" + encodeURIComponent(search);
if (filterCrates !== null) {
extra += "&filter-crate=" + encodeURIComponent(filterCrates);
* @return {string|null}
*/
function getFilterCrates() {
- var elem = document.getElementById("crate-search");
+ const elem = document.getElementById("crate-search");
if (elem &&
elem.value !== "All crates" &&
*/
function parseQuery(userQuery) {
userQuery = userQuery.trim();
- var parserState = {
+ const parserState = {
length: userQuery.length,
pos: 0,
// Total number of elements (includes generics).
typeFilter: null,
userQuery: userQuery.toLowerCase(),
};
- var query = newParsedQuery(userQuery);
+ let query = newParsedQuery(userQuery);
try {
parseInput(query, parserState);
if (parserState.typeFilter !== null) {
- var typeFilter = parserState.typeFilter;
+ let typeFilter = parserState.typeFilter;
if (typeFilter === "const") {
typeFilter = "constant";
}
* @return {ResultsTable}
*/
function execQuery(parsedQuery, searchWords, filterCrates) {
- var results_others = {}, results_in_args = {}, results_returned = {};
+ const results_others = {}, results_in_args = {}, results_returned = {};
function transformResults(results) {
- var duplicates = {};
- var out = [];
-
- for (var i = 0, len = results.length; i < len; ++i) {
- var result = results[i];
+ const duplicates = {};
+ const out = [];
+ for (const result of results) {
if (result.id > -1) {
- var obj = searchIndex[result.id];
+ const obj = searchIndex[result.id];
obj.lev = result.lev;
- var res = buildHrefAndPath(obj);
+ const res = buildHrefAndPath(obj);
obj.displayPath = pathSplitter(res[0]);
obj.fullPath = obj.displayPath + obj.name;
// To be sure than it some items aren't considered as duplicate.
}
function sortResults(results, isType) {
- var userQuery = parsedQuery.userQuery;
- var ar = [];
- for (var entry in results) {
+ const userQuery = parsedQuery.userQuery;
+ const ar = [];
+ for (const entry in results) {
if (hasOwnPropertyRustdoc(results, entry)) {
- var result = results[entry];
+ const result = results[entry];
result.word = searchWords[result.id];
result.item = searchIndex[result.id] || {};
ar.push(result);
}
results.sort(function(aaa, bbb) {
- var a, b;
+ let a, b;
// sort by exact match with regard to the last word (mismatch goes later)
a = (aaa.word !== userQuery);
return 0;
});
- var nameSplit = null;
+ let nameSplit = null;
if (parsedQuery.elems.length === 1) {
- var hasPath = typeof parsedQuery.elems[0].path === "undefined";
+ const hasPath = typeof parsedQuery.elems[0].path === "undefined";
nameSplit = hasPath ? null : parsedQuery.elems[0].path;
}
- for (var i = 0, len = results.length; i < len; ++i) {
- result = results[i];
-
+ for (const result of results) {
// this validation does not make sense when searching by types
if (result.dontValidate) {
continue;
}
- var name = result.item.name.toLowerCase(),
+ const name = result.item.name.toLowerCase(),
path = result.item.path.toLowerCase(),
parent = result.item.parent;
}
// The names match, but we need to be sure that all generics kinda
// match as well.
- var elem_name;
+ let elem_name;
if (elem.generics.length > 0 && row[GENERICS_DATA].length >= elem.generics.length) {
- var elems = Object.create(null);
- for (var x = 0, length = row[GENERICS_DATA].length; x < length; ++x) {
- elem_name = row[GENERICS_DATA][x][NAME];
+ const elems = Object.create(null);
+ for (const entry of row[GENERICS_DATA]) {
+ elem_name = entry[NAME];
if (elem_name === "") {
// Pure generic, needs to check into it.
- if (checkGenerics(
- row[GENERICS_DATA][x], elem, MAX_LEV_DISTANCE + 1) !== 0) {
+ if (checkGenerics(entry, elem, MAX_LEV_DISTANCE + 1) !== 0) {
return MAX_LEV_DISTANCE + 1;
}
continue;
}
// We need to find the type that matches the most to remove it in order
// to move forward.
- for (x = 0, length = elem.generics.length; x < length; ++x) {
- var generic = elem.generics[x];
- var match = null;
+ for (const generic of elem.generics) {
+ let match = null;
if (elems[generic.name]) {
match = generic.name;
} else {
* @return {integer} - Returns a Levenshtein distance to the best match.
*/
function checkIfInGenerics(row, elem) {
- var lev = MAX_LEV_DISTANCE + 1;
- for (var x = 0, length = row[GENERICS_DATA].length; x < length && lev !== 0; ++x) {
- lev = Math.min(
- checkType(row[GENERICS_DATA][x], elem, true),
- lev
- );
+ let lev = MAX_LEV_DISTANCE + 1;
+ for (const entry of row[GENERICS_DATA]) {
+ lev = Math.min(checkType(entry, elem, true), lev);
+ if (lev === 0) {
+ break;
+ }
}
return lev;
}
return MAX_LEV_DISTANCE + 1;
}
- var lev = levenshtein(row[NAME], elem.name);
+ let lev = levenshtein(row[NAME], elem.name);
if (literalSearch) {
if (lev !== 0) {
// The name didn't match, let's try to check if the generics do.
if (elem.generics.length === 0) {
- var checkGeneric = (row.length > GENERICS_DATA &&
+ const checkGeneric = (row.length > GENERICS_DATA &&
row[GENERICS_DATA].length > 0);
if (checkGeneric && row[GENERICS_DATA].findIndex(function(tmp_elem) {
return tmp_elem[NAME] === elem.name;
} else {
// At this point, the name kinda match and we have generics to check, so
// let's go!
- var tmp_lev = checkGenerics(row, elem, lev);
+ const tmp_lev = checkGenerics(row, elem, lev);
if (tmp_lev > MAX_LEV_DISTANCE) {
return MAX_LEV_DISTANCE + 1;
}
* match, returns `MAX_LEV_DISTANCE + 1`.
*/
function findArg(row, elem, typeFilter) {
- var lev = MAX_LEV_DISTANCE + 1;
+ let lev = MAX_LEV_DISTANCE + 1;
if (row && row.type && row.type[INPUTS_DATA] && row.type[INPUTS_DATA].length > 0) {
- var length = row.type[INPUTS_DATA].length;
- for (var i = 0; i < length; i++) {
- var tmp = row.type[INPUTS_DATA][i];
- if (!typePassesFilter(typeFilter, tmp[1])) {
+ for (const input of row.type[INPUTS_DATA]) {
+ if (!typePassesFilter(typeFilter, input[1])) {
continue;
}
- lev = Math.min(lev, checkType(tmp, elem, parsedQuery.literalSearch));
+ lev = Math.min(lev, checkType(input, elem, parsedQuery.literalSearch));
if (lev === 0) {
return 0;
}
* match, returns `MAX_LEV_DISTANCE + 1`.
*/
function checkReturned(row, elem, typeFilter) {
- var lev = MAX_LEV_DISTANCE + 1;
+ let lev = MAX_LEV_DISTANCE + 1;
if (row && row.type && row.type.length > OUTPUT_DATA) {
- var ret = row.type[OUTPUT_DATA];
+ let ret = row.type[OUTPUT_DATA];
if (typeof ret[0] === "string") {
ret = [ret];
}
- for (var x = 0, len = ret.length; x < len; ++x) {
- var tmp = ret[x];
- if (!typePassesFilter(typeFilter, tmp[1])) {
+ for (const ret_ty of ret) {
+ if (!typePassesFilter(typeFilter, ret_ty[1])) {
continue;
}
- lev = Math.min(lev, checkType(tmp, elem, parsedQuery.literalSearch));
+ lev = Math.min(lev, checkType(ret_ty, elem, parsedQuery.literalSearch));
if (lev === 0) {
return 0;
}
if (contains.length === 0) {
return 0;
}
- var ret_lev = MAX_LEV_DISTANCE + 1;
- var path = ty.path.split("::");
+ let ret_lev = MAX_LEV_DISTANCE + 1;
+ const path = ty.path.split("::");
if (ty.parent && ty.parent.name) {
path.push(ty.parent.name.toLowerCase());
}
- var length = path.length;
- var clength = contains.length;
+ const length = path.length;
+ const clength = contains.length;
if (clength > length) {
return MAX_LEV_DISTANCE + 1;
}
- for (var i = 0; i < length; ++i) {
+ for (let i = 0; i < length; ++i) {
if (i + clength > length) {
break;
}
- var lev_total = 0;
- var aborted = false;
- for (var x = 0; x < clength; ++x) {
- var lev = levenshtein(path[i + x], contains[x]);
+ let lev_total = 0;
+ let aborted = false;
+ for (let x = 0; x < clength; ++x) {
+ const lev = levenshtein(path[i + x], contains[x]);
if (lev > MAX_LEV_DISTANCE) {
aborted = true;
break;
if (filter <= NO_TYPE_FILTER || filter === type) return true;
// Match related items
- var name = itemTypes[type];
+ const name = itemTypes[type];
switch (itemTypes[filter]) {
case "constant":
return name === "associatedconstant";
}
function handleAliases(ret, query, filterCrates) {
- var lowerQuery = query.toLowerCase();
+ const lowerQuery = query.toLowerCase();
// We separate aliases and crate aliases because we want to have current crate
// aliases to be before the others in the displayed results.
- var aliases = [];
- var crateAliases = [];
+ const aliases = [];
+ const crateAliases = [];
if (filterCrates !== null) {
if (ALIASES[filterCrates] && ALIASES[filterCrates][lowerQuery]) {
- var query_aliases = ALIASES[filterCrates][lowerQuery];
- var len = query_aliases.length;
- for (var i = 0; i < len; ++i) {
- aliases.push(createAliasFromItem(searchIndex[query_aliases[i]]));
+ const query_aliases = ALIASES[filterCrates][lowerQuery];
+ for (const alias of query_aliases) {
+ aliases.push(createAliasFromItem(searchIndex[alias]));
}
}
} else {
Object.keys(ALIASES).forEach(function(crate) {
if (ALIASES[crate][lowerQuery]) {
- var pushTo = crate === window.currentCrate ? crateAliases : aliases;
- var query_aliases = ALIASES[crate][lowerQuery];
- var len = query_aliases.length;
- for (var i = 0; i < len; ++i) {
- pushTo.push(createAliasFromItem(searchIndex[query_aliases[i]]));
+ const pushTo = crate === window.currentCrate ? crateAliases : aliases;
+ const query_aliases = ALIASES[crate][lowerQuery];
+ for (const alias of query_aliases) {
+ pushTo.push(createAliasFromItem(searchIndex[alias]));
}
}
});
}
- var sortFunc = function(aaa, bbb) {
+ const sortFunc = function(aaa, bbb) {
if (aaa.path < bbb.path) {
return 1;
} else if (aaa.path === bbb.path) {
crateAliases.sort(sortFunc);
aliases.sort(sortFunc);
- var pushFunc = function(alias) {
+ const pushFunc = function(alias) {
alias.alias = query;
- var res = buildHrefAndPath(alias);
+ const res = buildHrefAndPath(alias);
alias.displayPath = pathSplitter(res[0]);
alias.fullPath = alias.displayPath + alias.name;
alias.href = res[1];
function addIntoResults(results, fullId, id, index, lev) {
if (lev === 0 || (!parsedQuery.literalSearch && lev <= MAX_LEV_DISTANCE)) {
if (results[fullId] !== undefined) {
- var result = results[fullId];
+ const result = results[fullId];
if (result.dontValidate || result.lev <= lev) {
return;
}
if (!row || (filterCrates !== null && row.crate !== filterCrates)) {
return;
}
- var lev, lev_add = 0, index = -1;
- var fullId = row.id;
+ let lev, lev_add = 0, index = -1;
+ const fullId = row.id;
- var in_args = findArg(row, elem, parsedQuery.typeFilter);
- var returned = checkReturned(row, elem, parsedQuery.typeFilter);
+ const in_args = findArg(row, elem, parsedQuery.typeFilter);
+ const returned = checkReturned(row, elem, parsedQuery.typeFilter);
addIntoResults(results_in_args, fullId, pos, index, in_args);
addIntoResults(results_returned, fullId, pos, index, returned);
if (!typePassesFilter(parsedQuery.typeFilter, row.ty)) {
return;
}
- var searchWord = searchWords[pos];
+ const searchWord = searchWords[pos];
if (parsedQuery.literalSearch) {
if (searchWord === elem.name) {
return;
}
- var totalLev = 0;
- var nbLev = 0;
- var lev;
+ let totalLev = 0;
+ let nbLev = 0;
// If the result is too "bad", we return false and it ends this search.
function checkArgs(elems, callback) {
- for (var i = 0, len = elems.length; i < len; ++i) {
- var elem = elems[i];
+ for (const elem of elems) {
// There is more than one parameter to the query so all checks should be "exact"
- lev = callback(row, elem, NO_TYPE_FILTER);
+ const lev = callback(row, elem, NO_TYPE_FILTER);
if (lev <= 1) {
nbLev += 1;
totalLev += lev;
if (nbLev === 0) {
return;
}
- lev = Math.round(totalLev / nbLev);
+ const lev = Math.round(totalLev / nbLev);
addIntoResults(results, row.id, pos, 0, lev);
}
function innerRunQuery() {
- var elem, i, nSearchWords, in_returned, row;
+ let elem, i, nSearchWords, in_returned, row;
if (parsedQuery.foundElems === 1) {
if (parsedQuery.elems.length === 1) {
}
}
} else if (parsedQuery.foundElems > 0) {
- var container = results_others;
+ let container = results_others;
// In the special case where only a "returned" information is available, we want to
// put the information into the "results_returned" dict.
if (parsedQuery.returned.length !== 0 && parsedQuery.elems.length === 0) {
innerRunQuery();
}
- var ret = createQueryResults(
+ const ret = createQueryResults(
sortResults(results_in_args, true),
sortResults(results_returned, true),
sortResults(results_others, false),
if (!keys || !keys.length) {
return true;
}
- for (var i = 0, len = keys.length; i < len; ++i) {
+ for (const key of keys) {
// each check is for validation so we negate the conditions and invalidate
if (!(
// check for an exact name match
- name.indexOf(keys[i]) > -1 ||
+ name.indexOf(key) > -1 ||
// then an exact path match
- path.indexOf(keys[i]) > -1 ||
+ path.indexOf(key) > -1 ||
// next if there is a parent, check for exact parent match
(parent !== undefined && parent.name !== undefined &&
- parent.name.toLowerCase().indexOf(keys[i]) > -1) ||
+ parent.name.toLowerCase().indexOf(key) > -1) ||
// lastly check to see if the name was a levenshtein match
- levenshtein(name, keys[i]) <= MAX_LEV_DISTANCE)) {
+ levenshtein(name, key) <= MAX_LEV_DISTANCE)) {
return false;
}
}
}
function nextTab(direction) {
- var next = (searchState.currentTab + direction + 3) % searchState.focusedByTab.length;
+ const next = (searchState.currentTab + direction + 3) % searchState.focusedByTab.length;
searchState.focusedByTab[searchState.currentTab] = document.activeElement;
printTab(next);
focusSearchResult();
// Focus the first search result on the active tab, or the result that
// was focused last time this tab was active.
function focusSearchResult() {
- var target = searchState.focusedByTab[searchState.currentTab] ||
+ const target = searchState.focusedByTab[searchState.currentTab] ||
document.querySelectorAll(".search-results.active a").item(0) ||
document.querySelectorAll("#titles > button").item(searchState.currentTab);
if (target) {
}
function buildHrefAndPath(item) {
- var displayPath;
- var href;
- var type = itemTypes[item.ty];
- var name = item.name;
- var path = item.path;
+ let displayPath;
+ let href;
+ const type = itemTypes[item.ty];
+ const name = item.name;
+ let path = item.path;
if (type === "mod") {
displayPath = path + "::";
displayPath = "";
href = window.rootPath + name + "/index.html";
} else if (item.parent !== undefined) {
- var myparent = item.parent;
- var anchor = "#" + type + "." + name;
- var parentType = itemTypes[myparent.ty];
- var pageType = parentType;
- var pageName = myparent.name;
+ const myparent = item.parent;
+ let anchor = "#" + type + "." + name;
+ const parentType = itemTypes[myparent.ty];
+ let pageType = parentType;
+ let pageName = myparent.name;
if (parentType === "primitive") {
displayPath = myparent.name + "::";
} else if (type === "structfield" && parentType === "variant") {
// Structfields belonging to variants are special: the
// final path element is the enum name.
- var enumNameIdx = item.path.lastIndexOf("::");
- var enumName = item.path.substr(enumNameIdx + 2);
+ const enumNameIdx = item.path.lastIndexOf("::");
+ const enumName = item.path.substr(enumNameIdx + 2);
path = item.path.substr(0, enumNameIdx);
displayPath = path + "::" + enumName + "::" + myparent.name + "::";
anchor = "#variant." + myparent.name + ".field." + name;
}
function escape(content) {
- var h1 = document.createElement("h1");
+ const h1 = document.createElement("h1");
h1.textContent = content;
return h1.innerHTML;
}
function pathSplitter(path) {
- var tmp = "<span>" + path.replace(/::/g, "::</span><span>");
+ const tmp = "<span>" + path.replace(/::/g, "::</span><span>");
if (tmp.endsWith("<span>")) {
return tmp.slice(0, tmp.length - 6);
}
* @param {boolean} display - True if this is the active tab
*/
function addTab(array, query, display) {
- var extraClass = "";
+ let extraClass = "";
if (display === true) {
extraClass = " active";
}
- var output = document.createElement("div");
- var length = 0;
+ const output = document.createElement("div");
+ let length = 0;
if (array.length > 0) {
output.className = "search-results " + extraClass;
array.forEach(function(item) {
- var name = item.name;
- var type = itemTypes[item.ty];
+ const name = item.name;
+ const type = itemTypes[item.ty];
length += 1;
- var extra = "";
+ let extra = "";
if (type === "primitive") {
extra = " <i>(primitive type)</i>";
} else if (type === "keyword") {
extra = " <i>(keyword)</i>";
}
- var link = document.createElement("a");
+ const link = document.createElement("a");
link.className = "result-" + type;
link.href = item.href;
- var wrapper = document.createElement("div");
- var resultName = document.createElement("div");
+ const wrapper = document.createElement("div");
+ const resultName = document.createElement("div");
resultName.className = "result-name";
if (item.is_alias) {
- var alias = document.createElement("span");
+ const alias = document.createElement("span");
alias.className = "alias";
- var bold = document.createElement("b");
+ const bold = document.createElement("b");
bold.innerText = item.alias;
alias.appendChild(bold);
item.displayPath + "<span class=\"" + type + "\">" + name + extra + "</span>");
wrapper.appendChild(resultName);
- var description = document.createElement("div");
+ const description = document.createElement("div");
description.className = "desc";
- var spanDesc = document.createElement("span");
+ const spanDesc = document.createElement("span");
spanDesc.insertAdjacentHTML("beforeend", item.desc);
description.appendChild(spanDesc);
* @param {string} filterCrates
*/
function showResults(results, go_to_first, filterCrates) {
- var search = searchState.outputElement();
+ const search = searchState.outputElement();
if (go_to_first || (results.others.length === 1
&& getSettingValue("go-to-only-result") === "true"
// By default, the search DOM element is "empty" (meaning it has no children not
// ESC or empty the search input (which also "cancels" the search).
&& (!search.firstChild || search.firstChild.innerText !== searchState.loadingText)))
{
- var elem = document.createElement("a");
+ const elem = document.createElement("a");
elem.href = results.others[0].href;
removeClass(elem, "active");
// For firefox, we need the element to be in the DOM so it can be clicked.
currentResults = results.query.userQuery;
- var ret_others = addTab(results.others, results.query, true);
- var ret_in_args = addTab(results.in_args, results.query, false);
- var ret_returned = addTab(results.returned, results.query, false);
+ const ret_others = addTab(results.others, results.query, true);
+ const ret_in_args = addTab(results.in_args, results.query, false);
+ const ret_returned = addTab(results.returned, results.query, false);
// Navigate to the relevant tab if the current tab is empty, like in case users search
// for "-> String". If they had selected another tab previously, they have to click on
// it again.
- var currentTab = searchState.currentTab;
+ let currentTab = searchState.currentTab;
if ((currentTab === 0 && ret_others[1] === 0) ||
(currentTab === 1 && ret_in_args[1] === 0) ||
(currentTab === 2 && ret_returned[1] === 0)) {
let crates = "";
if (window.ALL_CRATES.length > 1) {
crates = ` in <select id="crate-search"><option value="All crates">All crates</option>`;
- for (let c of window.ALL_CRATES) {
+ for (const c of window.ALL_CRATES) {
crates += `<option value="${c}" ${c == filterCrates && "selected"}>${c}</option>`;
}
crates += `</select>`;
}
- var typeFilter = "";
+ let typeFilter = "";
if (results.query.typeFilter !== NO_TYPE_FILTER) {
typeFilter = " (type: " + escape(itemTypes[results.query.typeFilter]) + ")";
}
- var output = `<div id="search-settings">` +
+ let output = `<div id="search-settings">` +
`<h1 class="search-results-title">Results for ${escape(results.query.userQuery)}` +
`${typeFilter}</h1> in ${crates} </div>`;
if (results.query.error !== null) {
makeTabHeader(2, "In Return Types", ret_returned[1]) +
"</div>";
- var resultsElem = document.createElement("div");
+ const resultsElem = document.createElement("div");
resultsElem.id = "results";
resultsElem.appendChild(ret_others[0]);
resultsElem.appendChild(ret_in_args[0]);
resultsElem.appendChild(ret_returned[0]);
search.innerHTML = output;
- let crateSearch = document.getElementById("crate-search");
+ const crateSearch = document.getElementById("crate-search");
if (crateSearch) {
crateSearch.addEventListener("input", updateCrate);
}
// Reset focused elements.
searchState.focusedByTab = [null, null, null];
searchState.showResults(search);
- var elems = document.getElementById("titles").childNodes;
+ const elems = document.getElementById("titles").childNodes;
elems[0].onclick = function() { printTab(0); };
elems[1].onclick = function() { printTab(1); };
elems[2].onclick = function() { printTab(2); };
* @param {boolean} [forced]
*/
function search(e, forced) {
- var params = searchState.getQueryStringParams();
- var query = parseQuery(searchState.input.value.trim());
+ const params = searchState.getQueryStringParams();
+ const query = parseQuery(searchState.input.value.trim());
if (e) {
e.preventDefault();
return;
}
- var filterCrates = getFilterCrates();
+ let filterCrates = getFilterCrates();
// In case we have no information about the saved crate and there is a URL query parameter,
// we override it with the URL query parameter.
// Because searching is incremental by character, only the most
// recent search query is added to the browser history.
if (searchState.browserSupportsHistoryApi()) {
- var newURL = buildUrl(query.original, filterCrates);
+ const newURL = buildUrl(query.original, filterCrates);
if (!history.state && !params.search) {
history.pushState(null, "", newURL);
} else {
/**
* @type {Array<string>}
*/
- var searchWords = [];
- var i, word;
- var currentIndex = 0;
- var id = 0;
+ const searchWords = [];
+ let i, word;
+ let currentIndex = 0;
+ let id = 0;
- for (var crate in rawSearchIndex) {
+ for (const crate in rawSearchIndex) {
if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) {
continue;
}
- var crateSize = 0;
+ let crateSize = 0;
/**
* The raw search data for a given crate. `n`, `t`, `d`, and `q`, `i`, and `f`
* p: Array<Object>,
* }}
*/
- var crateCorpus = rawSearchIndex[crate];
+ const crateCorpus = rawSearchIndex[crate];
searchWords.push(crate);
// This object should have exactly the same set of fields as the "row"
// object defined below. Your JavaScript runtime will thank you.
// https://mathiasbynens.be/notes/shapes-ics
- var crateRow = {
+ const crateRow = {
crate: crate,
ty: 1, // == ExternCrate
name: crate,
currentIndex += 1;
// an array of (Number) item types
- var itemTypes = crateCorpus.t;
+ const itemTypes = crateCorpus.t;
// an array of (String) item names
- var itemNames = crateCorpus.n;
+ const itemNames = crateCorpus.n;
// an array of (String) full paths (or empty string for previous path)
- var itemPaths = crateCorpus.q;
+ const itemPaths = crateCorpus.q;
// an array of (String) descriptions
- var itemDescs = crateCorpus.d;
+ const itemDescs = crateCorpus.d;
// an array of (Number) the parent path index + 1 to `paths`, or 0 if none
- var itemParentIdxs = crateCorpus.i;
+ const itemParentIdxs = crateCorpus.i;
// an array of (Object | null) the type of the function, if any
- var itemFunctionSearchTypes = crateCorpus.f;
+ const itemFunctionSearchTypes = crateCorpus.f;
// an array of [(Number) item type,
// (String) name]
- var paths = crateCorpus.p;
+ const paths = crateCorpus.p;
// an array of [(String) alias name
// [Number] index to items]
- var aliases = crateCorpus.a;
+ const aliases = crateCorpus.a;
// convert `rawPaths` entries into object form
- var len = paths.length;
+ let len = paths.length;
for (i = 0; i < len; ++i) {
paths[i] = {ty: paths[i][0], name: paths[i][1]};
}
// all other search operations have access to this cached data for
// faster analysis operations
len = itemTypes.length;
- var lastPath = "";
+ let lastPath = "";
for (i = 0; i < len; ++i) {
// This object should have exactly the same set of fields as the "crateRow"
// object defined above.
word = "";
searchWords.push("");
}
- var row = {
+ const row = {
crate: crate,
ty: itemTypes[i],
name: itemNames[i],
if (aliases) {
ALIASES[crate] = {};
- var j, local_aliases;
- for (var alias_name in aliases) {
+ for (const alias_name in aliases) {
if (!hasOwnPropertyRustdoc(aliases, alias_name)) {
continue;
}
if (!hasOwnPropertyRustdoc(ALIASES[crate], alias_name)) {
ALIASES[crate][alias_name] = [];
}
- local_aliases = aliases[alias_name];
- for (j = 0, len = local_aliases.length; j < len; ++j) {
- ALIASES[crate][alias_name].push(local_aliases[j] + currentIndex);
+ for (const local_alias of aliases[alias_name]) {
+ ALIASES[crate][alias_name].push(local_alias + currentIndex);
}
}
}
}
function putBackSearch() {
- var search_input = searchState.input;
+ const search_input = searchState.input;
if (!searchState.input) {
return;
}
- var search = searchState.outputElement();
+ const search = searchState.outputElement();
if (search_input.value !== "" && hasClass(search, "hidden")) {
searchState.showResults(search);
if (searchState.browserSupportsHistoryApi()) {
}
function registerSearchEvents() {
- var searchAfter500ms = function() {
+ const searchAfter500ms = function() {
searchState.clearInputTimeout();
if (searchState.input.value.length === 0) {
if (searchState.browserSupportsHistoryApi()) {
// up and down arrow select next/previous search result, or the
// search box if we're already at the top.
if (e.which === 38) { // up
- var previous = document.activeElement.previousElementSibling;
+ const previous = document.activeElement.previousElementSibling;
if (previous) {
previous.focus();
} else {
}
e.preventDefault();
} else if (e.which === 40) { // down
- var next = document.activeElement.nextElementSibling;
+ const next = document.activeElement.nextElementSibling;
if (next) {
next.focus();
}
- var rect = document.activeElement.getBoundingClientRect();
+ const rect = document.activeElement.getBoundingClientRect();
if (window.innerHeight - rect.bottom < rect.height) {
window.scrollBy(0, rect.height);
}
// history.
if (searchState.browserSupportsHistoryApi()) {
// Store the previous <title> so we can revert back to it later.
- var previousTitle = document.title;
+ const previousTitle = document.title;
window.addEventListener("popstate", function(e) {
- var params = searchState.getQueryStringParams();
+ const params = searchState.getQueryStringParams();
// Revert to the previous title manually since the History
// API ignores the title parameter.
document.title = previousTitle;
// that try to sync state between the URL and the search input. To work around it,
// do a small amount of re-init on page show.
window.onpageshow = function(){
- var qSearch = searchState.getQueryStringParams().search;
+ const qSearch = searchState.getQueryStringParams().search;
if (searchState.input.value === "" && qSearch) {
searchState.input.value = qSearch;
}
function updateCrate(ev) {
if (ev.target.value === "All crates") {
// If we don't remove it from the URL, it'll be picked up again by the search.
- var params = searchState.getQueryStringParams();
- var query = searchState.input.value.trim();
+ const params = searchState.getQueryStringParams();
+ const query = searchState.input.value.trim();
if (!history.state && !params.search) {
history.pushState(null, "", buildUrl(query, null));
} else {
// Local js definitions:
+/* eslint-env es6 */
+/* eslint no-var: "error" */
+/* eslint prefer-const: "error" */
/* global getSettingValue, getVirtualKey, onEachLazy, updateLocalStorage, updateSystemTheme */
/* global addClass, removeClass */
function setEvents() {
updateLightAndDark();
onEachLazy(document.getElementsByClassName("slider"), function(elem) {
- var toggle = elem.previousElementSibling;
- var settingId = toggle.id;
- var settingValue = getSettingValue(settingId);
+ const toggle = elem.previousElementSibling;
+ const settingId = toggle.id;
+ const settingValue = getSettingValue(settingId);
if (settingValue !== null) {
toggle.checked = settingValue === "true";
}
toggle.onkeyrelease = handleKey;
});
onEachLazy(document.getElementsByClassName("select-wrapper"), function(elem) {
- var select = elem.getElementsByTagName("select")[0];
- var settingId = select.id;
- var settingValue = getSettingValue(settingId);
+ const select = elem.getElementsByTagName("select")[0];
+ const settingId = select.id;
+ const settingValue = getSettingValue(settingId);
if (settingValue !== null) {
select.value = settingValue;
}
/// Files related to the Fira Sans font.
crate mod fira_sans {
- /// The file `FiraSans-Regular.woff`, the Regular variant of the Fira Sans font.
- crate static REGULAR: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff");
-
/// The file `FiraSans-Regular.woff2`, the Regular variant of the Fira Sans font in woff2.
- crate static REGULAR2: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff2");
-
- /// The file `FiraSans-Medium.woff`, the Medium variant of the Fira Sans font.
- crate static MEDIUM: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff");
+ crate static REGULAR: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff2");
/// The file `FiraSans-Medium.woff2`, the Medium variant of the Fira Sans font in woff2.
- crate static MEDIUM2: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff2");
+ crate static MEDIUM: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff2");
/// The file `FiraSans-LICENSE.txt`, the license text for the Fira Sans font.
crate static LICENSE: &[u8] = include_bytes!("static/fonts/FiraSans-LICENSE.txt");
/// Files related to the Source Serif 4 font.
crate mod source_serif_4 {
- /// The file `SourceSerif4-Regular.ttf.woff`, the Regular variant of the Source Serif 4 font.
- crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff");
-
/// The file `SourceSerif4-Regular.ttf.woff2`, the Regular variant of the Source Serif 4 font in
/// woff2.
- crate static REGULAR2: &[u8] = include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff2");
-
- /// The file `SourceSerif4-Bold.ttf.woff`, the Bold variant of the Source Serif 4 font.
- crate static BOLD: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff");
+ crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff2");
/// The file `SourceSerif4-Bold.ttf.woff2`, the Bold variant of the Source Serif 4 font in
/// woff2.
- crate static BOLD2: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff2");
-
- /// The file `SourceSerif4-It.ttf.woff`, the Italic variant of the Source Serif 4 font.
- crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff");
+ crate static BOLD: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff2");
/// The file `SourceSerif4-It.ttf.woff2`, the Italic variant of the Source Serif 4 font in
/// woff2.
- crate static ITALIC2: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff2");
+ crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff2");
/// The file `SourceSerif4-LICENSE.txt`, the license text for the Source Serif 4 font.
crate static LICENSE: &[u8] = include_bytes!("static/fonts/SourceSerif4-LICENSE.md");
/// Files related to the Source Code Pro font.
crate mod source_code_pro {
- /// The file `SourceCodePro-Regular.ttf.woff`, the Regular variant of the Source Code Pro font.
- crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff");
-
/// The file `SourceCodePro-Regular.ttf.woff2`, the Regular variant of the Source Code Pro font
/// in woff2.
- crate static REGULAR2: &[u8] = include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff2");
-
- /// The file `SourceCodePro-Semibold.ttf.woff`, the Semibold variant of the Source Code Pro
- /// font.
- crate static SEMIBOLD: &[u8] = include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff");
+ crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff2");
/// The file `SourceCodePro-Semibold.ttf.woff2`, the Semibold variant of the Source Code Pro
/// font in woff2.
- crate static SEMIBOLD2: &[u8] = include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff2");
-
- /// The file `SourceCodePro-It.ttf.woff`, the Italic variant of the Source Code Pro font.
- crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff");
+ crate static SEMIBOLD: &[u8] = include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff2");
/// The file `SourceCodePro-It.ttf.woff2`, the Italic variant of the Source Code Pro font in
/// woff2.
- crate static ITALIC2: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff2");
+ crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff2");
/// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font.
crate static LICENSE: &[u8] = include_bytes!("static/fonts/SourceCodePro-LICENSE.txt");
/// ```sh
/// pyftsubset NanumBarunGothic.ttf \
/// --unicodes=U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF \
-/// --output-file=NanumBarunGothic.ttf.woff --flavor=woff
-/// ```
-/// ```sh
-/// pyftsubset NanumBarunGothic.ttf \
-/// --unicodes=U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF \
/// --output-file=NanumBarunGothic.ttf.woff2 --flavor=woff2
/// ```
crate mod nanum_barun_gothic {
- /// The file `NanumBarunGothic.ttf.woff`, the Regular variant of the Nanum Barun Gothic font.
- crate static REGULAR: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff");
-
/// The file `NanumBarunGothic.ttf.woff2`, the Regular variant of the Nanum Barun Gothic font.
- crate static REGULAR2: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff2");
+ crate static REGULAR: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff2");
/// The file `NanumBarunGothic-LICENSE.txt`, the license text of the Nanum Barun Gothic font.
crate static LICENSE: &[u8] = include_bytes!("static/fonts/NanumBarunGothic-LICENSE.txt");
-Subproject commit fd336816c3a6d228dcef22171c43140f6fa7656f
+Subproject commit 326efc90ac5bf79a8fdd90898addf86bb6a6e404
--- /dev/null
+// assembly-output: ptx-linker
+// compile-flags: --crate-type cdylib -C target-cpu=sm_86
+// only-nvptx64
+// ignore-nvptx64
+
+// The following ABI tests are made with nvcc 11.6 does.
+//
+// The PTX ABI stability is tied to major versions of the PTX ISA
+// These tests assume major version 7
+//
+//
+// The following correspondence between types are assumed:
+// u<N> - uint<N>_t
+// i<N> - int<N>_t
+// [T, N] - std::array<T, N>
+// &T - T const*
+// &mut T - T*
+
+// CHECK: .version 7
+
+#![feature(abi_ptx, lang_items, no_core)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+#[repr(C)]
+pub struct SingleU8 {
+ f: u8,
+}
+
+#[repr(C)]
+pub struct DoubleU8 {
+ f: u8,
+ g: u8,
+}
+
+#[repr(C)]
+pub struct TripleU8 {
+ f: u8,
+ g: u8,
+ h: u8,
+}
+
+#[repr(C)]
+pub struct TripleU16 {
+ f: u16,
+ g: u16,
+ h: u16,
+}
+#[repr(C)]
+pub struct TripleU32 {
+ f: u32,
+ g: u32,
+ h: u32,
+}
+#[repr(C)]
+pub struct TripleU64 {
+ f: u64,
+ g: u64,
+ h: u64,
+}
+
+#[repr(C)]
+pub struct DoubleFloat {
+ f: f32,
+ g: f32,
+}
+
+#[repr(C)]
+pub struct TripleFloat {
+ f: f32,
+ g: f32,
+ h: f32,
+}
+
+#[repr(C)]
+pub struct TripleDouble {
+ f: f64,
+ g: f64,
+ h: f64,
+}
+
+#[repr(C)]
+pub struct ManyIntegers {
+ f: u8,
+ g: u16,
+ h: u32,
+ i: u64,
+}
+
+#[repr(C)]
+pub struct ManyNumerics {
+ f: u8,
+ g: u16,
+ h: u32,
+ i: u64,
+ j: f32,
+ k: f64,
+}
+
+// CHECK: .visible .entry f_u8_arg(
+// CHECK: .param .u8 f_u8_arg_param_0
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_u8_arg(_a: u8) {}
+
+// CHECK: .visible .entry f_u16_arg(
+// CHECK: .param .u16 f_u16_arg_param_0
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_u16_arg(_a: u16) {}
+
+// CHECK: .visible .entry f_u32_arg(
+// CHECK: .param .u32 f_u32_arg_param_0
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_u32_arg(_a: u32) {}
+
+// CHECK: .visible .entry f_u64_arg(
+// CHECK: .param .u64 f_u64_arg_param_0
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_u64_arg(_a: u64) {}
+
+// CHECK: .visible .entry f_u128_arg(
+// CHECK: .param .align 16 .b8 f_u128_arg_param_0[16]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_u128_arg(_a: u128) {}
+
+// CHECK: .visible .entry f_i8_arg(
+// CHECK: .param .u8 f_i8_arg_param_0
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_i8_arg(_a: i8) {}
+
+// CHECK: .visible .entry f_i16_arg(
+// CHECK: .param .u16 f_i16_arg_param_0
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_i16_arg(_a: i16) {}
+
+// CHECK: .visible .entry f_i32_arg(
+// CHECK: .param .u32 f_i32_arg_param_0
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_i32_arg(_a: i32) {}
+
+// CHECK: .visible .entry f_i64_arg(
+// CHECK: .param .u64 f_i64_arg_param_0
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_i64_arg(_a: i64) {}
+
+// CHECK: .visible .entry f_i128_arg(
+// CHECK: .param .align 16 .b8 f_i128_arg_param_0[16]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_i128_arg(_a: i128) {}
+
+// CHECK: .visible .entry f_f32_arg(
+// CHECK: .param .f32 f_f32_arg_param_0
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_f32_arg(_a: f32) {}
+
+// CHECK: .visible .entry f_f64_arg(
+// CHECK: .param .f64 f_f64_arg_param_0
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_f64_arg(_a: f64) {}
+
+// CHECK: .visible .entry f_single_u8_arg(
+// CHECK: .param .align 1 .b8 f_single_u8_arg_param_0[1]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_single_u8_arg(_a: SingleU8) {}
+
+// CHECK: .visible .entry f_double_u8_arg(
+// CHECK: .param .align 1 .b8 f_double_u8_arg_param_0[2]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_double_u8_arg(_a: DoubleU8) {}
+
+// CHECK: .visible .entry f_triple_u8_arg(
+// CHECK: .param .align 1 .b8 f_triple_u8_arg_param_0[3]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_triple_u8_arg(_a: TripleU8) {}
+
+// CHECK: .visible .entry f_triple_u16_arg(
+// CHECK: .param .align 2 .b8 f_triple_u16_arg_param_0[6]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_triple_u16_arg(_a: TripleU16) {}
+
+// CHECK: .visible .entry f_triple_u32_arg(
+// CHECK: .param .align 4 .b8 f_triple_u32_arg_param_0[12]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_triple_u32_arg(_a: TripleU32) {}
+
+// CHECK: .visible .entry f_triple_u64_arg(
+// CHECK: .param .align 8 .b8 f_triple_u64_arg_param_0[24]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_triple_u64_arg(_a: TripleU64) {}
+
+// CHECK: .visible .entry f_many_integers_arg(
+// CHECK: .param .align 8 .b8 f_many_integers_arg_param_0[16]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_many_integers_arg(_a: ManyIntegers) {}
+
+// CHECK: .visible .entry f_double_float_arg(
+// CHECK: .param .align 4 .b8 f_double_float_arg_param_0[8]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_double_float_arg(_a: DoubleFloat) {}
+
+// CHECK: .visible .entry f_triple_float_arg(
+// CHECK: .param .align 4 .b8 f_triple_float_arg_param_0[12]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_triple_float_arg(_a: TripleFloat) {}
+
+// CHECK: .visible .entry f_triple_double_arg(
+// CHECK: .param .align 8 .b8 f_triple_double_arg_param_0[24]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_triple_double_arg(_a: TripleDouble) {}
+
+// CHECK: .visible .entry f_many_numerics_arg(
+// CHECK: .param .align 8 .b8 f_many_numerics_arg_param_0[32]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_many_numerics_arg(_a: ManyNumerics) {}
+
+// CHECK: .visible .entry f_byte_array_arg(
+// CHECK: .param .align 1 .b8 f_byte_array_arg_param_0[5]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_byte_array_arg(_a: [u8; 5]) {}
+
+// CHECK: .visible .entry f_float_array_arg(
+// CHECK: .param .align 4 .b8 f_float_array_arg_param_0[20]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_float_array_arg(_a: [f32; 5]) {}
+
+// CHECK: .visible .entry f_u128_array_arg(
+// CHECK: .param .align 16 .b8 f_u128_array_arg_param_0[80]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_u128_array_arg(_a: [u128; 5]) {}
+
+// CHECK: .visible .entry f_u32_slice_arg(
+// CHECK: .param .u64 f_u32_slice_arg_param_0
+// CHECK: .param .u64 f_u32_slice_arg_param_1
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_u32_slice_arg(_a: &[u32]) {}
+
+// CHECK: .visible .entry f_tuple_u8_u8_arg(
+// CHECK: .param .align 1 .b8 f_tuple_u8_u8_arg_param_0[2]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_tuple_u8_u8_arg(_a: (u8, u8)) {}
+
+// CHECK: .visible .entry f_tuple_u32_u32_arg(
+// CHECK: .param .align 4 .b8 f_tuple_u32_u32_arg_param_0[8]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_tuple_u32_u32_arg(_a: (u32, u32)) {}
+
+
+// CHECK: .visible .entry f_tuple_u8_u8_u32_arg(
+// CHECK: .param .align 4 .b8 f_tuple_u8_u8_u32_arg_param_0[8]
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn f_tuple_u8_u8_u32_arg(_a: (u8, u8, u32)) {}
[ -e $(INVOCATION_ONLY)/x/index.html ]
[ -e $(INVOCATION_ONLY)/theme-xxx.css ] # generated from z.css
! [ -e $(INVOCATION_ONLY)/storage-xxx.js ]
- ! [ -e $(INVOCATION_ONLY)/SourceSerif4-It.ttf.woff ]
+ ! [ -e $(INVOCATION_ONLY)/SourceSerif4-It.ttf.woff2 ]
# FIXME: this probably shouldn't have a suffix
[ -e $(INVOCATION_ONLY)/y-xxx.css ]
toolchain-only:
$(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx --extend-css z.css x.rs
[ -e $(TOOLCHAIN_ONLY)/storage-xxx.js ]
- ! [ -e $(TOOLCHAIN_ONLY)/SourceSerif4-It.ttf.woff ]
+ ! [ -e $(TOOLCHAIN_ONLY)/SourceSerif4-It.ttf.woff2 ]
! [ -e $(TOOLCHAIN_ONLY)/search-index-xxx.js ]
! [ -e $(TOOLCHAIN_ONLY)/x/index.html ]
! [ -e $(TOOLCHAIN_ONLY)/theme.css ]
all-shared:
$(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources,unversioned-shared-resources --output $(ALL_SHARED) --resource-suffix=-xxx --extend-css z.css x.rs
[ -e $(ALL_SHARED)/storage-xxx.js ]
- [ -e $(ALL_SHARED)/SourceSerif4-It.ttf.woff ]
+ [ -e $(ALL_SHARED)/SourceSerif4-It.ttf.woff2 ]
! [ -e $(ALL_SHARED)/search-index-xxx.js ]
! [ -e $(ALL_SHARED)/settings.html ]
! [ -e $(ALL_SHARED)/x ]
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `S::f` is unsafe and requires unsafe function or block
--> $DIR/async-unsafe-fn-call-in-safe.rs:14:5
|
LL | S::f();
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block
--> $DIR/async-unsafe-fn-call-in-safe.rs:15:5
|
LL | f();
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `S::f` is unsafe and requires unsafe function or block
--> $DIR/async-unsafe-fn-call-in-safe.rs:19:5
|
LL | S::f();
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block
--> $DIR/async-unsafe-fn-call-in-safe.rs:20:5
|
LL | f();
async unsafe fn f() {}
async fn g() {
- S::f(); //~ ERROR call to unsafe function is unsafe
- f(); //~ ERROR call to unsafe function is unsafe
+ S::f(); //~ ERROR call to unsafe function `S::f` is unsafe
+ f(); //~ ERROR call to unsafe function `f` is unsafe
}
fn main() {
- S::f(); //[mir]~ ERROR call to unsafe function is unsafe
- f(); //[mir]~ ERROR call to unsafe function is unsafe
+ S::f(); //[mir]~ ERROR call to unsafe function `S::f` is unsafe
+ f(); //[mir]~ ERROR call to unsafe function `f` is unsafe
}
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `S::f` is unsafe and requires unsafe function or block
--> $DIR/async-unsafe-fn-call-in-safe.rs:14:5
|
LL | S::f();
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block
--> $DIR/async-unsafe-fn-call-in-safe.rs:15:5
|
LL | f();
--- /dev/null
+// Regression test for #93927: suggested trait bound for T should be Eq, not PartialEq
+struct MyType<T>(T);
+
+impl<T> PartialEq for MyType<T>
+where
+ T: Eq,
+{
+ fn eq(&self, other: &Self) -> bool {
+ true
+ }
+}
+
+fn cond<T: PartialEq>(val: MyType<T>) -> bool {
+ val == val
+ //~^ ERROR binary operation `==` cannot be applied to type `MyType<T>`
+}
+
+fn main() {
+ cond(MyType(0));
+}
--- /dev/null
+error[E0369]: binary operation `==` cannot be applied to type `MyType<T>`
+ --> $DIR/issue-93927.rs:14:9
+ |
+LL | val == val
+ | --- ^^ --- MyType<T>
+ | |
+ | MyType<T>
+ |
+help: consider further restricting this bound
+ |
+LL | fn cond<T: PartialEq + std::cmp::Eq>(val: MyType<T>) -> bool {
+ | ++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `std::pin::Pin::<P>::new_unchecked` is unsafe and requires unsafe function or block
--> $DIR/coerce-unsafe-closure-to-unsafe-fn-ptr.rs:5:31
|
LL | let _: unsafe fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); };
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `Pin::<P>::new_unchecked` is unsafe and requires unsafe function or block
--> $DIR/coerce-unsafe-closure-to-unsafe-fn-ptr.rs:5:31
|
LL | let _: unsafe fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); };
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block
--> $DIR/const-extern-fn-requires-unsafe.rs:9:17
|
LL | let a: [u8; foo()];
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block
--> $DIR/const-extern-fn-requires-unsafe.rs:11:5
|
LL | foo();
fn main() {
let a: [u8; foo()];
- //~^ ERROR call to unsafe function is unsafe and requires unsafe function or block
+ //~^ ERROR call to unsafe function `foo` is unsafe and requires unsafe function or block
foo();
- //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe function or block
+ //[mir]~^ ERROR call to unsafe function `foo` is unsafe and requires unsafe function or block
}
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block
--> $DIR/const-extern-fn-requires-unsafe.rs:9:17
|
LL | let a: [u8; foo()];
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block
--> $DIR/E0133.rs:7:5
|
LL | f();
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block
--> $DIR/E0133.rs:7:5
|
LL | f();
--- /dev/null
+// We previously mentioned other extern types in the error message here.
+//
+// Two extern types shouldn't really be considered similar just
+// because they are both extern types.
+
+#![feature(extern_types)]
+extern {
+ type ShouldNotBeMentioned;
+}
+
+extern {
+ type Foo;
+}
+
+unsafe impl Send for ShouldNotBeMentioned {}
+
+fn assert_send<T: Send + ?Sized>() {}
+
+fn main() {
+ assert_send::<Foo>()
+ //~^ ERROR `Foo` cannot be sent between threads safely
+}
--- /dev/null
+error[E0277]: `Foo` cannot be sent between threads safely
+ --> $DIR/extern-type-diag-not-similar.rs:20:19
+ |
+LL | assert_send::<Foo>()
+ | ^^^ `Foo` cannot be sent between threads safely
+ |
+ = help: the trait `Send` is not implemented for `Foo`
+note: required by a bound in `assert_send`
+ --> $DIR/extern-type-diag-not-similar.rs:17:19
+ |
+LL | fn assert_send<T: Send + ?Sized>() {}
+ | ^^^^ required by this bound in `assert_send`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `test::free` is unsafe and requires unsafe function or block
--> $DIR/foreign-unsafe-fn-called.rs:11:5
|
LL | test::free();
fn main() {
test::free();
- //~^ ERROR call to unsafe function is unsafe
+ //~^ ERROR call to unsafe function `test::free` is unsafe
}
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `test::free` is unsafe and requires unsafe function or block
--> $DIR/foreign-unsafe-fn-called.rs:11:5
|
LL | test::free();
+++ /dev/null
-// run-rustfix
-
-use std::ops::Add;
-
-struct A<B>(B);
-
-impl<B> Add for A<B> where B: Add + Add<Output = B> {
- type Output = Self;
-
- fn add(self, rhs: Self) -> Self {
- A(self.0 + rhs.0) //~ ERROR mismatched types
- }
-}
-
-struct C<B>(B);
-
-impl<B: Add + Add<Output = B>> Add for C<B> {
- type Output = Self;
-
- fn add(self, rhs: Self) -> Self {
- Self(self.0 + rhs.0) //~ ERROR mismatched types
- }
-}
-
-struct D<B>(B);
-
-impl<B: std::ops::Add<Output = B>> Add for D<B> {
- type Output = Self;
-
- fn add(self, rhs: Self) -> Self {
- Self(self.0 + rhs.0) //~ ERROR cannot add `B` to `B`
- }
-}
-
-struct E<B>(B);
-
-impl<B: Add> Add for E<B> where B: Add<Output = B>, B: Add<Output = B> {
- //~^ ERROR equality constraints are not yet supported in `where` clauses
- type Output = Self;
-
- fn add(self, rhs: Self) -> Self {
- Self(self.0 + rhs.0) //~ ERROR mismatched types
- }
-}
-
-fn main() {}
-// run-rustfix
-
use std::ops::Add;
struct A<B>(B);
error: equality constraints are not yet supported in `where` clauses
- --> $DIR/missing-bounds.rs:37:33
+ --> $DIR/missing-bounds.rs:35:33
|
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
| ^^^^^^^^^^^^^^^^^^^^^^ not supported
| ~~~~~~~~~~~~~~~~~~
error[E0308]: mismatched types
- --> $DIR/missing-bounds.rs:11:11
+ --> $DIR/missing-bounds.rs:9:11
|
LL | impl<B> Add for A<B> where B: Add {
| - this type parameter
= note: expected type parameter `B`
found associated type `<B as Add>::Output`
note: tuple struct defined here
- --> $DIR/missing-bounds.rs:5:8
+ --> $DIR/missing-bounds.rs:3:8
|
LL | struct A<B>(B);
| ^
| +++++++++++++++++
error[E0308]: mismatched types
- --> $DIR/missing-bounds.rs:21:14
+ --> $DIR/missing-bounds.rs:19:14
|
LL | impl<B: Add> Add for C<B> {
| - this type parameter
= note: expected type parameter `B`
found associated type `<B as Add>::Output`
note: tuple struct defined here
- --> $DIR/missing-bounds.rs:15:8
+ --> $DIR/missing-bounds.rs:13:8
|
LL | struct C<B>(B);
| ^
| +++++++++++++++++
error[E0369]: cannot add `B` to `B`
- --> $DIR/missing-bounds.rs:31:21
+ --> $DIR/missing-bounds.rs:29:21
|
LL | Self(self.0 + rhs.0)
| ------ ^ ----- B
|
help: consider restricting type parameter `B`
|
-LL | impl<B: std::ops::Add<Output = B>> Add for D<B> {
- | +++++++++++++++++++++++++++
+LL | impl<B: std::ops::Add> Add for D<B> {
+ | +++++++++++++++
error[E0308]: mismatched types
- --> $DIR/missing-bounds.rs:42:14
+ --> $DIR/missing-bounds.rs:40:14
|
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
| - this type parameter
= note: expected type parameter `B`
found associated type `<B as Add>::Output`
note: tuple struct defined here
- --> $DIR/missing-bounds.rs:35:8
+ --> $DIR/missing-bounds.rs:33:8
|
LL | struct E<B>(B);
| ^
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| --------- - ^^^^^^ unsatisfied trait bound introduced here
+help: one of the expressions' fields has a method of the same name
+ |
+LL | let filter = map.stream.filterx(|x: &_| true);
+ | +++++++
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:140:24
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| --------- - ^^^^^^ unsatisfied trait bound introduced here
+help: one of the expressions' fields has a method of the same name
+ |
+LL | let count = filter.stream.countx();
+ | +++++++
error: aborting due to 2 previous errors
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| --------- - ^^^^^^ unsatisfied trait bound introduced here
+help: one of the expressions' fields has a method of the same name
+ |
+LL | let filter = map.stream.filterx(|x: &_| true);
+ | +++++++
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:140:24
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| --------- - ^^^^^^ unsatisfied trait bound introduced here
+help: one of the expressions' fields has a method of the same name
+ |
+LL | let count = filter.stream.countx();
+ | +++++++
error: aborting due to 2 previous errors
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `std::intrinsics::unchecked_add` is unsafe and requires unsafe function or block
--> $DIR/unchecked_math_unsafe.rs:8:15
|
LL | let add = std::intrinsics::unchecked_add(x, y);
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `std::intrinsics::unchecked_sub` is unsafe and requires unsafe function or block
--> $DIR/unchecked_math_unsafe.rs:9:15
|
LL | let sub = std::intrinsics::unchecked_sub(x, y);
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `std::intrinsics::unchecked_mul` is unsafe and requires unsafe function or block
--> $DIR/unchecked_math_unsafe.rs:10:15
|
LL | let mul = std::intrinsics::unchecked_mul(x, y);
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `unchecked_add` is unsafe and requires unsafe function or block
--> $DIR/unchecked_math_unsafe.rs:8:15
|
LL | let add = std::intrinsics::unchecked_add(x, y);
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `unchecked_sub` is unsafe and requires unsafe function or block
--> $DIR/unchecked_math_unsafe.rs:9:15
|
LL | let sub = std::intrinsics::unchecked_sub(x, y);
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `unchecked_mul` is unsafe and requires unsafe function or block
--> $DIR/unchecked_math_unsafe.rs:10:15
|
LL | let mul = std::intrinsics::unchecked_mul(x, y);
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `std::ptr::write` is unsafe and requires unsafe function or block
--> $DIR/issue-28776.rs:7:5
|
LL | (&ptr::write)(1 as *mut _, 42);
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `std::ptr::write` is unsafe and requires unsafe function or block
--> $DIR/issue-28776.rs:7:5
|
LL | (&ptr::write)(1 as *mut _, 42);
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `X::with` is unsafe and requires unsafe function or block
--> $DIR/issue-3080.rs:10:5
|
LL | X(()).with();
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `X::with` is unsafe and requires unsafe function or block
--> $DIR/issue-3080.rs:10:5
|
LL | X(()).with();
| |
| &T
|
-help: consider restricting type parameter `T`
+help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
-LL | fn func<'a, T: std::ops::Mul<Output = &T>>(a: &'a [T]) -> impl Iterator<Item=&'a T> {
- | ++++++++++++++++++++++++++++
+LL | fn func<'a, T>(a: &'a [T]) -> impl Iterator<Item=&'a T> where &T: Mul<&T> {
+ | +++++++++++++++++
error: aborting due to previous error
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `issue_5844_aux::rand` is unsafe and requires unsafe function or block
--> $DIR/issue-5844.rs:8:5
|
LL | issue_5844_aux::rand();
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `rand` is unsafe and requires unsafe function or block
--> $DIR/issue-5844.rs:8:5
|
LL | issue_5844_aux::rand();
--- /dev/null
+fn main() {
+ 0.....{loop{}1};
+ //~^ ERROR unexpected token
+ //~| ERROR mismatched types
+}
--- /dev/null
+error: unexpected token: `...`
+ --> $DIR/issue-96335.rs:2:6
+ |
+LL | 0.....{loop{}1};
+ | ^^^
+ |
+help: use `..` for an exclusive range
+ |
+LL | 0....{loop{}1};
+ | ~~
+help: or `..=` for an inclusive range
+ |
+LL | 0..=..{loop{}1};
+ | ~~~
+
+error[E0308]: mismatched types
+ --> $DIR/issue-96335.rs:2:9
+ |
+LL | 0.....{loop{}1};
+ | ----^^^^^^^^^^^
+ | | |
+ | | expected integer, found struct `RangeTo`
+ | arguments to this function are incorrect
+ |
+ = note: expected type `{integer}`
+ found struct `RangeTo<{integer}>`
+note: associated function defined here
+ --> $SRC_DIR/core/src/ops/range.rs:LL:COL
+ |
+LL | pub const fn new(start: Idx, end: Idx) -> Self {
+ | ^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
static s: &'static str =
+ r#""## //~ ERROR too many `#` when terminating raw string
+;
+
+static s2: &'static str =
r#"
- "## //~ too many `#` when terminating raw string
+ "#### //~ ERROR too many `#` when terminating raw string
;
+
+const A: &'static str = r"" //~ ERROR expected `;`, found `#`
+
+// Test
+#[test]
+fn test() {}
+
+const B: &'static str = r""## //~ ERROR too many `#` when terminating raw string
+
+// Test
+#[test]
+fn test2() {}
+
+fn main() {}
error: too many `#` when terminating raw string
- --> $DIR/raw-str-unbalanced.rs:3:9
+ --> $DIR/raw-str-unbalanced.rs:2:10
|
-LL | "##
- | ^ help: remove the extra `#`
+LL | r#""##
+ | -----^ help: remove the extra `#`
+ | |
+ | this raw string started with 1 `#`
+
+error: too many `#` when terminating raw string
+ --> $DIR/raw-str-unbalanced.rs:7:9
+ |
+LL | / r#"
+LL | | "####
+ | | -^^^ help: remove the extra `#`s
+ | |________|
+ | this raw string started with 1 `#`
+
+error: expected `;`, found `#`
+ --> $DIR/raw-str-unbalanced.rs:10:28
+ |
+LL | const A: &'static str = r""
+ | ^ help: add `;` here
+...
+LL | #[test]
+ | - unexpected token
+
+error: too many `#` when terminating raw string
+ --> $DIR/raw-str-unbalanced.rs:16:28
|
- = note: the raw string started with 1 `#`s
+LL | const B: &'static str = r""##
+ | ---^^ help: remove the extra `#`s
+ | |
+ | this raw string started with 0 `#`s
-error: aborting due to previous error
+error: aborting due to 4 previous errors
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:23:5
|
LL | sse2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:24:5
|
LL | avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:25:5
|
LL | Quux.avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:30:5
|
LL | avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:31:5
|
LL | Quux.avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:36:5
|
LL | sse2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:37:5
|
LL | avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:38:5
|
LL | Quux.avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:44:5
|
LL | sse2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:47:18
|
LL | const name: () = sse2();
}
fn foo() {
- sse2(); //~ ERROR call to function with `#[target_feature]` is unsafe
- avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe
- Quux.avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe
+ sse2(); //~ ERROR call to function `sse2` with `#[target_feature]` is unsafe
+ avx_bmi2(); //~ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe
+ Quux.avx_bmi2(); //~ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe
}
#[target_feature(enable = "sse2")]
fn bar() {
- avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe
- Quux.avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe
+ avx_bmi2(); //~ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe
+ Quux.avx_bmi2(); //~ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe
}
#[target_feature(enable = "avx")]
fn baz() {
- sse2(); //~ ERROR call to function with `#[target_feature]` is unsafe
- avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe
- Quux.avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe
+ sse2(); //~ ERROR call to function `sse2` with `#[target_feature]` is unsafe
+ avx_bmi2(); //~ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe
+ Quux.avx_bmi2(); //~ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe
}
#[target_feature(enable = "avx")]
#[target_feature(enable = "bmi2")]
fn qux() {
- sse2(); //~ ERROR call to function with `#[target_feature]` is unsafe
+ sse2(); //~ ERROR call to function `sse2` with `#[target_feature]` is unsafe
}
-const name: () = sse2(); //~ ERROR call to function with `#[target_feature]` is unsafe
+const name: () = sse2(); //~ ERROR call to function `sse2` with `#[target_feature]` is unsafe
fn main() {}
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:23:5
|
LL | sse2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:24:5
|
LL | avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:25:5
|
LL | Quux.avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:30:5
|
LL | avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:31:5
|
LL | Quux.avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:36:5
|
LL | sse2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:37:5
|
LL | avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:38:5
|
LL | Quux.avx_bmi2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:44:5
|
LL | sse2();
|
= note: can only be called if the required target features are available
-error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:47:18
|
LL | const name: () = sse2();
--- /dev/null
+struct Kind;
+
+struct Ty {
+ kind: Kind,
+}
+
+impl Ty {
+ fn kind(&self) -> Kind {
+ todo!()
+ }
+}
+
+struct InferOk<T> {
+ value: T,
+ predicates: Vec<()>,
+}
+
+fn foo(i: InferOk<Ty>) {
+ let k = i.kind();
+ //~^ no method named `kind` found for struct `InferOk` in the current scope
+}
+
+fn main() {}
--- /dev/null
+error[E0599]: no method named `kind` found for struct `InferOk` in the current scope
+ --> $DIR/field-has-method.rs:19:15
+ |
+LL | struct InferOk<T> {
+ | ----------------- method `kind` not found for this
+...
+LL | let k = i.kind();
+ | ^^^^ method not found in `InferOk<Ty>`
+ |
+help: one of the expressions' fields has a method of the same name
+ |
+LL | let k = i.value.kind();
+ | ++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
|
LL | struct S<T>(T);
| ^^^^^^^^^^^^^^^ must implement `PartialEq<_>`
- = note: the trait `std::cmp::PartialEq` is not implemented for `S<T>`
help: consider annotating `S<T>` with `#[derive(PartialEq)]`
|
LL | #[derive(PartialEq)]
|
+help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
+ |
+LL | pub fn foo<T>(s: S<T>, t: S<T>) where S<T>: PartialEq {
+ | +++++++++++++++++++++
error: aborting due to previous error
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
- --> $DIR/issue-43733.rs:19:5
+error[E0133]: call to unsafe function `std::thread::$LOCALKEYINNER::<T>::get` is unsafe and requires unsafe function or block
+ --> $DIR/issue-43733.rs:21:5
|
LL | __KEY.get(Default::default)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
- --> $DIR/issue-43733.rs:22:42
+error[E0133]: call to unsafe function `std::thread::LocalKey::<T>::new` is unsafe and requires unsafe function or block
+ --> $DIR/issue-43733.rs:26:42
|
LL | static FOO: std::thread::LocalKey<Foo> = std::thread::LocalKey::new(__getit);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
// revisions: mir thir
// [thir]compile-flags: -Z thir-unsafeck
+// normalize-stderr-test: "__FastLocalKeyInner::<T>::get" -> "$$LOCALKEYINNER::<T>::get"
+// normalize-stderr-test: "__OsLocalKeyInner::<T>::get" -> "$$LOCALKEYINNER::<T>::get"
#![feature(thread_local)]
#![feature(cfg_target_thread_local, thread_local_internals)]
static __KEY: std::thread::__OsLocalKeyInner<Foo> = std::thread::__OsLocalKeyInner::new();
fn __getit(_: Option<&mut Option<RefCell<String>>>) -> std::option::Option<&'static Foo> {
- __KEY.get(Default::default) //~ ERROR call to unsafe function is unsafe
+ __KEY.get(Default::default)
+ //[mir]~^ ERROR call to unsafe function `std::thread::
+ //[thir]~^^ ERROR call to unsafe function `__
}
static FOO: std::thread::LocalKey<Foo> = std::thread::LocalKey::new(__getit);
-//~^ ERROR call to unsafe function is unsafe
+//[mir]~^ ERROR call to unsafe function `std::thread::LocalKey::<T>::new` is unsafe
+//[thir]~^^ ERROR call to unsafe function `LocalKey::<T>::new` is unsafe
fn main() {
FOO.with(|foo| println!("{}", foo.borrow()));
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
- --> $DIR/issue-43733.rs:19:5
+error[E0133]: call to unsafe function `$LOCALKEYINNER::<T>::get` is unsafe and requires unsafe function or block
+ --> $DIR/issue-43733.rs:21:5
|
LL | __KEY.get(Default::default)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
- --> $DIR/issue-43733.rs:22:42
+error[E0133]: call to unsafe function `LocalKey::<T>::new` is unsafe and requires unsafe function or block
+ --> $DIR/issue-43733.rs:26:42
|
LL | static FOO: std::thread::LocalKey<Foo> = std::thread::LocalKey::new(__getit);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
// run-pass
// no-prefer-dynamic
// ignore-emscripten no threads support
-
static mut HIT: bool = false;
struct Foo;
| |
| &T
|
-help: consider further restricting this bound
+help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
-LL | fn foo<T: MyMul<f64, f64> + std::ops::Mul<Output = f64>>(a: &T, b: f64) -> f64 {
- | +++++++++++++++++++++++++++++
+LL | fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 where &T: Mul<f64> {
+ | ++++++++++++++++++
error: aborting due to previous error
|
help: consider restricting type parameter `T`
|
-LL | fn foo<T: std::ops::Add<Output = T>>(x: T, y: T) {
- | +++++++++++++++++++++++++++
+LL | fn foo<T: std::ops::Add>(x: T, y: T) {
+ | +++++++++++++++
error[E0368]: binary assignment operation `+=` cannot be applied to type `T`
--> $DIR/missing_trait_impl.rs:9:5
|
help: consider restricting type parameter `T`
|
-LL | fn baz<T: std::ops::Neg<Output = T>>(x: T) {
- | +++++++++++++++++++++++++++
+LL | fn baz<T: std::ops::Neg>(x: T) {
+ | +++++++++++++++
error[E0600]: cannot apply unary operator `!` to type `T`
--> $DIR/missing_trait_impl.rs:14:13
|
help: consider restricting type parameter `T`
|
-LL | fn baz<T: std::ops::Not<Output = T>>(x: T) {
- | +++++++++++++++++++++++++++
+LL | fn baz<T: std::ops::Not>(x: T) {
+ | +++++++++++++++
error[E0614]: type `T` cannot be dereferenced
--> $DIR/missing_trait_impl.rs:15:13
-error: call to unsafe function is unsafe and requires unsafe block (error E0133)
+error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5
|
LL | unsf();
- | ^^^^^^ call to unsafe function
+ | ^^^^^^ call to unsafe function `unsf`
|
note: the lint level is defined here
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9
LL | #![deny(unused_unsafe)]
| ^^^^^^^^^^^^^
-error: call to unsafe function is unsafe and requires unsafe block (error E0133)
+error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5
|
LL | unsf();
- | ^^^^^^ call to unsafe function
+ | ^^^^^^ call to unsafe function `unsf`
|
note: the lint level is defined here
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8
LL | #[allow(unsafe_op_in_unsafe_fn)]
| ^^^^^^^^^^^^^^^^^^^^^^
-error[E0133]: call to unsafe function is unsafe and requires unsafe block
+error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
|
LL | unsf();
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe function or block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:80:9
|
LL | unsf();
unsafe fn deny_level() {
unsf();
- //~^ ERROR call to unsafe function is unsafe and requires unsafe block
+ //~^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block
*PTR;
//~^ ERROR dereference of raw pointer is unsafe and requires unsafe block
VOID = ();
#[deny(warnings)]
unsafe fn warning_level() {
unsf();
- //~^ ERROR call to unsafe function is unsafe and requires unsafe block
+ //~^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block
*PTR;
//~^ ERROR dereference of raw pointer is unsafe and requires unsafe block
VOID = ();
fn main() {
unsf();
- //~^ ERROR call to unsafe function is unsafe and requires unsafe block
+ //~^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block
#[allow(unsafe_op_in_unsafe_fn)]
{
unsf();
- //~^ ERROR call to unsafe function is unsafe and requires unsafe function or block
+ //~^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe function or block
}
}
-error: call to unsafe function is unsafe and requires unsafe block (error E0133)
+error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5
|
LL | unsf();
LL | #![deny(unused_unsafe)]
| ^^^^^^^^^^^^^
-error: call to unsafe function is unsafe and requires unsafe block (error E0133)
+error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5
|
LL | unsf();
LL | unsafe { unsf() }
| ^^^^^^ unnecessary `unsafe` block
-error[E0133]: call to unsafe function is unsafe and requires unsafe block
+error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
|
LL | unsf();
|
= note: consult the function's documentation for information on how to avoid undefined behavior
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe function or block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:80:9
|
LL | unsf();
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `dummy` is unsafe and requires unsafe function or block
--> $DIR/unsafe-const-fn.rs:10:18
|
LL | const VAL: u32 = dummy(0xFFFF);
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `dummy` is unsafe and requires unsafe function or block
--> $DIR/unsafe-const-fn.rs:10:18
|
LL | const VAL: u32 = dummy(0xFFFF);
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block
--> $DIR/unsafe-fn-called-from-safe.rs:7:5
|
LL | f();
unsafe fn f() { return; }
fn main() {
- f(); //~ ERROR call to unsafe function is unsafe
+ f(); //~ ERROR call to unsafe function `f` is unsafe
}
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block
--> $DIR/unsafe-fn-called-from-safe.rs:7:5
|
LL | f();
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block
--> $DIR/unsafe-fn-used-as-value.rs:8:5
|
LL | x();
fn main() {
let x = f;
- x(); //~ ERROR call to unsafe function is unsafe
+ x(); //~ ERROR call to unsafe function `f` is unsafe
}
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block
--> $DIR/unsafe-fn-used-as-value.rs:8:5
|
LL | x();
}
// Stupid function extractor for array.
-function extractArrayVariable(content, arrayName) {
- var splitter = "var " + arrayName;
+function extractArrayVariable(content, arrayName, kind) {
+ if (typeof kind === "undefined") {
+ kind = "let ";
+ }
+ var splitter = kind + arrayName;
while (true) {
var start = content.indexOf(splitter);
if (start === -1) {
}
content = content.slice(start + 1);
}
+ if (kind === "let ") {
+ return extractArrayVariable(content, arrayName, "const ");
+ }
return null;
}
// Stupid function extractor for variable.
-function extractVariable(content, varName) {
- var splitter = "var " + varName;
+function extractVariable(content, varName, kind) {
+ if (typeof kind === "undefined") {
+ kind = "let ";
+ }
+ var splitter = kind + varName;
while (true) {
var start = content.indexOf(splitter);
if (start === -1) {
}
content = content.slice(start + 1);
}
+ if (kind === "let ") {
+ return extractVariable(content, varName, "const ");
+ }
return null;
}